Merge "Call the onDismiss listener in submenus." into nyc-dev
diff --git a/Android.mk b/Android.mk
index 59b2a46..024b2fd 100644
--- a/Android.mk
+++ b/Android.mk
@@ -226,6 +226,7 @@
core/java/android/os/INetworkManagementService.aidl \
core/java/android/os/IPermissionController.aidl \
core/java/android/os/IProcessInfoService.aidl \
+ core/java/android/os/IProgressListener.aidl \
core/java/android/os/IPowerManager.aidl \
core/java/android/os/IRecoverySystem.aidl \
core/java/android/os/IRecoverySystemProgressListener.aidl \
@@ -299,7 +300,6 @@
core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl \
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IEphemeralResolver.aidl \
- core/java/com/android/internal/app/IProcessStats.aidl \
core/java/com/android/internal/app/ISoundTriggerService.aidl \
core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.aidl \
@@ -307,6 +307,7 @@
core/java/com/android/internal/app/IVoiceInteractorCallback.aidl \
core/java/com/android/internal/app/IVoiceInteractorRequest.aidl \
core/java/com/android/internal/app/IMediaContainerService.aidl \
+ core/java/com/android/internal/app/procstats/IProcessStats.aidl \
core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
core/java/com/android/internal/backup/IBackupTransport.aidl \
diff --git a/api/current.txt b/api/current.txt
index a9bb90f3..c416044 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -576,6 +576,7 @@
field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int fontFeatureSettings = 16843959; // 0x10104b7
field public static final int footerDividersEnabled = 16843311; // 0x101022f
+ field public static final int forceHasOverlappingRendering = 16844068; // 0x1010524
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundTint = 16843885; // 0x101046d
@@ -859,7 +860,8 @@
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
- field public static final int minimalSize = 16844022; // 0x10104f6
+ field public static final int minimalHeight = 16844067; // 0x1010523
+ field public static final int minimalWidth = 16844022; // 0x10104f6
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
field public static final int mipMap = 16843725; // 0x10103cd
@@ -9257,7 +9259,6 @@
field public int documentLaunchMode;
field public int flags;
field public int launchMode;
- field public android.content.pm.ActivityInfo.Layout layout;
field public int maxRecents;
field public java.lang.String parentActivityName;
field public java.lang.String permission;
@@ -9268,14 +9269,16 @@
field public java.lang.String taskAffinity;
field public int theme;
field public int uiOptions;
+ field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
}
- public static final class ActivityInfo.Layout {
- ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+ public static final class ActivityInfo.WindowLayout {
+ ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
field public final int gravity;
field public final int height;
field public final float heightFraction;
- field public final int minimalSize;
+ field public final int minimalHeight;
+ field public final int minimalWidth;
field public final int width;
field public final float widthFraction;
}
@@ -19251,10 +19254,19 @@
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -29567,8 +29579,8 @@
public class StorageManager {
method public java.lang.String getMountedObbPath(java.lang.String);
- method public android.os.storage.StorageVolume getPrimaryVolume();
- method public android.os.storage.StorageVolume[] getVolumeList();
+ method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+ method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
method public boolean isEncrypted(java.io.File);
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -29896,6 +29908,8 @@
method public android.content.SharedPreferences getSharedPreferences();
method public int getSharedPreferencesMode();
method public java.lang.String getSharedPreferencesName();
+ method public boolean isStorageDefault();
+ method public boolean isStorageDeviceProtected();
method public static void setDefaultValues(android.content.Context, int, boolean);
method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
method public void setSharedPreferencesMode(int);
@@ -30760,6 +30774,7 @@
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
@@ -34583,7 +34598,6 @@
method public boolean onMenuOpened(int, android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
- method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method public void onWakeUp();
@@ -36229,9 +36243,9 @@
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public static java.lang.String propertiesToString(int);
method public final void putExtras(android.os.Bundle);
method public final void removeExtras(java.util.List<java.lang.String>);
- method public static java.lang.String propertiesToString(int);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -36257,8 +36271,8 @@
method public static java.lang.String stateToString(int);
field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
- field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
+ field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -42332,6 +42346,7 @@
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
+ method public void forceHasOverlappingRendering(boolean);
method public void forceLayout();
method public static int generateViewId();
method public java.lang.CharSequence getAccessibilityClassName();
@@ -42377,6 +42392,7 @@
method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
+ method public final boolean getHasOverlappingRendering();
method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
method public int getHorizontalFadingEdgeLength();
@@ -57317,6 +57333,7 @@
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public boolean removeIf(java.util.function.Predicate<? super E>);
+ method public void replaceAll(java.util.function.UnaryOperator<E>);
method public int size();
method public void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
@@ -57402,6 +57419,10 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+ method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+ method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+ method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
method public static void parallelSort(byte[]);
method public static void parallelSort(byte[], int, int);
method public static void parallelSort(char[]);
@@ -57950,6 +57971,7 @@
method public java.lang.Object clone();
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+ method public boolean replace(K, V, V);
}
public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -57970,6 +57992,9 @@
ctor public Hashtable(java.util.Map<? extends K, ? extends V>);
method public synchronized void clear();
method public synchronized java.lang.Object clone();
+ method public synchronized V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+ method public synchronized V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+ method public synchronized V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
method public synchronized boolean contains(java.lang.Object);
method public synchronized boolean containsKey(java.lang.Object);
method public boolean containsValue(java.lang.Object);
@@ -57977,13 +58002,19 @@
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
method public synchronized V get(java.lang.Object);
+ method public synchronized V getOrDefault(java.lang.Object, V);
method public synchronized boolean isEmpty();
method public java.util.Set<K> keySet();
method public synchronized java.util.Enumeration<K> keys();
+ method public synchronized V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
method public synchronized V put(K, V);
method public synchronized void putAll(java.util.Map<? extends K, ? extends V>);
+ method public synchronized V putIfAbsent(K, V);
method protected void rehash();
method public synchronized V remove(java.lang.Object);
+ method public synchronized boolean remove(java.lang.Object, java.lang.Object);
+ method public synchronized boolean replace(K, V, V);
+ method public synchronized V replace(K, V);
method public synchronized int size();
method public java.util.Collection<V> values();
}
@@ -58128,9 +58159,11 @@
method public abstract boolean remove(java.lang.Object);
method public abstract E remove(int);
method public abstract boolean removeAll(java.util.Collection<?>);
+ method public default void replaceAll(java.util.function.UnaryOperator<E>);
method public abstract boolean retainAll(java.util.Collection<?>);
method public abstract E set(int, E);
method public abstract int size();
+ method public default void sort(java.util.Comparator<? super E>);
method public abstract java.util.List<E> subList(int, int);
method public abstract java.lang.Object[] toArray();
method public abstract T[] toArray(T[]);
@@ -59045,9 +59078,11 @@
method public synchronized boolean removeElement(java.lang.Object);
method public synchronized void removeElementAt(int);
method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
+ method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
method public synchronized void setElementAt(E, int);
method public synchronized void setSize(int);
method public synchronized int size();
+ method public synchronized void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
method public synchronized void trimToSize();
field protected int capacityIncrement;
@@ -59513,6 +59548,7 @@
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
+ method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
diff --git a/api/removed.txt b/api/removed.txt
index 36c8ce5..86085c8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -136,6 +136,15 @@
}
+package android.os.storage {
+
+ public class StorageManager {
+ method public android.os.storage.StorageVolume getPrimaryVolume();
+ method public android.os.storage.StorageVolume[] getVolumeList();
+ }
+
+}
+
package android.preference {
public class PreferenceManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index a9324d9..e372d98 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -671,6 +671,7 @@
field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int fontFeatureSettings = 16843959; // 0x10104b7
field public static final int footerDividersEnabled = 16843311; // 0x101022f
+ field public static final int forceHasOverlappingRendering = 16844068; // 0x1010524
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundTint = 16843885; // 0x101046d
@@ -954,7 +955,8 @@
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
- field public static final int minimalSize = 16844022; // 0x10104f6
+ field public static final int minimalHeight = 16844067; // 0x1010523
+ field public static final int minimalWidth = 16844022; // 0x10104f6
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
field public static final int mipMap = 16843725; // 0x10103cd
@@ -9580,7 +9582,6 @@
field public int documentLaunchMode;
field public int flags;
field public int launchMode;
- field public android.content.pm.ActivityInfo.Layout layout;
field public int maxRecents;
field public java.lang.String parentActivityName;
field public java.lang.String permission;
@@ -9591,14 +9592,16 @@
field public java.lang.String taskAffinity;
field public int theme;
field public int uiOptions;
+ field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
}
- public static final class ActivityInfo.Layout {
- ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+ public static final class ActivityInfo.WindowLayout {
+ ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
field public final int gravity;
field public final int height;
field public final float heightFraction;
- field public final int minimalSize;
+ field public final int minimalHeight;
+ field public final int minimalWidth;
field public final int width;
field public final float widthFraction;
}
@@ -20423,10 +20426,19 @@
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -31570,12 +31582,13 @@
public class UpdateEngine {
ctor public UpdateEngine();
- method public void applyPayload(java.lang.String, long, long, java.lang.String[]) throws android.os.RemoteException;
- method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler) throws android.os.RemoteException;
- method public boolean bind(android.os.UpdateEngineCallback) throws android.os.RemoteException;
- method public void cancel() throws android.os.RemoteException;
- method public void resume() throws android.os.RemoteException;
- method public void suspend() throws android.os.RemoteException;
+ method public void applyPayload(java.lang.String, long, long, java.lang.String[]);
+ method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler);
+ method public boolean bind(android.os.UpdateEngineCallback);
+ method public void cancel();
+ method public void resetStatus();
+ method public void resume();
+ method public void suspend();
}
public static final class UpdateEngine.ErrorCodeConstants {
@@ -31879,8 +31892,8 @@
public class StorageManager {
method public java.lang.String getMountedObbPath(java.lang.String);
- method public android.os.storage.StorageVolume getPrimaryVolume();
- method public android.os.storage.StorageVolume[] getVolumeList();
+ method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+ method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
method public boolean isEncrypted(java.io.File);
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -32208,6 +32221,9 @@
method public android.content.SharedPreferences getSharedPreferences();
method public int getSharedPreferencesMode();
method public java.lang.String getSharedPreferencesName();
+ method public boolean isStorageCredentialProtected();
+ method public boolean isStorageDefault();
+ method public boolean isStorageDeviceProtected();
method public static void setDefaultValues(android.content.Context, int, boolean);
method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
method public void setSharedPreferencesMode(int);
@@ -33073,6 +33089,7 @@
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
@@ -37031,7 +37048,6 @@
method public boolean onMenuOpened(int, android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
- method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method public void onWakeUp();
@@ -38803,9 +38819,9 @@
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public static java.lang.String propertiesToString(int);
method public final void putExtras(android.os.Bundle);
method public final void removeExtras(java.util.List<java.lang.String>);
- method public static java.lang.String propertiesToString(int);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -38831,8 +38847,8 @@
method public static java.lang.String stateToString(int);
field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
- field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
+ field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -45056,6 +45072,7 @@
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
+ method public void forceHasOverlappingRendering(boolean);
method public void forceLayout();
method public static int generateViewId();
method public java.lang.CharSequence getAccessibilityClassName();
@@ -45101,6 +45118,7 @@
method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
+ method public final boolean getHasOverlappingRendering();
method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
method public int getHorizontalFadingEdgeLength();
@@ -48657,7 +48675,6 @@
public final class WebViewFactory {
ctor public WebViewFactory();
method public static android.content.pm.PackageInfo getLoadedPackageInfo();
- method public static java.lang.String getWebViewPackageName();
method public static int loadWebViewNativeLibraryFromPackage(java.lang.String, java.lang.ClassLoader);
method public static void prepareWebViewInZygote();
field public static final java.lang.String CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY = "persist.sys.webview.vmsize";
@@ -60380,6 +60397,7 @@
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public boolean removeIf(java.util.function.Predicate<? super E>);
+ method public void replaceAll(java.util.function.UnaryOperator<E>);
method public int size();
method public void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
@@ -60465,6 +60483,10 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+ method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+ method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+ method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
method public static void parallelSort(byte[]);
method public static void parallelSort(byte[], int, int);
method public static void parallelSort(char[]);
@@ -61013,6 +61035,7 @@
method public java.lang.Object clone();
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+ method public boolean replace(K, V, V);
}
public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -61033,6 +61056,9 @@
ctor public Hashtable(java.util.Map<? extends K, ? extends V>);
method public synchronized void clear();
method public synchronized java.lang.Object clone();
+ method public synchronized V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+ method public synchronized V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+ method public synchronized V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
method public synchronized boolean contains(java.lang.Object);
method public synchronized boolean containsKey(java.lang.Object);
method public boolean containsValue(java.lang.Object);
@@ -61040,13 +61066,19 @@
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
method public synchronized V get(java.lang.Object);
+ method public synchronized V getOrDefault(java.lang.Object, V);
method public synchronized boolean isEmpty();
method public java.util.Set<K> keySet();
method public synchronized java.util.Enumeration<K> keys();
+ method public synchronized V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
method public synchronized V put(K, V);
method public synchronized void putAll(java.util.Map<? extends K, ? extends V>);
+ method public synchronized V putIfAbsent(K, V);
method protected void rehash();
method public synchronized V remove(java.lang.Object);
+ method public synchronized boolean remove(java.lang.Object, java.lang.Object);
+ method public synchronized boolean replace(K, V, V);
+ method public synchronized V replace(K, V);
method public synchronized int size();
method public java.util.Collection<V> values();
}
@@ -61191,9 +61223,11 @@
method public abstract boolean remove(java.lang.Object);
method public abstract E remove(int);
method public abstract boolean removeAll(java.util.Collection<?>);
+ method public default void replaceAll(java.util.function.UnaryOperator<E>);
method public abstract boolean retainAll(java.util.Collection<?>);
method public abstract E set(int, E);
method public abstract int size();
+ method public default void sort(java.util.Comparator<? super E>);
method public abstract java.util.List<E> subList(int, int);
method public abstract java.lang.Object[] toArray();
method public abstract T[] toArray(T[]);
@@ -62108,9 +62142,11 @@
method public synchronized boolean removeElement(java.lang.Object);
method public synchronized void removeElementAt(int);
method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
+ method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
method public synchronized void setElementAt(E, int);
method public synchronized void setSize(int);
method public synchronized int size();
+ method public synchronized void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
method public synchronized void trimToSize();
field protected int capacityIncrement;
@@ -62576,6 +62612,7 @@
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
+ method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index d48b9b3..bc17627 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -134,6 +134,15 @@
}
+package android.os.storage {
+
+ public class StorageManager {
+ method public android.os.storage.StorageVolume getPrimaryVolume();
+ method public android.os.storage.StorageVolume[] getVolumeList();
+ }
+
+}
+
package android.preference {
public class PreferenceManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index 84e8b26..e4153f1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -576,6 +576,7 @@
field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int fontFeatureSettings = 16843959; // 0x10104b7
field public static final int footerDividersEnabled = 16843311; // 0x101022f
+ field public static final int forceHasOverlappingRendering = 16844068; // 0x1010524
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundTint = 16843885; // 0x101046d
@@ -859,7 +860,8 @@
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
- field public static final int minimalSize = 16844022; // 0x10104f6
+ field public static final int minimalHeight = 16844067; // 0x1010523
+ field public static final int minimalWidth = 16844022; // 0x10104f6
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
field public static final int mipMap = 16843725; // 0x10103cd
@@ -9264,7 +9266,6 @@
field public int documentLaunchMode;
field public int flags;
field public int launchMode;
- field public android.content.pm.ActivityInfo.Layout layout;
field public int maxRecents;
field public java.lang.String parentActivityName;
field public java.lang.String permission;
@@ -9275,14 +9276,16 @@
field public java.lang.String taskAffinity;
field public int theme;
field public int uiOptions;
+ field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
}
- public static final class ActivityInfo.Layout {
- ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+ public static final class ActivityInfo.WindowLayout {
+ ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
field public final int gravity;
field public final int height;
field public final float heightFraction;
- field public final int minimalSize;
+ field public final int minimalHeight;
+ field public final int minimalWidth;
field public final int width;
field public final float widthFraction;
}
@@ -19306,10 +19309,19 @@
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -29633,8 +29645,8 @@
public class StorageManager {
method public java.lang.String getMountedObbPath(java.lang.String);
- method public android.os.storage.StorageVolume getPrimaryVolume();
- method public android.os.storage.StorageVolume[] getVolumeList();
+ method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+ method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
method public boolean isEncrypted(java.io.File);
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -29962,6 +29974,8 @@
method public android.content.SharedPreferences getSharedPreferences();
method public int getSharedPreferencesMode();
method public java.lang.String getSharedPreferencesName();
+ method public boolean isStorageDefault();
+ method public boolean isStorageDeviceProtected();
method public static void setDefaultValues(android.content.Context, int, boolean);
method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
method public void setSharedPreferencesMode(int);
@@ -30829,6 +30843,7 @@
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
@@ -34342,6 +34357,7 @@
public class NetworkSecurityPolicy {
method public static android.security.NetworkSecurityPolicy getInstance();
+ method public void handleTrustStorageUpdate();
method public boolean isCleartextTrafficPermitted();
method public boolean isCleartextTrafficPermitted(java.lang.String);
}
@@ -34654,7 +34670,6 @@
method public boolean onMenuOpened(int, android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
- method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method public void onWakeUp();
@@ -36300,9 +36315,9 @@
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public static java.lang.String propertiesToString(int);
method public final void putExtras(android.os.Bundle);
method public final void removeExtras(java.util.List<java.lang.String>);
- method public static java.lang.String propertiesToString(int);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -36328,8 +36343,8 @@
method public static java.lang.String stateToString(int);
field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
- field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
+ field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -42405,6 +42420,7 @@
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
+ method public void forceHasOverlappingRendering(boolean);
method public void forceLayout();
method public static int generateViewId();
method public java.lang.CharSequence getAccessibilityClassName();
@@ -42450,6 +42466,7 @@
method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
method public final boolean getGlobalVisibleRect(android.graphics.Rect);
method public android.os.Handler getHandler();
+ method public final boolean getHasOverlappingRendering();
method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
method public int getHorizontalFadingEdgeLength();
@@ -57390,6 +57407,7 @@
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public boolean removeIf(java.util.function.Predicate<? super E>);
+ method public void replaceAll(java.util.function.UnaryOperator<E>);
method public int size();
method public void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
@@ -57475,6 +57493,10 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+ method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+ method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+ method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
method public static void parallelSort(byte[]);
method public static void parallelSort(byte[], int, int);
method public static void parallelSort(char[]);
@@ -58023,6 +58045,7 @@
method public java.lang.Object clone();
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+ method public boolean replace(K, V, V);
}
public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -58043,6 +58066,9 @@
ctor public Hashtable(java.util.Map<? extends K, ? extends V>);
method public synchronized void clear();
method public synchronized java.lang.Object clone();
+ method public synchronized V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+ method public synchronized V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+ method public synchronized V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
method public synchronized boolean contains(java.lang.Object);
method public synchronized boolean containsKey(java.lang.Object);
method public boolean containsValue(java.lang.Object);
@@ -58050,13 +58076,19 @@
method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
method public synchronized V get(java.lang.Object);
+ method public synchronized V getOrDefault(java.lang.Object, V);
method public synchronized boolean isEmpty();
method public java.util.Set<K> keySet();
method public synchronized java.util.Enumeration<K> keys();
+ method public synchronized V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
method public synchronized V put(K, V);
method public synchronized void putAll(java.util.Map<? extends K, ? extends V>);
+ method public synchronized V putIfAbsent(K, V);
method protected void rehash();
method public synchronized V remove(java.lang.Object);
+ method public synchronized boolean remove(java.lang.Object, java.lang.Object);
+ method public synchronized boolean replace(K, V, V);
+ method public synchronized V replace(K, V);
method public synchronized int size();
method public java.util.Collection<V> values();
}
@@ -58201,9 +58233,11 @@
method public abstract boolean remove(java.lang.Object);
method public abstract E remove(int);
method public abstract boolean removeAll(java.util.Collection<?>);
+ method public default void replaceAll(java.util.function.UnaryOperator<E>);
method public abstract boolean retainAll(java.util.Collection<?>);
method public abstract E set(int, E);
method public abstract int size();
+ method public default void sort(java.util.Comparator<? super E>);
method public abstract java.util.List<E> subList(int, int);
method public abstract java.lang.Object[] toArray();
method public abstract T[] toArray(T[]);
@@ -59118,9 +59152,11 @@
method public synchronized boolean removeElement(java.lang.Object);
method public synchronized void removeElementAt(int);
method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
+ method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
method public synchronized void setElementAt(E, int);
method public synchronized void setSize(int);
method public synchronized int size();
+ method public synchronized void sort(java.util.Comparator<? super E>);
method public java.util.Spliterator<E> spliterator();
method public synchronized void trimToSize();
field protected int capacityIncrement;
@@ -59586,6 +59622,7 @@
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
+ method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 36c8ce5..86085c8 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -136,6 +136,15 @@
}
+package android.os.storage {
+
+ public class StorageManager {
+ method public android.os.storage.StorageVolume getPrimaryVolume();
+ method public android.os.storage.StorageVolume[] getVolumeList();
+ }
+
+}
+
package android.preference {
public class PreferenceManager {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 86734b1..221b2d3 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1141,7 +1141,7 @@
int userId = Integer.parseInt(nextArgRequired());
byte[] token = argToBytes(nextArgRequired());
byte[] secret = argToBytes(nextArgRequired());
- boolean success = mAm.unlockUser(userId, token, secret);
+ boolean success = mAm.unlockUser(userId, token, secret, null);
if (success) {
System.out.println("Success: user unlocked");
} else {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ee17e8a..0d387e6 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1249,7 +1249,7 @@
protected void onResume() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
getApplication().dispatchActivityResumed(this);
- mActivityTransitionState.onResume();
+ mActivityTransitionState.onResume(this, isTopOfTask());
mCalled = true;
}
@@ -5920,6 +5920,9 @@
* @return true if this is the topmost, non-finishing activity in its task.
*/
private boolean isTopOfTask() {
+ if (mToken == null || mWindow == null || !mWindowAdded) {
+ return false;
+ }
try {
return ActivityManagerNative.getDefault().isTopOfTask(mToken);
} catch (RemoteException e) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 6380801..baaa55d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -31,7 +31,7 @@
import android.os.ParcelFileDescriptor;
import android.util.Log;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastPrintWriter;
@@ -1410,10 +1410,10 @@
public static final int RECENT_IGNORE_HOME_STACK_TASKS = 0x0008;
/**
- * Ignores all tasks that are on the docked stack.
+ * Ignores the top task in the docked stack.
* @hide
*/
- public static final int RECENT_INGORE_DOCKED_STACK_TASKS = 0x0010;
+ public static final int RECENT_INGORE_DOCKED_STACK_TOP_TASK = 0x0010;
/**
* Ignores all tasks that are on the pinned stack.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f5d7e7e..4bf48a3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -41,6 +41,7 @@
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
+import android.os.IProgressListener;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -2122,7 +2123,9 @@
int userId = data.readInt();
byte[] token = data.createByteArray();
byte[] secret = data.createByteArray();
- boolean result = unlockUser(userId, token, secret);
+ IProgressListener listener = IProgressListener.Stub
+ .asInterface(data.readStrongBinder());
+ boolean result = unlockUser(userId, token, secret, listener);
reply.writeNoException();
reply.writeInt(result ? 1 : 0);
return true;
@@ -5707,13 +5710,15 @@
return result;
}
- public boolean unlockUser(int userId, byte[] token, byte[] secret) throws RemoteException {
+ public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(userId);
data.writeByteArray(token);
data.writeByteArray(secret);
+ data.writeStrongInterface(listener);
mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
reply.readException();
boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 198bfb0a..e589e7c 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -25,6 +25,7 @@
import android.os.ResultReceiver;
import android.transition.Transition;
import android.transition.TransitionSet;
+import android.transition.Visibility;
import android.util.ArrayMap;
import android.view.GhostView;
import android.view.View;
@@ -378,6 +379,7 @@
transition.setEpicenterCallback(mEpicenterCallback);
transition = setTargets(transition, includeTransitioningViews);
}
+ noLayoutSuppressionForVisibilityTransitions(transition);
return transition;
}
@@ -944,6 +946,24 @@
}
}
+ /**
+ * Blocks suppressLayout from Visibility transitions. It is ok to suppress the layout,
+ * but we don't want to force the layout when suppressLayout becomes false. This leads
+ * to visual glitches.
+ */
+ private static void noLayoutSuppressionForVisibilityTransitions(Transition transition) {
+ if (transition instanceof Visibility) {
+ final Visibility visibility = (Visibility) transition;
+ visibility.setSuppressLayout(false);
+ } else if (transition instanceof TransitionSet) {
+ final TransitionSet set = (TransitionSet) transition;
+ final int count = set.getTransitionCount();
+ for (int i = 0; i < count; i++) {
+ noLayoutSuppressionForVisibilityTransitions(set.getTransitionAt(i));
+ }
+ }
+ }
+
private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
private Rect mEpicenter;
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index bf0bd79..d3ca7ee 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -236,9 +236,27 @@
}
}
- public void onResume() {
- restoreExitedViews();
- restoreReenteringViews();
+ public void onResume(Activity activity, boolean isTopOfTask) {
+ // After orientation change, the onResume can come in before the top Activity has
+ // left, so if the Activity is not top, wait a second for the top Activity to exit.
+ if (mCalledExitCoordinator == null) {
+ return; // This is the called activity
+ }
+ if (isTopOfTask || mEnterTransitionCoordinator == null) {
+ restoreExitedViews();
+ restoreReenteringViews();
+ } else {
+ activity.mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mEnterTransitionCoordinator == null ||
+ mEnterTransitionCoordinator.isWaitingForRemoteExit()) {
+ restoreExitedViews();
+ restoreReenteringViews();
+ }
+ }
+ }, 1000);
+ }
}
public void clear() {
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index d89c0e0..a599584 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -244,6 +244,10 @@
}
}
+ public boolean isWaitingForRemoteExit() {
+ return mIsReturning && mResultReceiver != null;
+ }
+
/**
* This is called onResume. If an Activity is resuming and the transitions
* haven't started yet, force the views to appear. This is likely to be
@@ -288,6 +292,10 @@
cancelPendingTransitions();
}
mAreViewsReady = true;
+ if (mResultReceiver != null) {
+ mResultReceiver.send(MSG_CANCEL, null);
+ mResultReceiver = null;
+ }
}
private void cancel() {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index ce017f6..0404288 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -100,6 +100,10 @@
mExitSharedElementBundle = resultData;
sharedElementExitBack();
break;
+ case MSG_CANCEL:
+ mIsCanceled = true;
+ finish();
+ break;
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 639c207..417c0679 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -47,6 +47,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.os.IInterface;
+import android.os.IProgressListener;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -461,7 +462,8 @@
// Multi-user APIs
public boolean switchUser(int userid) throws RemoteException;
public boolean startUserInBackground(int userid) throws RemoteException;
- public boolean unlockUser(int userid, byte[] token, byte[] secret) throws RemoteException;
+ public boolean unlockUser(int userid, byte[] token, byte[] secret, IProgressListener listener)
+ throws RemoteException;
public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
public UserInfo getCurrentUser() throws RemoteException;
public boolean isUserRunning(int userid, int flags) throws RemoteException;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 57ab7a2..66e0ada 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2856,12 +2856,15 @@
"com.google.android.c2dm.intent.RECEIVE";
/**
- * Broadcast Action: hook for permforming cleanup after a system update.
+ * Broadcast Action: This is broadcast once when the user is booting after a
+ * system update. It can be used to perform cleanup or upgrades after a
+ * system update.
+ * <p>
+ * This broadcast is sent after the {@link #ACTION_LOCKED_BOOT_COMPLETED}
+ * broadcast but before the {@link #ACTION_BOOT_COMPLETED} broadcast. It's
+ * only sent when the {@link Build#FINGERPRINT} has changed, and it's only
+ * sent to receivers in the system image.
*
- * The broadcast is sent when the system is booting, before the
- * BOOT_COMPLETED broadcast. It is only sent to receivers in the system
- * image. A receiver for this should do its work and then disable itself
- * so that it does not get run again at the next boot.
* @hide
*/
public static final String ACTION_PRE_BOOT_COMPLETED =
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 5da3c86..0f4cbbb 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -767,7 +767,11 @@
*/
public int lockTaskLaunchMode;
- public Layout layout;
+ /**
+ * Information about desired position and size of activity on the display when
+ * it is first started.
+ */
+ public WindowLayout windowLayout;
public ActivityInfo() {
}
@@ -788,7 +792,7 @@
parentActivityName = orig.parentActivityName;
maxRecents = orig.maxRecents;
lockTaskLaunchMode = orig.lockTaskLaunchMode;
- layout = orig.layout;
+ windowLayout = orig.windowLayout;
resizeMode = orig.resizeMode;
}
@@ -886,10 +890,10 @@
pw.println(prefix + "lockTaskLaunchMode="
+ lockTaskLaunchModeToString(lockTaskLaunchMode));
}
- if (layout != null) {
- pw.println(prefix + "defaultLayout=" + layout.width + "|"
- + layout.widthFraction + ", " + layout.height + "|"
- + layout.heightFraction + ", " + layout.gravity);
+ if (windowLayout != null) {
+ pw.println(prefix + "windowLayout=" + windowLayout.width + "|"
+ + windowLayout.widthFraction + ", " + windowLayout.height + "|"
+ + windowLayout.heightFraction + ", " + windowLayout.gravity);
}
pw.println(prefix + "resizeMode=" + resizeModeToString(resizeMode));
super.dumpBack(pw, prefix, flags);
@@ -922,14 +926,15 @@
dest.writeInt(persistableMode);
dest.writeInt(maxRecents);
dest.writeInt(lockTaskLaunchMode);
- if (layout != null) {
+ if (windowLayout != null) {
dest.writeInt(1);
- dest.writeInt(layout.width);
- dest.writeFloat(layout.widthFraction);
- dest.writeInt(layout.height);
- dest.writeFloat(layout.heightFraction);
- dest.writeInt(layout.gravity);
- dest.writeInt(layout.minimalSize);
+ dest.writeInt(windowLayout.width);
+ dest.writeFloat(windowLayout.widthFraction);
+ dest.writeInt(windowLayout.height);
+ dest.writeFloat(windowLayout.heightFraction);
+ dest.writeInt(windowLayout.gravity);
+ dest.writeInt(windowLayout.minimalWidth);
+ dest.writeInt(windowLayout.minimalHeight);
} else {
dest.writeInt(0);
}
@@ -964,36 +969,107 @@
maxRecents = source.readInt();
lockTaskLaunchMode = source.readInt();
if (source.readInt() == 1) {
- layout = new Layout(source);
+ windowLayout = new WindowLayout(source);
}
resizeMode = source.readInt();
}
- public static final class Layout {
- public Layout(int width, float widthFraction, int height, float heightFraction, int gravity,
- int minimalSize) {
+ /**
+ * Contains information about position and size of the activity on the display.
+ *
+ * Used in freeform mode to set desired position when activity is first launched.
+ * It describes how big the activity wants to be in both width and height,
+ * the minimal allowed size, and the gravity to be applied.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+ * @attr ref android.R.styleable#AndroidManifestLayout_gravity
+ * @attr ref android.R.styleable#AndroidManifestLayout_minimalWidth
+ * @attr ref android.R.styleable#AndroidManifestLayout_minimalHeight
+ */
+ public static final class WindowLayout {
+ public WindowLayout(int width, float widthFraction, int height, float heightFraction, int gravity,
+ int minimalWidth, int minimalHeight) {
this.width = width;
this.widthFraction = widthFraction;
this.height = height;
this.heightFraction = heightFraction;
this.gravity = gravity;
- this.minimalSize = minimalSize;
+ this.minimalWidth = minimalWidth;
+ this.minimalHeight = minimalHeight;
}
- Layout(Parcel source) {
+ WindowLayout(Parcel source) {
width = source.readInt();
widthFraction = source.readFloat();
height = source.readInt();
heightFraction = source.readFloat();
gravity = source.readInt();
- minimalSize = source.readInt();
+ minimalWidth = source.readInt();
+ minimalHeight = source.readInt();
}
+ /**
+ * Width of activity in pixels.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+ */
public final int width;
+
+ /**
+ * Width of activity as a fraction of available display width.
+ * If both {@link #width} and this value are set this one will be preferred.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+ */
public final float widthFraction;
+
+ /**
+ * Height of activity in pixels.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+ */
public final int height;
+
+ /**
+ * Height of activity as a fraction of available display height.
+ * If both {@link #height} and this value are set this one will be preferred.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+ */
public final float heightFraction;
+
+ /**
+ * Gravity of activity.
+ * Currently {@link android.view.Gravity#TOP}, {@link android.view.Gravity#BOTTOM},
+ * {@link android.view.Gravity#LEFT} and {@link android.view.Gravity#RIGHT} are supported.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_gravity
+ */
public final int gravity;
- public final int minimalSize;
+
+ /**
+ * Minimal width of activity in pixels to be able to display its content.
+ *
+ * <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+ * activities launched in the task. That is if the root activity of a task set minimal
+ * width, then the system will set the same minimal width on all other activities in the
+ * task. It will also ignore any other minimal width attributes of non-root activities.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_minimalWidth
+ */
+ public final int minimalWidth;
+
+ /**
+ * Minimal height of activity in pixels to be able to display its content.
+ *
+ * <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+ * activities launched in the task. That is if the root activity of a task set minimal
+ * height, then the system will set the same minimal height on all other activities in the
+ * task. It will also ignore any other minimal height attributes of non-root activities.
+ *
+ * @attr ref android.R.styleable#AndroidManifestLayout_minimalHeight
+ */
+ public final int minimalHeight;
}
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e3fb161..a0238fb 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -316,6 +316,12 @@
int getApplicationEnabledSetting(in String packageName, int userId);
/**
+ * Logs process start information (including APK hash) to the security log.
+ */
+ void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile,
+ int pid);
+
+ /**
* As per {@link android.content.pm.PackageManager#flushPackageRestrictionsAsUser}.
*/
void flushPackageRestrictionsAsUser(in int userId);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 84605bb..ea251f6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3648,12 +3648,15 @@
int gravity = sw.getInt(
com.android.internal.R.styleable.AndroidManifestLayout_gravity,
Gravity.CENTER);
- int minimalSize = sw.getDimensionPixelSize(
- com.android.internal.R.styleable.AndroidManifestLayout_minimalSize,
+ int minimalWidth = sw.getDimensionPixelSize(
+ com.android.internal.R.styleable.AndroidManifestLayout_minimalWidth,
+ -1);
+ int minimalHeight = sw.getDimensionPixelSize(
+ com.android.internal.R.styleable.AndroidManifestLayout_minimalHeight,
-1);
sw.recycle();
- a.info.layout = new ActivityInfo.Layout(width, widthFraction,
- height, heightFraction, gravity, minimalSize);
+ a.info.windowLayout = new ActivityInfo.WindowLayout(width, widthFraction,
+ height, heightFraction, gravity, minimalWidth, minimalHeight);
}
private Activity parseActivityAlias(Package owner, Resources res,
@@ -3735,7 +3738,7 @@
info.uiOptions = target.info.uiOptions;
info.parentActivityName = target.info.parentActivityName;
info.maxRecents = target.info.maxRecents;
- info.layout = target.info.layout;
+ info.windowLayout = target.info.windowLayout;
info.resizeMode = target.info.resizeMode;
info.encryptionAware = info.directBootAware = target.info.directBootAware;
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 4255582..d57f2e6e 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -40,28 +40,37 @@
}
public abstract List<ShortcutInfo>
- getShortcuts(@NonNull String callingPackage, long changedSince,
+ getShortcuts(int launcherUserId,
+ @NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable ComponentName componentName,
@ShortcutQuery.QueryFlags int flags,
int userId);
public abstract List<ShortcutInfo>
- getShortcutInfo(@NonNull String callingPackage,
+ getShortcutInfo(int launcherUserId, @NonNull String callingPackage,
@NonNull String packageName, @Nullable List<String> ids, int userId);
- public abstract void pinShortcuts(@NonNull String callingPackage, @NonNull String packageName,
+
+ public abstract boolean
+ isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
+ @NonNull String packageName, @NonNull String id, int userId);
+
+ public abstract void pinShortcuts(int launcherUserId,
+ @NonNull String callingPackage, @NonNull String packageName,
@NonNull List<String> shortcutIds, int userId);
- public abstract Intent createShortcutIntent(@NonNull String callingPackage,
+ public abstract Intent createShortcutIntent(int launcherUserId, @NonNull String callingPackage,
@NonNull String packageName, @NonNull String shortcutId, int userId);
public abstract void addListener(@NonNull ShortcutChangeListener listener);
- public abstract int getShortcutIconResId(@NonNull String callingPackage,
+ public abstract int getShortcutIconResId(int launcherUserId, @NonNull String callingPackage,
@NonNull ShortcutInfo shortcut, int userId);
- public abstract ParcelFileDescriptor getShortcutIconFd(@NonNull String callingPackage,
+ public abstract ParcelFileDescriptor getShortcutIconFd(int launcherUserId,
+ @NonNull String callingPackage,
@NonNull ShortcutInfo shortcut, int userId);
- public abstract boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId);
+ public abstract boolean hasShortcutHostPermission(int launcherUserId,
+ @NonNull String callingPackage);
}
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index e8a3438..dd3a36c 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -96,6 +96,7 @@
public int flags;
public long creationTime;
public long lastLoggedInTime;
+ public String lastLoggedInFingerprint;
public int profileGroupId;
public int restrictedProfileParentId;
@@ -214,6 +215,7 @@
serialNumber = orig.serialNumber;
creationTime = orig.creationTime;
lastLoggedInTime = orig.lastLoggedInTime;
+ lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
partial = orig.partial;
profileGroupId = orig.profileGroupId;
restrictedProfileParentId = orig.restrictedProfileParentId;
@@ -241,6 +243,7 @@
dest.writeInt(serialNumber);
dest.writeLong(creationTime);
dest.writeLong(lastLoggedInTime);
+ dest.writeString(lastLoggedInFingerprint);
dest.writeInt(partial ? 1 : 0);
dest.writeInt(profileGroupId);
dest.writeInt(guestToRemove ? 1 : 0);
@@ -265,6 +268,7 @@
serialNumber = source.readInt();
creationTime = source.readLong();
lastLoggedInTime = source.readLong();
+ lastLoggedInFingerprint = source.readString();
partial = source.readInt() != 0;
profileGroupId = source.readInt();
guestToRemove = source.readInt() != 0;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 3dbe437..acf0677 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -76,7 +76,7 @@
* <li>If necessary, modify the returned {@link Camera.Parameters} object and call
* {@link #setParameters(Camera.Parameters)}.
*
- * <li>If desired, call {@link #setDisplayOrientation(int)}.
+ * <li>Call {@link #setDisplayOrientation(int)} to ensure correct orientation of preview.
*
* <li><b>Important</b>: Pass a fully initialized {@link SurfaceHolder} to
* {@link #setPreviewDisplay(SurfaceHolder)}. Without a surface, the camera
@@ -1511,9 +1511,15 @@
* <p>Starting from API level 14, this method can be called when preview is
* active.
*
+ * <p><b>Note: </b>Before API level 24, the default value for orientation is 0. Starting in
+ * API level 24, the default orientation will be such that applications in forced-landscape mode
+ * will have correct preview orientation, which may be either a default of 0 or
+ * 180. Applications that operate in portrait mode or allow for changing orientation must still
+ * call this method after each orientation change to ensure correct preview display in all
+ * cases.</p>
+ *
* @param degrees the angle that the picture will be rotated clockwise.
- * Valid values are 0, 90, 180, and 270. The starting
- * position is 0 (landscape).
+ * Valid values are 0, 90, 180, and 270.
* @see #setPreviewDisplay(SurfaceHolder)
*/
public native final void setDisplayOrientation(int degrees);
diff --git a/core/java/android/os/IProgressListener.aidl b/core/java/android/os/IProgressListener.aidl
new file mode 100644
index 0000000..ad58a7c
--- /dev/null
+++ b/core/java/android/os/IProgressListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.os;
+
+import android.os.Bundle;
+
+/** @hide */
+oneway interface IProgressListener {
+ void onStarted(int id, in Bundle extras);
+ void onProgress(int id, int progress, in Bundle extras);
+ void onFinished(int id, in Bundle extras);
+}
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 80e6146..bf03cce 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -87,7 +87,7 @@
}
@SystemApi
- public boolean bind(final UpdateEngineCallback callback, final Handler handler) throws RemoteException {
+ public boolean bind(final UpdateEngineCallback callback, final Handler handler) {
IUpdateEngineCallback updateEngineCallback = new IUpdateEngineCallback.Stub() {
@Override
public void onStatusUpdate(final int status, final float percent) {
@@ -118,31 +118,60 @@
}
};
- return mUpdateEngine.bind(updateEngineCallback);
+ try {
+ return mUpdateEngine.bind(updateEngineCallback);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@SystemApi
- public boolean bind(final UpdateEngineCallback callback) throws RemoteException {
+ public boolean bind(final UpdateEngineCallback callback) {
return bind(callback, null);
}
@SystemApi
- public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) throws RemoteException {
- mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
+ public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) {
+ try {
+ mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@SystemApi
- public void cancel() throws RemoteException {
- mUpdateEngine.cancel();
+ public void cancel() {
+ try {
+ mUpdateEngine.cancel();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@SystemApi
- public void suspend() throws RemoteException {
- mUpdateEngine.suspend();
+ public void suspend() {
+ try {
+ mUpdateEngine.suspend();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@SystemApi
- public void resume() throws RemoteException {
- mUpdateEngine.resume();
+ public void resume() {
+ try {
+ mUpdateEngine.resume();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @SystemApi
+ public void resetStatus() {
+ try {
+ mUpdateEngine.resetStatus();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 22aec63..720d3f7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,8 +34,8 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.provider.Settings;
-import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -49,6 +49,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -101,6 +102,10 @@
/** {@hide} */
public static final int FLAG_FOR_WRITE = 1 << 8;
+ /** {@hide} */
+ public static final int FLAG_REAL_STATE = 1 << 9;
+ /** {@hide} */
+ public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10;
private final Context mContext;
private final ContentResolver mResolver;
@@ -859,11 +864,31 @@
}
/**
- * Gets the list of shared/external storage volumes available to the current user.
+ * Return the list of shared/external storage volumes available to the
+ * current user. This includes both the primary shared storage device and
+ * any attached external volumes including SD cards and USB drives.
*
- * <p>It always contains the primary storage volume, plus any additional external volume(s)
- * available in the device, such as SD cards or attached USB drives.
+ * @see Environment#getExternalStorageDirectory()
+ * @see StorageVolume#createAccessIntent(String)
*/
+ public @NonNull List<StorageVolume> getStorageVolumes() {
+ final ArrayList<StorageVolume> res = new ArrayList<>();
+ Collections.addAll(res,
+ getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE));
+ return res;
+ }
+
+ /**
+ * Return the primary shared/external storage volume available to the
+ * current user. This volume is the same storage device returned by
+ * {@link Environment#getExternalStorageDirectory()} and
+ * {@link Context#getExternalFilesDir(String)}.
+ */
+ public @NonNull StorageVolume getPrimaryStorageVolume() {
+ return getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE)[0];
+ }
+
+ /** @removed */
public @NonNull StorageVolume[] getVolumeList() {
return getVolumeList(mContext.getUserId(), 0);
}
@@ -912,9 +937,7 @@
return paths;
}
- /**
- * Gets the primary shared/external storage volume available to the current user.
- */
+ /** @removed */
public @NonNull StorageVolume getPrimaryVolume() {
return getPrimaryVolume(getVolumeList());
}
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 34c0b14..c028e15 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -65,8 +65,8 @@
* broad access to all files contained on a storage device.
* </ul>
*
- * <p>It can be obtained through {@link StorageManager#getVolumeList()} and
- * {@link StorageManager#getPrimaryVolume()} and also as an extra in some broadcasts
+ * <p>It can be obtained through {@link StorageManager#getStorageVolumes()} and
+ * {@link StorageManager#getPrimaryStorageVolume()} and also as an extra in some broadcasts
* (see {@link #EXTRA_STORAGE_VOLUME}).
*
* <p>
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 47dc6c3..73174e3 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -412,6 +412,41 @@
}
/**
+ * Indicates if the storage location used internally by this class is the
+ * default provided by the hosting {@link Context}.
+ *
+ * @see #setStorageDefault()
+ * @see #setStorageDeviceProtected()
+ */
+ public boolean isStorageDefault() {
+ return mStorage == STORAGE_DEFAULT;
+ }
+
+ /**
+ * Indicates if the storage location used internally by this class is backed
+ * by device-protected storage.
+ *
+ * @see #setStorageDefault()
+ * @see #setStorageDeviceProtected()
+ */
+ public boolean isStorageDeviceProtected() {
+ return mStorage == STORAGE_DEVICE_PROTECTED;
+ }
+
+ /**
+ * Indicates if the storage location used internally by this class is backed
+ * by credential-protected storage.
+ *
+ * @see #setStorageDefault()
+ * @see #setStorageDeviceProtected()
+ * @hide
+ */
+ @SystemApi
+ public boolean isStorageCredentialProtected() {
+ return mStorage == STORAGE_CREDENTIAL_PROTECTED;
+ }
+
+ /**
* Gets a SharedPreferences instance that preferences managed by this will
* use.
*
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index e2ae133..8ac185a 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -440,6 +440,13 @@
public static final String POST_DIAL_DIGITS = "post_dial_digits";
/**
+ * For an incoming call, the secondary line number the call was received via.
+ * When a SIM card has multiple phone numbers associated with it, the via number indicates
+ * which of the numbers associated with the SIM was called.
+ */
+ public static final String VIA_NUMBER = "via_number";
+
+ /**
* Indicates that the entry will be copied from primary user to other users.
* <P>Type: INTEGER</P>
*
@@ -485,10 +492,10 @@
public static Uri addCall(CallerInfo ci, Context context, String number,
int presentation, int callType, int features, PhoneAccountHandle accountHandle,
long start, int duration, Long dataUsage) {
- return addCall(ci, context, number, /* postDialDigits =*/ "", presentation,
- callType, features, accountHandle,
- start, duration, dataUsage, /* addForAllUsers =*/ false,
- /* userToBeInsertedTo =*/ null, /* is_read =*/ false);
+ return addCall(ci, context, number, /* postDialDigits =*/ "", /* viaNumber =*/ "",
+ presentation, callType, features, accountHandle, start, duration,
+ dataUsage, /* addForAllUsers =*/ false, /* userToBeInsertedTo =*/ null,
+ /* is_read =*/ false);
}
@@ -499,6 +506,8 @@
* if the contact is unknown.
* @param context the context used to get the ContentResolver
* @param number the phone number to be added to the calls db
+ * @param viaNumber the secondary number that the incoming call received with. If the
+ * call was received with the SIM assigned number, then this field must be ''.
* @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
@@ -519,12 +528,12 @@
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
- String postDialDigits, int presentation, int callType, int features,
- PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage,
- boolean addForAllUsers, UserHandle userToBeInsertedTo) {
- return addCall(ci, context, number, postDialDigits, presentation, callType, features,
- accountHandle, start, duration, dataUsage, addForAllUsers, userToBeInsertedTo,
- /* is_read =*/ false);
+ String postDialDigits, String viaNumber, int presentation, int callType,
+ int features, PhoneAccountHandle accountHandle, long start, int duration,
+ Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) {
+ return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
+ features, accountHandle, start, duration, dataUsage, addForAllUsers,
+ userToBeInsertedTo, /* is_read =*/ false);
}
/**
@@ -536,6 +545,8 @@
* @param number the phone number to be added to the calls db
* @param postDialDigits the post-dial digits that were dialed after the number,
* if it was outgoing. Otherwise it is ''.
+ * @param viaNumber the secondary number that the incoming call received with. If the
+ * call was received with the SIM assigned number, then this field must be ''.
* @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
@@ -560,9 +571,10 @@
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
- String postDialDigits, int presentation, int callType, int features,
- PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage,
- boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean is_read) {
+ String postDialDigits, String viaNumber, int presentation, int callType,
+ int features, PhoneAccountHandle accountHandle, long start, int duration,
+ Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
+ boolean is_read) {
if (VERBOSE_LOG) {
Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
number, userToBeInsertedTo, addForAllUsers));
@@ -618,6 +630,7 @@
values.put(NUMBER, number);
values.put(POST_DIAL_DIGITS, postDialDigits);
+ values.put(VIA_NUMBER, viaNumber);
values.put(NUMBER_PRESENTATION, Integer.valueOf(numberPresentation));
values.put(TYPE, Integer.valueOf(callType));
values.put(FEATURES, features);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f7e0e03..a78f468 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6089,7 +6089,6 @@
MOUNT_UMS_AUTOSTART,
MOUNT_UMS_PROMPT,
MOUNT_UMS_NOTIFY_ENABLED,
- UI_NIGHT_MODE,
SLEEP_TIMEOUT,
DOUBLE_TAP_TO_WAKE,
WAKE_GESTURE_ENABLED,
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 733a092..9530aca 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -16,6 +16,7 @@
package android.security;
+import android.annotation.TestApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.security.net.config.ApplicationConfig;
@@ -104,4 +105,13 @@
ManifestConfigSource source = new ManifestConfigSource(appContext);
return new ApplicationConfig(source);
}
+
+ /**
+ * Handle an update to the system or user certificate stores.
+ * @hide
+ */
+ @TestApi
+ public void handleTrustStorageUpdate() {
+ ApplicationConfig.getDefaultInstance().handleTrustStorageUpdate();
+ }
}
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
index 4de36cd..fadea56 100644
--- a/core/java/android/security/net/config/ApplicationConfig.java
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -17,6 +17,7 @@
package android.security.net.config;
import android.util.Pair;
+import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import javax.net.ssl.X509TrustManager;
@@ -146,6 +147,20 @@
return getConfigForHostname(hostname).isCleartextTrafficPermitted();
}
+ public void handleTrustStorageUpdate() {
+ ensureInitialized();
+ mDefaultConfig.handleTrustStorageUpdate();
+ if (mConfigs != null) {
+ Set<NetworkSecurityConfig> updatedConfigs =
+ new HashSet<NetworkSecurityConfig>(mConfigs.size());
+ for (Pair<Domain, NetworkSecurityConfig> entry : mConfigs) {
+ if (updatedConfigs.add(entry.second)) {
+ entry.second.handleTrustStorageUpdate();
+ }
+ }
+ }
+ }
+
private void ensureInitialized() {
synchronized(mLock) {
if (mInitialized) {
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index f3272e4..4bcc405 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -25,4 +25,5 @@
X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
X509Certificate findByIssuerAndSignature(X509Certificate cert);
Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert);
+ void handleTrustStorageUpdate();
}
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 742d430..45cd0f0 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -64,4 +64,8 @@
public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
return mSource.findAllByIssuerAndSignature(cert);
}
+
+ public void handleTrustStorageUpdate() {
+ mSource.handleTrustStorageUpdate();
+ }
}
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index b2c068c..e3c9d65 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -126,6 +126,13 @@
});
}
+ @Override
+ public void handleTrustStorageUpdate() {
+ synchronized (mLock) {
+ mCertificates = null;
+ }
+ }
+
private static interface CertSelector {
boolean match(X509Certificate cert);
}
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index ba5dd83..c68f385 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -105,4 +105,9 @@
}
return certs;
}
+
+ @Override
+ public void handleTrustStorageUpdate() {
+ // Nothing to do.
+ }
}
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 6d6a92a..b3a37d0 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -117,12 +117,6 @@
}
}
- void onTrustStoreChange() {
- synchronized (mAnchorsLock) {
- mAnchors = null;
- }
- }
-
/** @hide */
public TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {
for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
@@ -154,6 +148,16 @@
return certs;
}
+ public void handleTrustStorageUpdate() {
+ synchronized (mAnchorsLock) {
+ mAnchors = null;
+ for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+ ref.handleTrustStorageUpdate();
+ }
+ }
+ getTrustManager().handleTrustStorageUpdate();
+ }
+
/**
* Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
*
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index 81cad79..3c292ca 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -20,6 +20,7 @@
import android.util.ArrayMap;
import java.io.IOException;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
@@ -29,14 +30,15 @@
import java.util.Map;
import java.util.Set;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} that implements the trust anchor and pinning for a
+ * {@link X509ExtendedTrustManager} that implements the trust anchor and pinning for a
* given {@link NetworkSecurityConfig}.
* @hide
*/
-public class NetworkSecurityTrustManager implements X509TrustManager {
+public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
// TODO: Replace this with a general X509TrustManager and use duck-typing.
private final TrustManagerImpl mDelegate;
private final NetworkSecurityConfig mNetworkSecurityConfig;
@@ -68,9 +70,37 @@
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
- checkServerTrusted(certs, authType, null);
+ checkServerTrusted(certs, authType, (String) null);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, socket);
+ checkPins(trustedChain);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, engine);
+ checkPins(trustedChain);
}
/**
@@ -157,4 +187,11 @@
return mIssuers.clone();
}
}
+
+ public void handleTrustStorageUpdate() {
+ synchronized (mIssuersLock) {
+ mIssuers = null;
+ mDelegate.handleTrustStorageUpdate();
+ }
+ }
}
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index 22fbee2..78669c5 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -115,4 +115,9 @@
}
return certs;
}
+
+ @Override
+ public void handleTrustStorageUpdate() {
+ // Nothing to do, resource sources never change.
+ }
}
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index b4e58e6..19f6887 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -16,24 +16,28 @@
package android.security.net.config;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} based on an {@link ApplicationConfig}.
+ * {@link X509ExtendedTrustManager} based on an {@link ApplicationConfig}.
*
- * <p>This {@code X509TrustManager} delegates to the specific trust manager for the hostname
- * being used for the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
+ * <p>This trust manager delegates to the specific trust manager for the hostname being used for
+ * the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
* {@link NetworkSecurityTrustManager}).</p>
*
* Note that if the {@code ApplicationConfig} has per-domain configurations the hostname aware
* {@link #checkServerTrusted(X509Certificate[], String String)} must be used instead of the normal
* non-aware call.
* @hide */
-public class RootTrustManager implements X509TrustManager {
+public class RootTrustManager extends X509ExtendedTrustManager {
private final ApplicationConfig mConfig;
public RootTrustManager(ApplicationConfig config) {
@@ -53,6 +57,54 @@
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ if (socket instanceof SSLSocket) {
+ SSLSocket sslSocket = (SSLSocket) socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, socket);
+ } else {
+ // Not an SSLSocket, use the hostname unaware checkServerTrusted.
+ checkServerTrusted(certs, authType);
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ SSLSession session = engine.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
if (mConfig.hasPerDomainConfigs()) {
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index 085613f..356804e 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -152,6 +152,9 @@
{"en-UM", "en-US"}, // English (United States Minor Outlying Islands)
{"en-VI", "en-US"}, // English (Virgin Islands)
+ // All English locales other than those falling back to en-US are mapped to en-GB.
+ {"en", "en-GB"},
+
// For German, we're assuming the 1996 (and later) orthography by default.
{"de", "de-1996"},
// Liechtenstein uses the Swiss hyphenation rules for the 1901 orthography.
@@ -160,6 +163,9 @@
// Norwegian is very probably Norwegian Bokmål.
{"no", "nb"},
+ // Use mn-Cyrl. According to CLDR's likelySubtags.xml, mn is most likely to be mn-Cyrl.
+ {"mn", "mn-Cyrl"}, // Mongolian
+
// Fall back to Ethiopic script for languages likely to be written in Ethiopic.
// Data is from CLDR's likelySubtags.xml.
// TODO: Convert this to a mechanism using ICU4J's ULocale#addLikelySubtags().
@@ -182,15 +188,36 @@
// TODO: replace this with a discovery-based method that looks into /system/usr/hyphen-data
String[] availableLanguages = {
+ "as",
+ "bn",
+ "cy",
+ "da",
"de-1901", "de-1996", "de-CH-1901",
- "en-US",
+ "en-GB", "en-US",
"es",
+ "et",
+ "eu",
+ "fr",
+ "ga",
+ "gu",
+ "hi",
+ "hr",
"hu",
"hy",
+ "kn",
+ "ml",
+ "mn-Cyrl",
+ "mr",
"nb",
"nn",
+ "or",
+ "pa",
"pt",
- "und-Ethi"
+ "sl",
+ "ta",
+ "te",
+ "tk",
+ "und-Ethi",
};
for (int i = 0; i < availableLanguages.length; i++) {
String languageTag = availableLanguages[i];
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 692d848..0bd5071 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -799,6 +799,31 @@
return false;
}
+ /**
+ * Returns the range of the run that the character at offset belongs to.
+ * @param offset the offset
+ * @return The range of the run
+ * @hide
+ */
+ public long getRunRange(int offset) {
+ int line = getLineForOffset(offset);
+ Directions dirs = getLineDirections(line);
+ if (dirs == DIRS_ALL_LEFT_TO_RIGHT || dirs == DIRS_ALL_RIGHT_TO_LEFT) {
+ return TextUtils.packRangeInLong(0, getLineEnd(line));
+ }
+ int[] runs = dirs.mDirections;
+ int lineStart = getLineStart(line);
+ for (int i = 0; i < runs.length; i += 2) {
+ int start = lineStart + runs[i];
+ int limit = start + (runs[i+1] & RUN_LENGTH_MASK);
+ if (offset >= start && offset < limit) {
+ return TextUtils.packRangeInLong(start, limit);
+ }
+ }
+ // Should happen only if the offset is "out of bounds"
+ return TextUtils.packRangeInLong(0, getLineEnd(line));
+ }
+
private boolean primaryIsTrailingPrevious(int offset) {
int line = getLineForOffset(offset);
int lineStart = getLineStart(line);
@@ -886,6 +911,10 @@
return getHorizontal(offset, !trailing, clamped);
}
+ private float getHorizontal(int offset, boolean primary) {
+ return primary ? getPrimaryHorizontal(offset) : getSecondaryHorizontal(offset);
+ }
+
private float getHorizontal(int offset, boolean trailing, boolean clamped) {
int line = getLineForOffset(offset);
@@ -1114,6 +1143,20 @@
* closest to the specified horizontal position.
*/
public int getOffsetForHorizontal(int line, float horiz) {
+ return getOffsetForHorizontal(line, horiz, true);
+ }
+
+ /**
+ * Get the character offset on the specified line whose position is
+ * closest to the specified horizontal position.
+ *
+ * @param line the line used to find the closest offset
+ * @param horiz the horizontal position used to find the closest offset
+ * @param primary whether to use the primary position or secondary position to find the offset
+ *
+ * @hide
+ */
+ public int getOffsetForHorizontal(int line, float horiz, boolean primary) {
// TODO: use Paint.getOffsetForAdvance to avoid binary search
final int lineEndOffset = getLineEnd(line);
final int lineStartOffset = getLineStart(line);
@@ -1133,7 +1176,7 @@
!isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
}
int best = lineStartOffset;
- float bestdist = Math.abs(getPrimaryHorizontal(best) - 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];
@@ -1149,7 +1192,7 @@
guess = (high + low) / 2;
int adguess = getOffsetAtStartOf(guess);
- if (getPrimaryHorizontal(adguess) * swap >= horiz * swap)
+ if (getHorizontal(adguess, primary) * swap >= horiz * swap)
high = guess;
else
low = guess;
@@ -1162,9 +1205,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(getPrimaryHorizontal(low) - horiz);
+ float dist = Math.abs(getHorizontal(low, primary) - horiz);
if (aft < there) {
- float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
+ float other = Math.abs(getHorizontal(aft, primary) - horiz);
if (other < dist) {
dist = other;
@@ -1179,7 +1222,7 @@
}
}
- float dist = Math.abs(getPrimaryHorizontal(here) - horiz);
+ float dist = Math.abs(getHorizontal(here, primary) - horiz);
if (dist < bestdist) {
bestdist = dist;
@@ -1187,7 +1230,7 @@
}
}
- float dist = Math.abs(getPrimaryHorizontal(max) - horiz);
+ float dist = Math.abs(getHorizontal(max, primary) - horiz);
if (dist <= bestdist) {
bestdist = dist;
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 4eaab37..6579212 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -84,6 +84,7 @@
}
private int mMode = MODE_IN | MODE_OUT;
+ private boolean mSuppressLayout = true;
public Visibility() {}
@@ -98,6 +99,15 @@
}
/**
+ * This tells the Visibility transition to suppress layout during the transition and release
+ * the suppression after the transition.
+ * @hide
+ */
+ public void setSuppressLayout(boolean suppress) {
+ this.mSuppressLayout = suppress;
+ }
+
+ /**
* Changes the transition to support appearing and/or disappearing Views, depending
* on <code>mode</code>.
*
@@ -428,7 +438,7 @@
Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
if (animator != null) {
DisappearListener disappearListener = new DisappearListener(viewToKeep,
- finalVisibility);
+ finalVisibility, mSuppressLayout);
animator.addListener(disappearListener);
animator.addPauseListener(disappearListener);
addListener(disappearListener);
@@ -483,14 +493,16 @@
private final View mView;
private final int mFinalVisibility;
private final ViewGroup mParent;
+ private final boolean mSuppressLayout;
private boolean mLayoutSuppressed;
boolean mCanceled = false;
- public DisappearListener(View view, int finalVisibility) {
+ public DisappearListener(View view, int finalVisibility, boolean suppressLayout) {
this.mView = view;
this.mFinalVisibility = finalVisibility;
this.mParent = (ViewGroup) view.getParent();
+ this.mSuppressLayout = suppressLayout;
// Prevent a layout from including mView in its calculation.
suppressLayout(true);
}
@@ -555,7 +567,7 @@
}
private void suppressLayout(boolean suppress) {
- if (mLayoutSuppressed != suppress && mParent != null) {
+ if (mSuppressLayout && mLayoutSuppressed != suppress && mParent != null) {
mLayoutSuppressed = suppress;
mParent.suppressLayout(suppress);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 83c6e9e..6811aed 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2429,7 +2429,11 @@
* 1 PFLAG3_SCROLL_INDICATOR_START
* 1 PFLAG3_SCROLL_INDICATOR_END
* 1 PFLAG3_ASSIST_BLOCKED
- * 1111111 PFLAG3_POINTER_ICON_MASK
+ * 1 PFLAG3_POINTER_ICON_NULL
+ * 1 PFLAG3_POINTER_ICON_VALUE_START
+ * 11111111 PFLAG3_POINTER_ICON_MASK
+ * 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE
+ * 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED
* |-------|-------|-------|-------|
*/
@@ -2518,8 +2522,6 @@
*/
static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
- /* End of masks for mPrivateFlags3 */
-
static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
static final int SCROLL_INDICATORS_NONE = 0x0000;
@@ -2651,6 +2653,23 @@
private static final int PFLAG3_POINTER_ICON_VALUE_START = 2 << PFLAG3_POINTER_ICON_LSHIFT;
/**
+ * Whether this view has rendered elements that overlap (see {@link
+ * #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and
+ * {@link #getHasOverlappingRendering()} ). The value in this bit is only valid when
+ * PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED has been set. Otherwise, the value is
+ * determined by whatever {@link #hasOverlappingRendering()} returns.
+ */
+ private static final int PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE = 0x800000;
+
+ /**
+ * Whether {@link #forceHasOverlappingRendering(boolean)} has been called. When true, value
+ * in PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE is valid.
+ */
+ private static final int PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED = 0x1000000;
+
+ /* End of masks for mPrivateFlags3 */
+
+ /**
* Always allow a user to over-scroll this view, provided it is a
* view that can scroll.
*
@@ -4516,6 +4535,12 @@
}
}
break;
+ case R.styleable.View_forceHasOverlappingRendering:
+ if (a.peekValue(attr) != null) {
+ forceHasOverlappingRendering(a.getBoolean(attr, true));
+ }
+ break;
+
}
}
@@ -12116,6 +12141,42 @@
}
/**
+ * Sets the behavior for overlapping rendering for this view (see {@link
+ * #hasOverlappingRendering()} for more details on this behavior). Calling this method
+ * is an alternative to overriding {@link #hasOverlappingRendering()} in a subclass,
+ * providing the value which is then used internally. That is, when {@link
+ * #forceHasOverlappingRendering(boolean)} is called, the value of {@link
+ * #hasOverlappingRendering()} is ignored and the value passed into this method is used
+ * instead.
+ *
+ * @param hasOverlappingRendering The value for overlapping rendering to be used internally
+ * instead of that returned by {@link #hasOverlappingRendering()}.
+ *
+ * @attr ref android.R.styleable#View_forceHasOverlappingRendering
+ */
+ public void forceHasOverlappingRendering(boolean hasOverlappingRendering) {
+ mPrivateFlags3 |= PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED;
+ if (hasOverlappingRendering) {
+ mPrivateFlags3 |= PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE;
+ } else {
+ mPrivateFlags3 &= ~PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE;
+ }
+ }
+
+ /**
+ * Returns the value for overlapping rendering that is used internally. This is either
+ * the value passed into {@link #forceHasOverlappingRendering(boolean)}, if called, or
+ * the return value of {@link #hasOverlappingRendering()}, otherwise.
+ *
+ * @return The value for overlapping rendering being used internally.
+ */
+ public final boolean getHasOverlappingRendering() {
+ return (mPrivateFlags3 & PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED) != 0 ?
+ (mPrivateFlags3 & PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE) != 0 :
+ hasOverlappingRendering();
+ }
+
+ /**
* Returns whether this View has content which overlaps.
*
* <p>This function, intended to be overridden by specific View types, is an optimization when
@@ -12131,6 +12192,9 @@
* necessitates that a View return true if it uses the methods internally without passing the
* {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
*
+ * <p><strong>Note:</strong> The return value of this method is ignored if {@link
+ * #forceHasOverlappingRendering(boolean)} has been called on this view.</p>
+ *
* @return true if the content in this view might overlap, false otherwise.
*/
@ViewDebug.ExportedProperty(category = "drawing")
@@ -16566,7 +16630,7 @@
*/
void setDisplayListProperties(RenderNode renderNode) {
if (renderNode != null) {
- renderNode.setHasOverlappingRendering(hasOverlappingRendering());
+ renderNode.setHasOverlappingRendering(getHasOverlappingRendering());
renderNode.setClipToBounds(mParent instanceof ViewGroup
&& ((ViewGroup) mParent).getClipChildren());
@@ -16855,9 +16919,14 @@
} else {
// use layer paint to draw the bitmap, merging the two alphas, but also restore
int layerPaintAlpha = mLayerPaint != null ? mLayerPaint.getAlpha() : 255;
- mLayerPaint.setAlpha((int) (alpha * layerPaintAlpha));
+ if (mLayerPaint == null && alpha < 1) {
+ mLayerPaint = new Paint();
+ mLayerPaint.setAlpha((int) (alpha * layerPaintAlpha));
+ }
canvas.drawBitmap(cache, 0.0f, 0.0f, mLayerPaint);
- mLayerPaint.setAlpha(layerPaintAlpha);
+ if (mLayerPaint != null) {
+ mLayerPaint.setAlpha(layerPaintAlpha);
+ }
}
}
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index f18b7ac..c5b8849 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -1113,13 +1113,6 @@
if (mListener != null) {
mListener.onAnimationEnd(animation);
}
- if (mAnimatorOnEndMap != null) {
- Runnable r = mAnimatorOnEndMap.get(animation);
- if (r != null) {
- r.run();
- }
- mAnimatorOnEndMap.remove(animation);
- }
if (mAnimatorCleanupMap != null) {
Runnable r = mAnimatorCleanupMap.get(animation);
if (r != null) {
@@ -1127,6 +1120,13 @@
}
mAnimatorCleanupMap.remove(animation);
}
+ if (mAnimatorOnEndMap != null) {
+ Runnable r = mAnimatorOnEndMap.get(animation);
+ if (r != null) {
+ r.run();
+ }
+ mAnimatorOnEndMap.remove(animation);
+ }
mAnimatorMap.remove(animation);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9418aaf..5d4ee874 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -85,6 +85,7 @@
import android.widget.Scroller;
import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.SomeArgs;
import com.android.internal.policy.PhoneFallbackEventHandler;
@@ -154,7 +155,12 @@
static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList();
- final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList();
+ /**
+ * This list must only be modified by the main thread, so a lock is only needed when changing
+ * the list or when accessing the list from a non-main thread.
+ */
+ @GuardedBy("mWindowCallbacks")
+ final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList<>();
final Context mContext;
final IWindowSession mWindowSession;
final Display mDisplay;
@@ -2120,7 +2126,7 @@
boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
- if (!cancelDraw) {
+ if (!cancelDraw && !newSurface) {
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
for (int i = 0; i < mPendingTransitions.size(); ++i) {
mPendingTransitions.get(i).startChangingAnimations();
@@ -2169,7 +2175,6 @@
}
}
}
-
private void handleOutOfResourcesException(Surface.OutOfResourcesException e) {
Log.e(mTag, "OutOfResourcesException initializing HW surface", e);
try {
@@ -2437,10 +2442,8 @@
@Override
public void onHardwarePostDraw(DisplayListCanvas canvas) {
drawAccessibilityFocusedDrawableIfNeeded(canvas);
- synchronized (mWindowCallbacks) {
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onPostDraw(canvas);
- }
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onPostDraw(canvas);
}
}
@@ -3300,7 +3303,6 @@
private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
- private final static int MSG_FINISH_INPUT_CONNECTION = 12;
private final static int MSG_CHECK_FOCUS = 13;
private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3340,8 +3342,6 @@
return "MSG_DISPATCH_GET_NEW_SURFACE";
case MSG_DISPATCH_KEY_FROM_IME:
return "MSG_DISPATCH_KEY_FROM_IME";
- case MSG_FINISH_INPUT_CONNECTION:
- return "MSG_FINISH_INPUT_CONNECTION";
case MSG_CHECK_FOCUS:
return "MSG_CHECK_FOCUS";
case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -3562,12 +3562,6 @@
}
enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
} break;
- case MSG_FINISH_INPUT_CONNECTION: {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- imm.reportFinishInputConnection((InputConnection)msg.obj);
- }
- } break;
case MSG_CHECK_FOCUS: {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
@@ -5878,11 +5872,6 @@
}
}
- public void dispatchFinishInputConnection(InputConnection connection) {
- Message msg = mHandler.obtainMessage(MSG_FINISH_INPUT_CONNECTION, connection);
- mHandler.sendMessage(msg);
- }
-
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig, Rect backDropFrame, boolean forceLayout,
@@ -7106,11 +7095,9 @@
Rect stableInsets, int resizeMode) {
if (!mDragResizing) {
mDragResizing = true;
- synchronized (mWindowCallbacks) {
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onWindowDragResizeStart(initialBounds, fullscreen,
- systemInsets, stableInsets, resizeMode);
- }
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onWindowDragResizeStart(initialBounds, fullscreen,
+ systemInsets, stableInsets, resizeMode);
}
mFullRedrawNeeded = true;
}
@@ -7122,10 +7109,8 @@
private void endDragResizing() {
if (mDragResizing) {
mDragResizing = false;
- synchronized (mWindowCallbacks) {
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onWindowDragResizeEnd();
- }
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onWindowDragResizeEnd();
}
mFullRedrawNeeded = true;
}
@@ -7133,13 +7118,11 @@
private boolean updateContentDrawBounds() {
boolean updated = false;
- synchronized (mWindowCallbacks) {
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- updated |= mWindowCallbacks.get(i).onContentDrawn(
- mWindowAttributes.surfaceInsets.left,
- mWindowAttributes.surfaceInsets.top,
- mWidth, mHeight);
- }
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ updated |= mWindowCallbacks.get(i).onContentDrawn(
+ mWindowAttributes.surfaceInsets.left,
+ mWindowAttributes.surfaceInsets.top,
+ mWidth, mHeight);
}
return updated | (mDragResizing && mReportNextDraw);
}
@@ -7148,10 +7131,8 @@
if (mReportNextDraw) {
mWindowDrawCountDown = new CountDownLatch(mWindowCallbacks.size());
}
- synchronized (mWindowCallbacks) {
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onRequestDraw(mReportNextDraw);
- }
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onRequestDraw(mReportNextDraw);
}
}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 929fdac..750931a 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -91,6 +91,7 @@
mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
mStableInsetsConsumed = src.mStableInsetsConsumed;
mIsRound = src.mIsRound;
+ mAlwaysConsumeNavBar = src.mAlwaysConsumeNavBar;
}
/** @hide */
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index c22d60d..3ad730b 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -16,6 +16,7 @@
package android.view;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.Region;
@@ -157,6 +158,15 @@
public abstract void setMagnificationSpec(MagnificationSpec spec);
/**
+ * Obtains the magnified and available regions.
+ *
+ * @param outMagnified the currently magnified region
+ * @param outAvailable the region available for magnification
+ */
+ public abstract void getMagnificationRegions(@NonNull Region outMagnified,
+ @NonNull Region outAvailable);
+
+ /**
* Gets the magnification and translation applied to a window given its token.
* Not all windows are magnified and the window manager policy determines which
* windows are magnified. The returned result also takes into account the compat
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 6a830f8..a3c49c5 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -158,8 +158,8 @@
*
* @hide
*/
- protected void reportFinish() {
- // Intentionaly empty
+ public void reportFinish() {
+ // Intentionally empty
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index cf5cc3e..f5908a5 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -317,7 +317,6 @@
/**
* The InputConnection that was last retrieved from the served view.
*/
- InputConnection mServedInputConnection;
ControlledInputConnectionWrapper mServedInputConnectionWrapper;
/**
* The completions that were last provided by the served view.
@@ -494,12 +493,7 @@
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
if (mServedView != null && mServedView.hasWindowFocus()) {
- // Please note that this handler thread could be different
- // from a thread that created mServedView. That could happen
- // the current activity is running in the system process.
- // In that case, we really should not call
- // mServedInputConnection.finishComposingText.
- if (checkFocusNoStartInput(mHasBeenInactive, false)) {
+ if (checkFocusNoStartInput(mHasBeenInactive)) {
final int reason = active ?
InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS;
@@ -532,22 +526,25 @@
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
private final InputMethodManager mParentInputMethodManager;
- private boolean mActive;
public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
final InputMethodManager inputMethodManager) {
super(mainLooper, conn);
mParentInputMethodManager = inputMethodManager;
- mActive = true;
}
@Override
public boolean isActive() {
- return mParentInputMethodManager.mActive && mActive;
+ return mParentInputMethodManager.mActive && !isFinished();
}
void deactivate() {
- mActive = false;
+ if (isFinished()) {
+ // This is a small performance optimization. Still only the 1st call of
+ // reportFinish() will take effect.
+ return;
+ }
+ reportFinish();
}
@Override
@@ -562,7 +559,9 @@
@Override
public String toString() {
- return "ControlledInputConnectionWrapper{mActive=" + mActive
+ return "ControlledInputConnectionWrapper{"
+ + "connection=" + getInputConnection()
+ + " finished=" + isFinished()
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
+ "}";
}
@@ -780,7 +779,8 @@
*/
public boolean isAcceptingText() {
checkFocus();
- return mServedInputConnection != null;
+ return mServedInputConnectionWrapper != null &&
+ mServedInputConnectionWrapper.getInputConnection() != null;
}
/**
@@ -815,7 +815,6 @@
*/
void clearConnectionLocked() {
mCurrentTextBoxAttribute = null;
- mServedInputConnection = null;
if (mServedInputConnectionWrapper != null) {
mServedInputConnectionWrapper.deactivate();
mServedInputConnectionWrapper = null;
@@ -828,7 +827,7 @@
void finishInputLocked() {
mNextServedView = null;
if (mServedView != null) {
- if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView);
+ if (DEBUG) Log.v(TAG, "FINISH INPUT: mServedView=" + dumpViewInfo(mServedView));
if (mCurrentTextBoxAttribute != null) {
try {
mService.finishInput(mClient);
@@ -836,7 +835,6 @@
throw e.rethrowFromSystemServer();
}
}
- notifyInputConnectionFinished();
mServedView = null;
mCompletions = null;
mServedConnecting = false;
@@ -844,37 +842,6 @@
}
}
- /**
- * Notifies the served view that the current InputConnection will no longer be used.
- */
- private void notifyInputConnectionFinished() {
- if (mServedView != null && mServedInputConnection != null) {
- // We need to tell the previously served view that it is no
- // longer the input target, so it can reset its state. Schedule
- // this call on its window's Handler so it will be on the correct
- // thread and outside of our lock.
- ViewRootImpl viewRootImpl = mServedView.getViewRootImpl();
- if (viewRootImpl != null) {
- // This will result in a call to reportFinishInputConnection() below.
- viewRootImpl.dispatchFinishInputConnection(mServedInputConnection);
- }
- }
- }
-
- /**
- * Called from the FINISH_INPUT_CONNECTION message above.
- * @hide
- */
- public void reportFinishInputConnection(InputConnection ic) {
- if (mServedInputConnection != ic) {
- ic.finishComposingText();
- // To avoid modifying the public InputConnection interface
- if (ic instanceof BaseInputConnection) {
- ((BaseInputConnection) ic).reportFinish();
- }
- }
- }
-
public void displayCompletions(View view, CompletionInfo[] completions) {
checkFocus();
synchronized (mH) {
@@ -1169,10 +1136,10 @@
final View view;
synchronized (mH) {
view = mServedView;
-
+
// Make sure we have a window token for the served view.
if (DEBUG) {
- Log.v(TAG, "Starting input: view=" + view +
+ Log.v(TAG, "Starting input: view=" + dumpViewInfo(view) +
" reason=" + InputMethodClient.getStartInputReason(startInputReason));
}
if (view == null) {
@@ -1180,7 +1147,7 @@
return false;
}
}
-
+
// Now we need to get an input connection from the served view.
// This is complicated in a couple ways: we can't be holding our lock
// when calling out to the view, and we need to make sure we call into
@@ -1225,9 +1192,10 @@
// changed.
if (mServedView != view || !mServedConnecting) {
// Something else happened, so abort.
- if (DEBUG) Log.v(TAG,
- "Starting input: finished by someone else (view="
- + mServedView + " conn=" + mServedConnecting + ")");
+ if (DEBUG) Log.v(TAG,
+ "Starting input: finished by someone else. view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView)
+ + " mServedConnecting=" + mServedConnecting);
return false;
}
@@ -1240,9 +1208,10 @@
// Hook 'em up and let 'er rip.
mCurrentTextBoxAttribute = tba;
mServedConnecting = false;
- // Notify the served view that its previous input connection is finished
- notifyInputConnectionFinished();
- mServedInputConnection = ic;
+ if (mServedInputConnectionWrapper != null) {
+ mServedInputConnectionWrapper.deactivate();
+ mServedInputConnectionWrapper = null;
+ }
ControlledInputConnectionWrapper servedContext;
final int missingMethodFlags;
if (ic != null) {
@@ -1267,13 +1236,10 @@
servedContext = null;
missingMethodFlags = 0;
}
- if (mServedInputConnectionWrapper != null) {
- mServedInputConnectionWrapper.deactivate();
- }
mServedInputConnectionWrapper = servedContext;
try {
- if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
+ if (DEBUG) Log.v(TAG, "START INPUT: view=" + dumpViewInfo(view) + " ic="
+ ic + " tba=" + tba + " controlFlags=#"
+ Integer.toHexString(controlFlags));
final InputBindResult res = mService.startInputOrWindowGainedFocus(
@@ -1339,7 +1305,7 @@
}
void focusInLocked(View view) {
- if (DEBUG) Log.v(TAG, "focusIn: " + view);
+ if (DEBUG) Log.v(TAG, "focusIn: " + dumpViewInfo(view));
if (mCurRootView != view.getRootView()) {
// This is a request from a window that isn't in the window with
@@ -1358,9 +1324,8 @@
*/
public void focusOut(View view) {
synchronized (mH) {
- if (DEBUG) Log.v(TAG, "focusOut: " + view
- + " mServedView=" + mServedView
- + " winFocus=" + view.hasWindowFocus());
+ if (DEBUG) Log.v(TAG, "focusOut: view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView));
if (mServedView != view) {
// The following code would auto-hide the IME if we end up
// with no more views with focus. This can happen, however,
@@ -1381,9 +1346,8 @@
*/
public void onViewDetachedFromWindow(View view) {
synchronized (mH) {
- if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: " + view
- + " mServedView=" + mServedView
- + " hasWindowFocus=" + view.hasWindowFocus());
+ if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView));
if (mServedView == view && view.hasWindowFocus()) {
mNextServedView = null;
scheduleCheckFocusLocked(view);
@@ -1402,18 +1366,18 @@
* @hide
*/
public void checkFocus() {
- if (checkFocusNoStartInput(false, true)) {
+ if (checkFocusNoStartInput(false)) {
startInputInner(InputMethodClient.START_INPUT_REASON_CHECK_FOCUS, null, 0, 0, 0);
}
}
- private boolean checkFocusNoStartInput(boolean forceNewFocus, boolean finishComposingText) {
+ private boolean checkFocusNoStartInput(boolean forceNewFocus) {
// This is called a lot, so short-circuit before locking.
if (mServedView == mNextServedView && !forceNewFocus) {
return false;
}
- InputConnection ic = null;
+ final ControlledInputConnectionWrapper ic;
synchronized (mH) {
if (mServedView == mNextServedView && !forceNewFocus) {
return false;
@@ -1433,7 +1397,7 @@
return false;
}
- ic = mServedInputConnection;
+ ic = mServedInputConnectionWrapper;
mServedView = mNextServedView;
mCurrentTextBoxAttribute = null;
@@ -1441,7 +1405,7 @@
mServedConnecting = true;
}
- if (finishComposingText && ic != null) {
+ if (ic != null) {
ic.finishComposingText();
}
@@ -1487,7 +1451,7 @@
controlFlags |= CONTROL_WINDOW_FIRST;
}
- if (checkFocusNoStartInput(forceNewFocus, true)) {
+ if (checkFocusNoStartInput(forceNewFocus)) {
// We need to restart input on the current focus view. This
// should be done in conjunction with telling the system service
// about the window gaining focus, to help make the transition
@@ -2282,7 +2246,7 @@
} else {
p.println(" mCurrentTextBoxAttribute: null");
}
- p.println(" mServedInputConnection=" + mServedInputConnection);
+ p.println(" mServedInputConnectionWrapper=" + mServedInputConnectionWrapper);
p.println(" mCompletions=" + Arrays.toString(mCompletions));
p.println(" mCursorRect=" + mCursorRect);
p.println(" mCursorSelStart=" + mCursorSelStart
@@ -2341,4 +2305,16 @@
}
}
}
+
+ private static String dumpViewInfo(@Nullable final View view) {
+ if (view == null) {
+ return "null";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(view);
+ sb.append(",focus=" + view.hasFocus());
+ sb.append(",windowFocus=" + view.hasWindowFocus());
+ sb.append(",window=" + view.getWindowToken());
+ return sb.toString();
+ }
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index f1bf890..d884f19 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -128,11 +128,6 @@
public MissingWebViewPackageException(Exception e) { super(e); }
}
- // TODO (gsennton) remove when committing webview xts test change
- public static String getWebViewPackageName() {
- return null;
- }
-
/**
* @hide
*/
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 942cbcb..59d857c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4034,14 +4034,17 @@
// Don't update drawable during dragging.
return;
}
+ final Layout layout = mTextView.getLayout();
+ if (layout == null) {
+ return;
+ }
final int offset = getCurrentCursorOffset();
- final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
+ final boolean isRtlCharAtOffset = isAtRtlRun(layout, offset);
final Drawable oldDrawable = mDrawable;
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
- final Layout layout = mTextView.getLayout();
- if (layout != null && oldDrawable != mDrawable && isShowing()) {
+ if (oldDrawable != mDrawable && isShowing()) {
// Update popup window position.
mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX -
getHorizontalOffset() + getCursorOffset();
@@ -4154,6 +4157,19 @@
public abstract void updatePosition(float x, float y);
+ protected boolean isAtRtlRun(@NonNull Layout layout, int offset) {
+ return layout.isRtlCharAt(offset);
+ }
+
+ @VisibleForTesting
+ public float getHorizontal(@NonNull Layout layout, int offset) {
+ return layout.getPrimaryHorizontal(offset);
+ }
+
+ protected int getOffsetAtCoordinate(@NonNull Layout layout, int line, float x) {
+ return mTextView.getOffsetAtCoordinate(line, x);
+ }
+
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
// A HandleView relies on the layout, which may be nulled by external methods
Layout layout = mTextView.getLayout();
@@ -4194,7 +4210,7 @@
* @return The clamped horizontal position for the cursor.
*/
int getCursorHorizontalPosition(Layout layout, int offset) {
- return (int) (layout.getPrimaryHorizontal(offset) - 0.5f);
+ return (int) (getHorizontal(layout, offset) - 0.5f);
}
public void updatePosition(int parentPositionX, int parentPositionY,
@@ -4427,7 +4443,7 @@
int getCursorHorizontalPosition(Layout layout, int offset) {
final Drawable drawable = mCursorCount > 0 ? mCursorDrawable[0] : null;
if (drawable != null) {
- final float horizontal = layout.getPrimaryHorizontal(offset);
+ final float horizontal = getHorizontal(layout, offset);
return clampHorizontalPosition(drawable, horizontal) + mTempRect.left;
}
return super.getCursorHorizontalPosition(layout, offset);
@@ -4499,10 +4515,10 @@
mPreviousLineTouched = mTextView.getLineAtCoordinate(y);
}
int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
- offset = mTextView.getOffsetAtCoordinate(currLine, x);
+ offset = getOffsetAtCoordinate(layout, currLine, x);
mPreviousLineTouched = currLine;
} else {
- offset = mTextView.getOffsetForPosition(x, y);
+ offset = -1;
}
positionAtCursorOffset(offset, false);
if (mTextActionMode != null) {
@@ -4612,14 +4628,14 @@
final int anotherHandleOffset =
isStartHandle() ? mTextView.getSelectionEnd() : mTextView.getSelectionStart();
int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
- int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+ int initialOffset = getOffsetAtCoordinate(layout, currLine, x);
if (isStartHandle() && initialOffset >= anotherHandleOffset
|| !isStartHandle() && initialOffset <= anotherHandleOffset) {
// Handles have crossed, bound it to the first selected line and
// adjust by word / char as normal.
currLine = layout.getLineForOffset(anotherHandleOffset);
- initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+ initialOffset = getOffsetAtCoordinate(layout, currLine, x);
}
int offset = initialOffset;
@@ -4631,8 +4647,8 @@
}
final int currentOffset = getCurrentCursorOffset();
- final boolean rtlAtCurrentOffset = layout.isRtlCharAt(currentOffset);
- final boolean atRtl = layout.isRtlCharAt(offset);
+ final boolean rtlAtCurrentOffset = isAtRtlRun(layout, currentOffset);
+ final boolean atRtl = isAtRtlRun(layout, offset);
final boolean isLvlBoundary = layout.isLevelBoundary(offset);
// We can't determine if the user is expanding or shrinking the selection if they're
@@ -4689,14 +4705,15 @@
if (isExpanding) {
// User is increasing the selection.
- final boolean snapToWord = !mInWord
- || (isStartHandle() ? currLine < mPrevLine : currLine > mPrevLine);
+ int wordBoundary = isStartHandle() ? wordStart : wordEnd;
+ 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.
- int wordBoundary = isStartHandle() ? wordStart : wordEnd;
- if (layout != null && layout.getLineForOffset(wordBoundary) != currLine) {
+ if (layout.getLineForOffset(wordBoundary) != currLine) {
wordBoundary = isStartHandle() ?
layout.getLineStart(currLine) : layout.getLineEnd(currLine);
}
@@ -4717,9 +4734,9 @@
offset = mPreviousOffset;
}
}
- if (layout != null && (isStartHandle() && offset < initialOffset)
+ if ((isStartHandle() && offset < initialOffset)
|| (!isStartHandle() && offset > initialOffset)) {
- final float adjustedX = layout.getPrimaryHorizontal(offset);
+ final float adjustedX = getHorizontal(layout, offset);
mTouchWordDelta =
mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
} else {
@@ -4728,7 +4745,7 @@
positionCursor = true;
} else {
final int adjustedOffset =
- mTextView.getOffsetAtCoordinate(currLine, x - mTouchWordDelta);
+ getOffsetAtCoordinate(layout, currLine, x - mTouchWordDelta);
final boolean shrinking = isStartHandle()
? adjustedOffset > mPreviousOffset || currLine > mPrevLine
: adjustedOffset < mPreviousOffset || currLine < mPrevLine;
@@ -4737,9 +4754,9 @@
if (currLine != mPrevLine) {
// We're on a different line, so we'll snap to word boundaries.
offset = isStartHandle() ? wordStart : wordEnd;
- if (layout != null && (isStartHandle() && offset < initialOffset)
+ if ((isStartHandle() && offset < initialOffset)
|| (!isStartHandle() && offset > initialOffset)) {
- final float adjustedX = layout.getPrimaryHorizontal(offset);
+ final float adjustedX = getHorizontal(layout, offset);
mTouchWordDelta =
mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
} else {
@@ -4754,7 +4771,7 @@
// Handle has jumped to the word boundary, and the user is moving
// their finger towards the handle, the delta should be updated.
mTouchWordDelta = mTextView.convertToLocalHorizontalCoordinate(x) -
- layout.getPrimaryHorizontal(mPreviousOffset);
+ getHorizontal(layout, mPreviousOffset);
}
}
@@ -4792,9 +4809,32 @@
isStartHandle() ? mTextView.getSelectionEnd() : mTextView.getSelectionStart();
if ((isStartHandle() && offset >= anotherHandleOffset)
|| (!isStartHandle() && offset <= anotherHandleOffset)) {
+ mTouchWordDelta = 0.0f;
+ final Layout layout = mTextView.getLayout();
+ if (layout != null && offset != anotherHandleOffset) {
+ final float horiz = getHorizontal(layout, offset);
+ final float anotherHandleHoriz = getHorizontal(layout, anotherHandleOffset,
+ !isStartHandle());
+ final float currentHoriz = getHorizontal(layout, mPreviousOffset);
+ if (currentHoriz < anotherHandleHoriz && horiz < anotherHandleHoriz
+ || currentHoriz > anotherHandleHoriz && horiz > anotherHandleHoriz) {
+ // This handle passes another one as it crossed a direction boundary.
+ // Don't minimize the selection, but keep the handle at the run boundary.
+ final int currentOffset = getCurrentCursorOffset();
+ final int offsetToGetRunRange = isStartHandle() ?
+ currentOffset : Math.max(currentOffset - 1, 0);
+ final long range = layout.getRunRange(offsetToGetRunRange);
+ if (isStartHandle()) {
+ offset = TextUtils.unpackRangeStartFromLong(range);
+ } else {
+ offset = TextUtils.unpackRangeEndFromLong(range);
+ }
+ positionAtCursorOffset(offset, false);
+ return;
+ }
+ }
// Handles can not cross and selection is at least one character.
offset = getNextCursorOffset(anotherHandleOffset, !isStartHandle());
- mTouchWordDelta = 0.0f;
}
positionAtCursorOffset(offset, false);
}
@@ -4812,6 +4852,49 @@
}
return nearEdge;
}
+
+ @Override
+ protected boolean isAtRtlRun(@NonNull Layout layout, int offset) {
+ final int offsetToCheck = isStartHandle() ? offset : Math.max(offset - 1, 0);
+ return layout.isRtlCharAt(offsetToCheck);
+ }
+
+ @Override
+ public float getHorizontal(@NonNull Layout layout, int offset) {
+ return getHorizontal(layout, offset, isStartHandle());
+ }
+
+ private float getHorizontal(@NonNull Layout layout, int offset, boolean startHandle) {
+ 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) : layout.getSecondaryHorizontal(offset);
+ }
+
+ @Override
+ protected int getOffsetAtCoordinate(@NonNull Layout layout, int line, float x) {
+ final int primaryOffset = layout.getOffsetForHorizontal(line, x, true);
+ if (!layout.isLevelBoundary(primaryOffset)) {
+ return primaryOffset;
+ }
+ final int secondaryOffset = layout.getOffsetForHorizontal(line, x, false);
+ final int currentOffset = getCurrentCursorOffset();
+ final int primaryDiff = Math.abs(primaryOffset - currentOffset);
+ final int secondaryDiff = Math.abs(secondaryOffset - currentOffset);
+ if (primaryDiff < secondaryDiff) {
+ return primaryOffset;
+ } else if (primaryDiff > secondaryDiff) {
+ return secondaryOffset;
+ } else {
+ final int offsetToCheck = isStartHandle() ?
+ currentOffset : Math.max(currentOffset - 1, 0);
+ final boolean isRtlChar = layout.isRtlCharAt(offsetToCheck);
+ final boolean isRtlParagraph = layout.getParagraphDirection(line) == -1;
+ return isRtlChar == isRtlParagraph ? primaryOffset : secondaryOffset;
+ }
+ }
}
private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 5b4a368..7658cc8 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,15 +16,14 @@
package android.widget;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.os.Trace;
+import com.google.android.collect.Lists;
+
import com.android.internal.R;
import com.android.internal.util.Predicate;
-import com.google.android.collect.Lists;
import android.annotation.IdRes;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
@@ -33,6 +32,8 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Trace;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.SparseBooleanArray;
@@ -1106,20 +1107,63 @@
}
private class FocusSelector implements Runnable {
+ // the selector is waiting to set selection on the list view
+ private static final int STATE_SET_SELECTION = 1;
+ // the selector set the selection on the list view, waiting for a layoutChildren pass
+ private static final int STATE_WAIT_FOR_LAYOUT = 2;
+ // the selector's selection has been honored and it is waiting to request focus on the
+ // target child.
+ private static final int STATE_REQUEST_FOCUS = 3;
+
+ private int mAction;
private int mPosition;
private int mPositionTop;
-
- public FocusSelector setup(int position, int top) {
+
+ FocusSelector setupForSetSelection(int position, int top) {
mPosition = position;
mPositionTop = top;
+ mAction = STATE_SET_SELECTION;
return this;
}
-
+
public void run() {
- setSelectionFromTop(mPosition, mPositionTop);
+ if (mAction == STATE_SET_SELECTION) {
+ setSelectionFromTop(mPosition, mPositionTop);
+ mAction = STATE_WAIT_FOR_LAYOUT;
+ } else if (mAction == STATE_REQUEST_FOCUS) {
+ final int childIndex = mPosition - mFirstPosition;
+ final View child = getChildAt(childIndex);
+ if (child != null) {
+ child.requestFocus();
+ }
+ mAction = -1;
+ }
+ }
+
+ @Nullable Runnable setupFocusIfValid(int position) {
+ if (mAction != STATE_WAIT_FOR_LAYOUT || position != mPosition) {
+ return null;
+ }
+ mAction = STATE_REQUEST_FOCUS;
+ return this;
+ }
+
+ void onLayoutComplete() {
+ if (mAction == STATE_WAIT_FOR_LAYOUT) {
+ mAction = -1;
+ }
}
}
-
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mFocusSelector != null) {
+ removeCallbacks(mFocusSelector);
+ mFocusSelector = null;
+ }
+ super.onDetachedFromWindow();
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (getChildCount() > 0) {
@@ -1132,7 +1176,7 @@
if (mFocusSelector == null) {
mFocusSelector = new FocusSelector();
}
- post(mFocusSelector.setup(childPosition, top));
+ post(mFocusSelector.setupForSetSelection(childPosition, top));
}
}
super.onSizeChanged(w, h, oldw, oldh);
@@ -1672,7 +1716,21 @@
adjustViewsUpOrDown();
break;
case LAYOUT_SPECIFIC:
- sel = fillSpecific(reconcileSelectedPosition(), mSpecificTop);
+ final int selectedPosition = reconcileSelectedPosition();
+ sel = fillSpecific(selectedPosition, mSpecificTop);
+ /**
+ * When ListView is resized, FocusSelector requests an async selection for the
+ * previously focused item to make sure it is still visible. If the item is not
+ * selectable, it won't regain focus so instead we call FocusSelector
+ * to directly request focus on the view after it is visible.
+ */
+ if (sel == null && mFocusSelector != null) {
+ final Runnable focusRunnable = mFocusSelector
+ .setupFocusIfValid(selectedPosition);
+ if (focusRunnable != null) {
+ post(focusRunnable);
+ }
+ }
break;
case LAYOUT_MOVE_SELECTION:
sel = moveSelection(oldSel, newSel, delta, childrenTop, childrenBottom);
@@ -1812,6 +1870,9 @@
invokeOnItemScrollListener();
} finally {
+ if (mFocusSelector != null) {
+ mFocusSelector.onLayoutComplete();
+ }
if (!blockLayoutRequests) {
mBlockLayoutRequests = false;
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 18687c9..92631da 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -173,9 +173,6 @@
private int mHeight = LayoutParams.WRAP_CONTENT;
private int mLastHeight;
- private int mPopupWidth;
- private int mPopupHeight;
-
private float mElevation;
private Drawable mBackground;
@@ -1298,8 +1295,6 @@
mPopupViewInitialLayoutDirectionInherited =
(mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
- mPopupWidth = p.width;
- mPopupHeight = p.height;
}
/**
@@ -2006,7 +2001,7 @@
* @param height the new height, must be >= 0 or -1 to ignore
*/
public void update(View anchor, int width, int height) {
- update(anchor, false, 0, 0, true, width, height);
+ update(anchor, false, 0, 0, width, height);
}
/**
@@ -2026,11 +2021,11 @@
* @param height the new height, must be >= 0 or -1 to ignore
*/
public void update(View anchor, int xoff, int yoff, int width, int height) {
- update(anchor, true, xoff, yoff, true, width, height);
+ update(anchor, true, xoff, yoff, width, height);
}
private void update(View anchor, boolean updateLocation, int xoff, int yoff,
- boolean updateDimension, int width, int height) {
+ int width, int height) {
if (!isShowing() || mContentView == null) {
return;
@@ -2055,13 +2050,13 @@
final int oldX = p.x;
final int oldY = p.y;
- if (updateDimension) {
- if (width == -1) {
- width = mPopupWidth;
- }
- if (height == -1) {
- height = mPopupHeight;
- }
+ // If an explicit width/height has not specified, use the most recent
+ // explicitly specified value (either from setWidth/Height or update).
+ if (width == -1) {
+ width = mWidth;
+ }
+ if (height == -1) {
+ height = mHeight;
}
final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3195097..a9af654 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -17,6 +17,7 @@
package android.widget;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
+
import android.R;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -3115,10 +3116,15 @@
}
/**
+ * Returns the font feature settings. The format is the same as the CSS
+ * font-feature-settings attribute:
+ * <a href="http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings">
+ * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings</a>
+ *
* @return the currently set font feature settings. Default is null.
*
* @see #setFontFeatureSettings(String)
- * @see Paint#setFontFeatureSettings
+ * @see Paint#setFontFeatureSettings(String) Paint.setFontFeatureSettings(String)
*/
@Nullable
public String getFontFeatureSettings() {
@@ -3182,13 +3188,15 @@
}
/**
- * Sets font feature settings. The format is the same as the CSS
+ * Sets font feature settings. The format is the same as the CSS
* font-feature-settings attribute:
- * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings
+ * <a href="http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings">
+ * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings</a>
*
* @param fontFeatureSettings font feature settings represented as CSS compatible string
+ *
* @see #getFontFeatureSettings()
- * @see Paint#getFontFeatureSettings
+ * @see Paint#getFontFeatureSettings() Paint.getFontFeatureSettings()
*
* @attr ref android.R.styleable#TextView_fontFeatureSettings
*/
diff --git a/core/java/com/android/internal/app/ProcessMap.java b/core/java/com/android/internal/app/ProcessMap.java
index 23a8bd7..81036f7 100644
--- a/core/java/com/android/internal/app/ProcessMap.java
+++ b/core/java/com/android/internal/app/ProcessMap.java
@@ -54,4 +54,8 @@
public ArrayMap<String, SparseArray<E>> getMap() {
return mMap;
}
+
+ public int size() {
+ return mMap.size();
+ }
}
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
deleted file mode 100644
index 17ca904d..0000000
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ /dev/null
@@ -1,3794 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.app;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.text.format.DateFormat;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.DebugUtils;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.TimeUtils;
-
-import com.android.internal.util.GrowingArrayUtils;
-
-import dalvik.system.VMRuntime;
-import libcore.util.EmptyArray;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Objects;
-
-public final class ProcessStats implements Parcelable {
- static final String TAG = "ProcessStats";
- static final boolean DEBUG = false;
- static final boolean DEBUG_PARCEL = false;
-
- public static final String SERVICE_NAME = "procstats";
-
- // How often the service commits its data, giving the minimum batching
- // that is done.
- public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours
-
- // Minimum uptime period before committing. If the COMMIT_PERIOD has elapsed but
- // the total uptime has not exceeded this amount, then the commit will be held until
- // it is reached.
- public static long COMMIT_UPTIME_PERIOD = 60*60*1000; // Must have at least 1 hour elapsed
-
- public static final int STATE_NOTHING = -1;
- public static final int STATE_PERSISTENT = 0;
- public static final int STATE_TOP = 1;
- public static final int STATE_IMPORTANT_FOREGROUND = 2;
- public static final int STATE_IMPORTANT_BACKGROUND = 3;
- public static final int STATE_BACKUP = 4;
- public static final int STATE_HEAVY_WEIGHT = 5;
- public static final int STATE_SERVICE = 6;
- public static final int STATE_SERVICE_RESTARTING = 7;
- public static final int STATE_RECEIVER = 8;
- public static final int STATE_HOME = 9;
- public static final int STATE_LAST_ACTIVITY = 10;
- public static final int STATE_CACHED_ACTIVITY = 11;
- public static final int STATE_CACHED_ACTIVITY_CLIENT = 12;
- public static final int STATE_CACHED_EMPTY = 13;
- public static final int STATE_COUNT = STATE_CACHED_EMPTY+1;
-
- public static final int PSS_SAMPLE_COUNT = 0;
- public static final int PSS_MINIMUM = 1;
- public static final int PSS_AVERAGE = 2;
- public static final int PSS_MAXIMUM = 3;
- public static final int PSS_USS_MINIMUM = 4;
- public static final int PSS_USS_AVERAGE = 5;
- public static final int PSS_USS_MAXIMUM = 6;
- public static final int PSS_COUNT = PSS_USS_MAXIMUM+1;
-
- public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0;
- public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1;
- public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2;
- public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3;
- public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4;
- public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5;
- public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6;
- public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7;
- public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8;
- public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9;
- public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10;
- public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11;
- public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12;
- public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13;
- public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14;
- public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15;
- public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1;
-
- public static final int ADJ_NOTHING = -1;
- public static final int ADJ_MEM_FACTOR_NORMAL = 0;
- public static final int ADJ_MEM_FACTOR_MODERATE = 1;
- public static final int ADJ_MEM_FACTOR_LOW = 2;
- public static final int ADJ_MEM_FACTOR_CRITICAL = 3;
- public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1;
- public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT;
- public static final int ADJ_SCREEN_OFF = 0;
- public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD;
- public static final int ADJ_COUNT = ADJ_SCREEN_ON*2;
-
- public static final int FLAG_COMPLETE = 1<<0;
- public static final int FLAG_SHUTDOWN = 1<<1;
- public static final int FLAG_SYSPROPS = 1<<2;
-
- public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
- ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };
-
- public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON };
-
- public static final int[] NON_CACHED_PROC_STATES = new int[] {
- STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
- STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT,
- STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
- };
-
- public static final int[] BACKGROUND_PROC_STATES = new int[] {
- STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
- STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
- };
-
- // Map from process states to the states we track.
- static final int[] PROCESS_STATE_TO_STATE = new int[] {
- STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
- STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
- STATE_TOP, // ActivityManager.PROCESS_STATE_TOP
- STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- STATE_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
- STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
- STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
- STATE_BACKUP, // ActivityManager.PROCESS_STATE_BACKUP
- STATE_HEAVY_WEIGHT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
- STATE_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
- STATE_RECEIVER, // ActivityManager.PROCESS_STATE_RECEIVER
- STATE_HOME, // ActivityManager.PROCESS_STATE_HOME
- STATE_LAST_ACTIVITY, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
- STATE_CACHED_ACTIVITY, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
- STATE_CACHED_ACTIVITY_CLIENT, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
- STATE_CACHED_EMPTY, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
- };
-
- public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
- STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
- STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
- STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
- STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
- };
-
- static final String[] STATE_NAMES = new String[] {
- "Persist", "Top ", "ImpFg ", "ImpBg ",
- "Backup ", "HeavyWt", "Service", "ServRst",
- "Receivr", "Home ",
- "LastAct", "CchAct ", "CchCAct", "CchEmty"
- };
-
- public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] {
- "off", "on"
- };
-
- public static final String[] ADJ_MEM_NAMES_CSV = new String[] {
- "norm", "mod", "low", "crit"
- };
-
- public static final String[] STATE_NAMES_CSV = new String[] {
- "pers", "top", "impfg", "impbg", "backup", "heavy",
- "service", "service-rs", "receiver", "home", "lastact",
- "cch-activity", "cch-aclient", "cch-empty"
- };
-
- static final String[] ADJ_SCREEN_TAGS = new String[] {
- "0", "1"
- };
-
- static final String[] ADJ_MEM_TAGS = new String[] {
- "n", "m", "l", "c"
- };
-
- static final String[] STATE_TAGS = new String[] {
- "p", "t", "f", "b", "u", "w",
- "s", "x", "r", "h", "l", "a", "c", "e"
- };
-
- static final String CSV_SEP = "\t";
-
- // Current version of the parcel format.
- private static final int PARCEL_VERSION = 18;
- // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
- private static final int MAGIC = 0x50535453;
-
- // Where the "type"/"state" part of the data appears in an offset integer.
- static int OFFSET_TYPE_SHIFT = 0;
- static int OFFSET_TYPE_MASK = 0xff;
- // Where the "which array" part of the data appears in an offset integer.
- static int OFFSET_ARRAY_SHIFT = 8;
- static int OFFSET_ARRAY_MASK = 0xff;
- // Where the "index into array" part of the data appears in an offset integer.
- static int OFFSET_INDEX_SHIFT = 16;
- static int OFFSET_INDEX_MASK = 0xffff;
-
- public String mReadError;
- public String mTimePeriodStartClockStr;
- public int mFlags;
-
- public final ProcessMap<SparseArray<PackageState>> mPackages
- = new ProcessMap<SparseArray<PackageState>>();
- public final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
-
- public final long[] mMemFactorDurations = new long[ADJ_COUNT];
- public int mMemFactor = STATE_NOTHING;
- public long mStartTime;
-
- public int[] mSysMemUsageTable = null;
- public int mSysMemUsageTableSize = 0;
- public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT];
-
- public long mTimePeriodStartClock;
- public long mTimePeriodStartRealtime;
- public long mTimePeriodEndRealtime;
- public long mTimePeriodStartUptime;
- public long mTimePeriodEndUptime;
- String mRuntime;
- boolean mRunning;
-
- static final int LONGS_SIZE = 4096;
- final ArrayList<long[]> mLongs = new ArrayList<long[]>();
- int mNextLong;
-
- int[] mAddLongTable;
- int mAddLongTableSize;
-
- // For writing parcels.
- ArrayMap<String, Integer> mCommonStringToIndex;
-
- // For reading parcels.
- ArrayList<String> mIndexToCommonString;
-
- public ProcessStats(boolean running) {
- mRunning = running;
- reset();
- }
-
- public ProcessStats(Parcel in) {
- reset();
- readFromParcel(in);
- }
-
- public void add(ProcessStats other) {
- ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = other.mPackages.getMap();
- for (int ip=0; ip<pkgMap.size(); ip++) {
- final String pkgName = pkgMap.keyAt(ip);
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- final int uid = uids.keyAt(iu);
- final SparseArray<PackageState> versions = uids.valueAt(iu);
- for (int iv=0; iv<versions.size(); iv++) {
- final int vers = versions.keyAt(iv);
- final PackageState otherState = versions.valueAt(iv);
- final int NPROCS = otherState.mProcesses.size();
- final int NSRVS = otherState.mServices.size();
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState otherProc = otherState.mProcesses.valueAt(iproc);
- if (otherProc.mCommonProcess != otherProc) {
- if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
- + " vers " + vers + " proc " + otherProc.mName);
- ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers,
- otherProc.mName);
- if (thisProc.mCommonProcess == thisProc) {
- if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting");
- thisProc.mMultiPackage = true;
- long now = SystemClock.uptimeMillis();
- final PackageState pkgState = getPackageStateLocked(pkgName, uid,
- vers);
- thisProc = thisProc.clone(thisProc.mPackage, now);
- pkgState.mProcesses.put(thisProc.mName, thisProc);
- }
- thisProc.add(otherProc);
- }
- }
- for (int isvc=0; isvc<NSRVS; isvc++) {
- ServiceState otherSvc = otherState.mServices.valueAt(isvc);
- if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
- + " service " + otherSvc.mName);
- ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers,
- otherSvc.mProcessName, otherSvc.mName);
- thisSvc.add(otherSvc);
- }
- }
- }
- }
-
- ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap();
- for (int ip=0; ip<procMap.size(); ip++) {
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- int uid = uids.keyAt(iu);
- ProcessState otherProc = uids.valueAt(iu);
- ProcessState thisProc = mProcesses.get(otherProc.mName, uid);
- if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + otherProc.mName);
- if (thisProc == null) {
- if (DEBUG) Slog.d(TAG, "Creating new process!");
- thisProc = new ProcessState(this, otherProc.mPackage, uid, otherProc.mVersion,
- otherProc.mName);
- mProcesses.put(otherProc.mName, uid, thisProc);
- PackageState thisState = getPackageStateLocked(otherProc.mPackage, uid,
- otherProc.mVersion);
- if (!thisState.mProcesses.containsKey(otherProc.mName)) {
- thisState.mProcesses.put(otherProc.mName, thisProc);
- }
- }
- thisProc.add(otherProc);
- }
- }
-
- for (int i=0; i<ADJ_COUNT; i++) {
- if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by "
- + other.mMemFactorDurations[i] + " from "
- + mMemFactorDurations[i]);
- mMemFactorDurations[i] += other.mMemFactorDurations[i];
- }
-
- for (int i=0; i<other.mSysMemUsageTableSize; i++) {
- int ent = other.mSysMemUsageTable[i];
- int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- long[] longs = other.mLongs.get((ent>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- addSysMemUsage(state, longs, ((ent >> OFFSET_INDEX_SHIFT) & OFFSET_INDEX_MASK));
- }
-
- if (other.mTimePeriodStartClock < mTimePeriodStartClock) {
- mTimePeriodStartClock = other.mTimePeriodStartClock;
- mTimePeriodStartClockStr = other.mTimePeriodStartClockStr;
- }
- mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
- mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;
- }
-
- public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem,
- long nativeMem) {
- if (mMemFactor != STATE_NOTHING) {
- int state = mMemFactor * STATE_COUNT;
- mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1;
- for (int i=0; i<3; i++) {
- mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem;
- mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem;
- mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem;
- mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem;
- mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem;
- }
- addSysMemUsage(state, mSysMemUsageArgs, 0);
- }
- }
-
- void addSysMemUsage(int state, long[] data, int dataOff) {
- int idx = binarySearch(mSysMemUsageTable, mSysMemUsageTableSize, state);
- int off;
- if (idx >= 0) {
- off = mSysMemUsageTable[idx];
- } else {
- mAddLongTable = mSysMemUsageTable;
- mAddLongTableSize = mSysMemUsageTableSize;
- off = addLongData(~idx, state, SYS_MEM_USAGE_COUNT);
- mSysMemUsageTable = mAddLongTable;
- mSysMemUsageTableSize = mAddLongTableSize;
- }
- long[] longs = mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK;
- addSysMemUsage(longs, idx, data, dataOff);
- }
-
- static void addSysMemUsage(long[] dstData, int dstOff, long[] addData, int addOff) {
- final long dstCount = dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT];
- final long addCount = addData[addOff+SYS_MEM_USAGE_SAMPLE_COUNT];
- if (dstCount == 0) {
- dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT] = addCount;
- for (int i=SYS_MEM_USAGE_CACHED_MINIMUM; i<SYS_MEM_USAGE_COUNT; i++) {
- dstData[dstOff+i] = addData[addOff+i];
- }
- } else if (addCount > 0) {
- dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT] = dstCount + addCount;
- for (int i=SYS_MEM_USAGE_CACHED_MINIMUM; i<SYS_MEM_USAGE_COUNT; i+=3) {
- if (dstData[dstOff+i] > addData[addOff+i]) {
- dstData[dstOff+i] = addData[addOff+i];
- }
- dstData[dstOff+i+1] = (long)(
- ((dstData[dstOff+i+1]*(double)dstCount)
- + (addData[addOff+i+1]*(double)addCount))
- / (dstCount+addCount) );
- if (dstData[dstOff+i+2] < addData[addOff+i+2]) {
- dstData[dstOff+i+2] = addData[addOff+i+2];
- }
- }
- }
- }
-
- public static final Parcelable.Creator<ProcessStats> CREATOR
- = new Parcelable.Creator<ProcessStats>() {
- public ProcessStats createFromParcel(Parcel in) {
- return new ProcessStats(in);
- }
-
- public ProcessStats[] newArray(int size) {
- return new ProcessStats[size];
- }
- };
-
- private static void printScreenLabel(PrintWriter pw, int offset) {
- switch (offset) {
- case ADJ_NOTHING:
- pw.print(" ");
- break;
- case ADJ_SCREEN_OFF:
- pw.print("SOff/");
- break;
- case ADJ_SCREEN_ON:
- pw.print("SOn /");
- break;
- default:
- pw.print("????/");
- break;
- }
- }
-
- public static void printScreenLabelCsv(PrintWriter pw, int offset) {
- switch (offset) {
- case ADJ_NOTHING:
- break;
- case ADJ_SCREEN_OFF:
- pw.print(ADJ_SCREEN_NAMES_CSV[0]);
- break;
- case ADJ_SCREEN_ON:
- pw.print(ADJ_SCREEN_NAMES_CSV[1]);
- break;
- default:
- pw.print("???");
- break;
- }
- }
-
- private static void printMemLabel(PrintWriter pw, int offset, char sep) {
- switch (offset) {
- case ADJ_NOTHING:
- pw.print(" ");
- if (sep != 0) pw.print(' ');
- break;
- case ADJ_MEM_FACTOR_NORMAL:
- pw.print("Norm");
- if (sep != 0) pw.print(sep);
- break;
- case ADJ_MEM_FACTOR_MODERATE:
- pw.print("Mod ");
- if (sep != 0) pw.print(sep);
- break;
- case ADJ_MEM_FACTOR_LOW:
- pw.print("Low ");
- if (sep != 0) pw.print(sep);
- break;
- case ADJ_MEM_FACTOR_CRITICAL:
- pw.print("Crit");
- if (sep != 0) pw.print(sep);
- break;
- default:
- pw.print("????");
- if (sep != 0) pw.print(sep);
- break;
- }
- }
-
- public static void printMemLabelCsv(PrintWriter pw, int offset) {
- if (offset >= ADJ_MEM_FACTOR_NORMAL) {
- if (offset <= ADJ_MEM_FACTOR_CRITICAL) {
- pw.print(ADJ_MEM_NAMES_CSV[offset]);
- } else {
- pw.print("???");
- }
- }
- }
-
- public static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations,
- int curState, long curStartTime, long now) {
- long totalTime = 0;
- int printedScreen = -1;
- for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
- int printedMem = -1;
- for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
- int state = imem+iscreen;
- long time = durations[state];
- String running = "";
- if (curState == state) {
- time += now - curStartTime;
- if (pw != null) {
- running = " (running)";
- }
- }
- if (time != 0) {
- if (pw != null) {
- pw.print(prefix);
- printScreenLabel(pw, printedScreen != iscreen
- ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0);
- printedMem = imem;
- pw.print(": ");
- TimeUtils.formatDuration(time, pw); pw.println(running);
- }
- totalTime += time;
- }
- }
- }
- if (totalTime != 0 && pw != null) {
- pw.print(prefix);
- pw.print(" TOTAL: ");
- TimeUtils.formatDuration(totalTime, pw);
- pw.println();
- }
- return totalTime;
- }
-
- static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations,
- int curState, long curStartTime, long now) {
- for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
- for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
- int state = imem+iscreen;
- long time = durations[state];
- if (curState == state) {
- time += now - curStartTime;
- }
- if (time != 0) {
- printAdjTagAndValue(pw, state, time);
- }
- }
- }
- }
-
- static void dumpServiceTimeCheckin(PrintWriter pw, String label, String packageName,
- int uid, int vers, String serviceName, ServiceState svc, int serviceType, int opCount,
- int curState, long curStartTime, long now) {
- if (opCount <= 0) {
- return;
- }
- pw.print(label);
- pw.print(",");
- pw.print(packageName);
- pw.print(",");
- pw.print(uid);
- pw.print(",");
- pw.print(vers);
- pw.print(",");
- pw.print(serviceName);
- pw.print(",");
- pw.print(opCount);
- boolean didCurState = false;
- for (int i=0; i<svc.mDurationsTableSize; i++) {
- int off = svc.mDurationsTable[i];
- int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- int memFactor = type / ServiceState.SERVICE_COUNT;
- type %= ServiceState.SERVICE_COUNT;
- if (type != serviceType) {
- continue;
- }
- long time = svc.mStats.getLong(off, 0);
- if (curState == memFactor) {
- didCurState = true;
- time += now - curStartTime;
- }
- printAdjTagAndValue(pw, memFactor, time);
- }
- if (!didCurState && curState != STATE_NOTHING) {
- printAdjTagAndValue(pw, curState, now - curStartTime);
- }
- pw.println();
- }
-
- public static void computeProcessData(ProcessState proc, ProcessDataCollection data, long now) {
- data.totalTime = 0;
- data.numPss = data.minPss = data.avgPss = data.maxPss =
- data.minUss = data.avgUss = data.maxUss = 0;
- for (int is=0; is<data.screenStates.length; is++) {
- for (int im=0; im<data.memStates.length; im++) {
- for (int ip=0; ip<data.procStates.length; ip++) {
- int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
- + data.procStates[ip];
- data.totalTime += proc.getDuration(bucket, now);
- long samples = proc.getPssSampleCount(bucket);
- if (samples > 0) {
- long minPss = proc.getPssMinimum(bucket);
- long avgPss = proc.getPssAverage(bucket);
- long maxPss = proc.getPssMaximum(bucket);
- long minUss = proc.getPssUssMinimum(bucket);
- long avgUss = proc.getPssUssAverage(bucket);
- long maxUss = proc.getPssUssMaximum(bucket);
- if (data.numPss == 0) {
- data.minPss = minPss;
- data.avgPss = avgPss;
- data.maxPss = maxPss;
- data.minUss = minUss;
- data.avgUss = avgUss;
- data.maxUss = maxUss;
- } else {
- if (minPss < data.minPss) {
- data.minPss = minPss;
- }
- data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
- + (avgPss*(double)samples)) / (data.numPss+samples) );
- if (maxPss > data.maxPss) {
- data.maxPss = maxPss;
- }
- if (minUss < data.minUss) {
- data.minUss = minUss;
- }
- data.avgUss = (long)( ((data.avgUss*(double)data.numPss)
- + (avgUss*(double)samples)) / (data.numPss+samples) );
- if (maxUss > data.maxUss) {
- data.maxUss = maxUss;
- }
- }
- data.numPss += samples;
- }
- }
- }
- }
- }
-
- static long computeProcessTimeLocked(ProcessState proc, int[] screenStates, int[] memStates,
- int[] procStates, long now) {
- long totalTime = 0;
- /*
- for (int i=0; i<proc.mDurationsTableSize; i++) {
- int val = proc.mDurationsTable[i];
- totalTime += proc.mState.getLong(val, 0);
- if ((val&0xff) == proc.mCurState) {
- totalTime += now - proc.mStartTime;
- }
- }
- */
- for (int is=0; is<screenStates.length; is++) {
- for (int im=0; im<memStates.length; im++) {
- for (int ip=0; ip<procStates.length; ip++) {
- int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
- + procStates[ip];
- totalTime += proc.getDuration(bucket, now);
- }
- }
- }
- proc.mTmpTotalTime = totalTime;
- return totalTime;
- }
-
- static class PssAggr {
- long pss = 0;
- long samples = 0;
-
- void add(long newPss, long newSamples) {
- pss = (long)( (pss*(double)samples) + (newPss*(double)newSamples) )
- / (samples+newSamples);
- samples += newSamples;
- }
- }
-
- public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) {
- data.totalTime = 0;
- for (int i=0; i<STATE_COUNT; i++) {
- data.processStateWeight[i] = 0;
- data.processStatePss[i] = 0;
- data.processStateTime[i] = 0;
- data.processStateSamples[i] = 0;
- }
- for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) {
- data.sysMemUsage[i] = 0;
- }
- data.sysMemCachedWeight = 0;
- data.sysMemFreeWeight = 0;
- data.sysMemZRamWeight = 0;
- data.sysMemKernelWeight = 0;
- data.sysMemNativeWeight = 0;
- data.sysMemSamples = 0;
- long[] totalMemUsage = new long[SYS_MEM_USAGE_COUNT];
- for (int i=0; i<mSysMemUsageTableSize; i++) {
- int ent = mSysMemUsageTable[i];
- long[] longs = mLongs.get((ent>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- int idx = (ent >> OFFSET_INDEX_SHIFT) & OFFSET_INDEX_MASK;
- addSysMemUsage(totalMemUsage, 0, longs, idx);
- }
- for (int is=0; is<data.screenStates.length; is++) {
- for (int im=0; im<data.memStates.length; im++) {
- int memBucket = data.screenStates[is] + data.memStates[im];
- int stateBucket = memBucket * STATE_COUNT;
- long memTime = mMemFactorDurations[memBucket];
- if (mMemFactor == memBucket) {
- memTime += now - mStartTime;
- }
- data.totalTime += memTime;
- int sysIdx = binarySearch(mSysMemUsageTable, mSysMemUsageTableSize, stateBucket);
- long[] longs = totalMemUsage;
- int idx = 0;
- if (sysIdx >= 0) {
- int ent = mSysMemUsageTable[sysIdx];
- long[] tmpLongs = mLongs.get((ent>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- int tmpIdx = (ent >> OFFSET_INDEX_SHIFT) & OFFSET_INDEX_MASK;
- if (tmpLongs[tmpIdx+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) {
- addSysMemUsage(data.sysMemUsage, 0, longs, idx);
- longs = tmpLongs;
- idx = tmpIdx;
- }
- }
- data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE]
- * (double)memTime;
- data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE]
- * (double)memTime;
- data.sysMemZRamWeight += longs[idx+SYS_MEM_USAGE_ZRAM_AVERAGE]
- * (double)memTime;
- data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE]
- * (double)memTime;
- data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE]
- * (double)memTime;
- data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT];
- }
- }
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- for (int iproc=0; iproc<procMap.size(); iproc++) {
- SparseArray<ProcessState> uids = procMap.valueAt(iproc);
- for (int iu=0; iu<uids.size(); iu++) {
- final ProcessState proc = uids.valueAt(iu);
- final PssAggr fgPss = new PssAggr();
- final PssAggr bgPss = new PssAggr();
- final PssAggr cachedPss = new PssAggr();
- boolean havePss = false;
- for (int i=0; i<proc.mDurationsTableSize; i++) {
- int off = proc.mDurationsTable[i];
- int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- int procState = type % STATE_COUNT;
- long samples = proc.getPssSampleCount(type);
- if (samples > 0) {
- long avg = proc.getPssAverage(type);
- havePss = true;
- if (procState <= STATE_IMPORTANT_FOREGROUND) {
- fgPss.add(avg, samples);
- } else if (procState <= STATE_RECEIVER) {
- bgPss.add(avg, samples);
- } else {
- cachedPss.add(avg, samples);
- }
- }
- }
- if (!havePss) {
- continue;
- }
- boolean fgHasBg = false;
- boolean fgHasCached = false;
- boolean bgHasCached = false;
- if (fgPss.samples < 3 && bgPss.samples > 0) {
- fgHasBg = true;
- fgPss.add(bgPss.pss, bgPss.samples);
- }
- if (fgPss.samples < 3 && cachedPss.samples > 0) {
- fgHasCached = true;
- fgPss.add(cachedPss.pss, cachedPss.samples);
- }
- if (bgPss.samples < 3 && cachedPss.samples > 0) {
- bgHasCached = true;
- bgPss.add(cachedPss.pss, cachedPss.samples);
- }
- if (bgPss.samples < 3 && !fgHasBg && fgPss.samples > 0) {
- bgPss.add(fgPss.pss, fgPss.samples);
- }
- if (cachedPss.samples < 3 && !bgHasCached && bgPss.samples > 0) {
- cachedPss.add(bgPss.pss, bgPss.samples);
- }
- if (cachedPss.samples < 3 && !fgHasCached && fgPss.samples > 0) {
- cachedPss.add(fgPss.pss, fgPss.samples);
- }
- for (int i=0; i<proc.mDurationsTableSize; i++) {
- final int off = proc.mDurationsTable[i];
- final int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- long time = getLong(off, 0);
- if (proc.mCurState == type) {
- time += now - proc.mStartTime;
- }
- final int procState = type % STATE_COUNT;
- data.processStateTime[procState] += time;
- long samples = proc.getPssSampleCount(type);
- long avg;
- if (samples > 0) {
- avg = proc.getPssAverage(type);
- } else if (procState <= STATE_IMPORTANT_FOREGROUND) {
- samples = fgPss.samples;
- avg = fgPss.pss;
- } else if (procState <= STATE_RECEIVER) {
- samples = bgPss.samples;
- avg = bgPss.pss;
- } else {
- samples = cachedPss.samples;
- avg = cachedPss.pss;
- }
- double newAvg = ( (data.processStatePss[procState]
- * (double)data.processStateSamples[procState])
- + (avg*(double)samples)
- ) / (data.processStateSamples[procState]+samples);
- data.processStatePss[procState] = (long)newAvg;
- data.processStateSamples[procState] += samples;
- data.processStateWeight[procState] += avg * (double)time;
- }
- }
- }
- }
-
- static void dumpProcessState(PrintWriter pw, String prefix, ProcessState proc,
- int[] screenStates, int[] memStates, int[] procStates, long now) {
- long totalTime = 0;
- int printedScreen = -1;
- for (int is=0; is<screenStates.length; is++) {
- int printedMem = -1;
- for (int im=0; im<memStates.length; im++) {
- for (int ip=0; ip<procStates.length; ip++) {
- final int iscreen = screenStates[is];
- final int imem = memStates[im];
- final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
- long time = proc.getDuration(bucket, now);
- String running = "";
- if (proc.mCurState == bucket) {
- running = " (running)";
- }
- if (time != 0) {
- pw.print(prefix);
- if (screenStates.length > 1) {
- printScreenLabel(pw, printedScreen != iscreen
- ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- }
- if (memStates.length > 1) {
- printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, '/');
- printedMem = imem;
- }
- pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
- TimeUtils.formatDuration(time, pw); pw.println(running);
- totalTime += time;
- }
- }
- }
- }
- if (totalTime != 0) {
- pw.print(prefix);
- if (screenStates.length > 1) {
- printScreenLabel(pw, STATE_NOTHING);
- }
- if (memStates.length > 1) {
- printMemLabel(pw, STATE_NOTHING, '/');
- }
- pw.print("TOTAL : ");
- TimeUtils.formatDuration(totalTime, pw);
- pw.println();
- }
- }
-
- static void dumpProcessPss(PrintWriter pw, String prefix, ProcessState proc, int[] screenStates,
- int[] memStates, int[] procStates) {
- boolean printedHeader = false;
- int printedScreen = -1;
- for (int is=0; is<screenStates.length; is++) {
- int printedMem = -1;
- for (int im=0; im<memStates.length; im++) {
- for (int ip=0; ip<procStates.length; ip++) {
- final int iscreen = screenStates[is];
- final int imem = memStates[im];
- final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
- long count = proc.getPssSampleCount(bucket);
- if (count > 0) {
- if (!printedHeader) {
- pw.print(prefix);
- pw.print("PSS/USS (");
- pw.print(proc.mPssTableSize);
- pw.println(" entries):");
- printedHeader = true;
- }
- pw.print(prefix);
- pw.print(" ");
- if (screenStates.length > 1) {
- printScreenLabel(pw, printedScreen != iscreen
- ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- }
- if (memStates.length > 1) {
- printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, '/');
- printedMem = imem;
- }
- pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
- pw.print(count);
- pw.print(" samples ");
- DebugUtils.printSizeValue(pw, proc.getPssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, proc.getPssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, proc.getPssMaximum(bucket) * 1024);
- pw.print(" / ");
- DebugUtils.printSizeValue(pw, proc.getPssUssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, proc.getPssUssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, proc.getPssUssMaximum(bucket) * 1024);
- pw.println();
- }
- }
- }
- }
- if (proc.mNumExcessiveWake != 0) {
- pw.print(prefix); pw.print("Killed for excessive wake locks: ");
- pw.print(proc.mNumExcessiveWake); pw.println(" times");
- }
- if (proc.mNumExcessiveCpu != 0) {
- pw.print(prefix); pw.print("Killed for excessive CPU use: ");
- pw.print(proc.mNumExcessiveCpu); pw.println(" times");
- }
- if (proc.mNumCachedKill != 0) {
- pw.print(prefix); pw.print("Killed from cached state: ");
- pw.print(proc.mNumCachedKill); pw.print(" times from pss ");
- DebugUtils.printSizeValue(pw, proc.mMinCachedKillPss * 1024); pw.print("-");
- DebugUtils.printSizeValue(pw, proc.mAvgCachedKillPss * 1024); pw.print("-");
- DebugUtils.printSizeValue(pw, proc.mMaxCachedKillPss * 1024); pw.println();
- }
- }
-
- long getSysMemUsageValue(int state, int index) {
- int idx = binarySearch(mSysMemUsageTable, mSysMemUsageTableSize, state);
- return idx >= 0 ? getLong(mSysMemUsageTable[idx], index) : 0;
- }
-
- void dumpSysMemUsageCategory(PrintWriter pw, String prefix, String label,
- int bucket, int index) {
- pw.print(prefix); pw.print(label);
- pw.print(": ");
- DebugUtils.printSizeValue(pw, getSysMemUsageValue(bucket, index) * 1024);
- pw.print(" min, ");
- DebugUtils.printSizeValue(pw, getSysMemUsageValue(bucket, index + 1) * 1024);
- pw.print(" avg, ");
- DebugUtils.printSizeValue(pw, getSysMemUsageValue(bucket, index+2) * 1024);
- pw.println(" max");
- }
-
- void dumpSysMemUsage(PrintWriter pw, String prefix, int[] screenStates,
- int[] memStates) {
- int printedScreen = -1;
- for (int is=0; is<screenStates.length; is++) {
- int printedMem = -1;
- for (int im=0; im<memStates.length; im++) {
- final int iscreen = screenStates[is];
- final int imem = memStates[im];
- final int bucket = ((iscreen + imem) * STATE_COUNT);
- long count = getSysMemUsageValue(bucket, SYS_MEM_USAGE_SAMPLE_COUNT);
- if (count > 0) {
- pw.print(prefix);
- if (screenStates.length > 1) {
- printScreenLabel(pw, printedScreen != iscreen
- ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- }
- if (memStates.length > 1) {
- printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, '\0');
- printedMem = imem;
- }
- pw.print(": ");
- pw.print(count);
- pw.println(" samples:");
- dumpSysMemUsageCategory(pw, prefix, " Cached", bucket,
- SYS_MEM_USAGE_CACHED_MINIMUM);
- dumpSysMemUsageCategory(pw, prefix, " Free", bucket,
- SYS_MEM_USAGE_FREE_MINIMUM);
- dumpSysMemUsageCategory(pw, prefix, " ZRam", bucket,
- SYS_MEM_USAGE_ZRAM_MINIMUM);
- dumpSysMemUsageCategory(pw, prefix, " Kernel", bucket,
- SYS_MEM_USAGE_KERNEL_MINIMUM);
- dumpSysMemUsageCategory(pw, prefix, " Native", bucket,
- SYS_MEM_USAGE_NATIVE_MINIMUM);
- }
- }
- }
- }
-
- static void dumpStateHeadersCsv(PrintWriter pw, String sep, int[] screenStates,
- int[] memStates, int[] procStates) {
- final int NS = screenStates != null ? screenStates.length : 1;
- final int NM = memStates != null ? memStates.length : 1;
- final int NP = procStates != null ? procStates.length : 1;
- for (int is=0; is<NS; is++) {
- for (int im=0; im<NM; im++) {
- for (int ip=0; ip<NP; ip++) {
- pw.print(sep);
- boolean printed = false;
- if (screenStates != null && screenStates.length > 1) {
- printScreenLabelCsv(pw, screenStates[is]);
- printed = true;
- }
- if (memStates != null && memStates.length > 1) {
- if (printed) {
- pw.print("-");
- }
- printMemLabelCsv(pw, memStates[im]);
- printed = true;
- }
- if (procStates != null && procStates.length > 1) {
- if (printed) {
- pw.print("-");
- }
- pw.print(STATE_NAMES_CSV[procStates[ip]]);
- }
- }
- }
- }
- }
-
- static void dumpProcessStateCsv(PrintWriter pw, ProcessState proc,
- boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
- boolean sepProcStates, int[] procStates, long now) {
- final int NSS = sepScreenStates ? screenStates.length : 1;
- final int NMS = sepMemStates ? memStates.length : 1;
- final int NPS = sepProcStates ? procStates.length : 1;
- for (int iss=0; iss<NSS; iss++) {
- for (int ims=0; ims<NMS; ims++) {
- for (int ips=0; ips<NPS; ips++) {
- final int vsscreen = sepScreenStates ? screenStates[iss] : 0;
- final int vsmem = sepMemStates ? memStates[ims] : 0;
- final int vsproc = sepProcStates ? procStates[ips] : 0;
- final int NSA = sepScreenStates ? 1 : screenStates.length;
- final int NMA = sepMemStates ? 1 : memStates.length;
- final int NPA = sepProcStates ? 1 : procStates.length;
- long totalTime = 0;
- for (int isa=0; isa<NSA; isa++) {
- for (int ima=0; ima<NMA; ima++) {
- for (int ipa=0; ipa<NPA; ipa++) {
- final int vascreen = sepScreenStates ? 0 : screenStates[isa];
- final int vamem = sepMemStates ? 0 : memStates[ima];
- final int vaproc = sepProcStates ? 0 : procStates[ipa];
- final int bucket = ((vsscreen + vascreen + vsmem + vamem)
- * STATE_COUNT) + vsproc + vaproc;
- totalTime += proc.getDuration(bucket, now);
- }
- }
- }
- pw.print(CSV_SEP);
- pw.print(totalTime);
- }
- }
- }
- }
-
- static void dumpProcessList(PrintWriter pw, String prefix, ArrayList<ProcessState> procs,
- int[] screenStates, int[] memStates, int[] procStates, long now) {
- String innerPrefix = prefix + " ";
- for (int i=procs.size()-1; i>=0; i--) {
- ProcessState proc = procs.get(i);
- pw.print(prefix);
- pw.print(proc.mName);
- pw.print(" / ");
- UserHandle.formatUid(pw, proc.mUid);
- pw.print(" (");
- pw.print(proc.mDurationsTableSize);
- pw.print(" entries)");
- pw.println(":");
- dumpProcessState(pw, innerPrefix, proc, screenStates, memStates, procStates, now);
- if (proc.mPssTableSize > 0) {
- dumpProcessPss(pw, innerPrefix, proc, screenStates, memStates, procStates);
- }
- }
- }
-
- static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix,
- String label, int[] screenStates, int[] memStates, int[] procStates,
- long now, long totalTime, boolean full) {
- ProcessDataCollection totals = new ProcessDataCollection(screenStates,
- memStates, procStates);
- computeProcessData(proc, totals, now);
- double percentage = (double) totals.totalTime / (double) totalTime * 100;
- // We don't print percentages < .01, so just drop those.
- if (percentage >= 0.005 || totals.numPss != 0) {
- if (prefix != null) {
- pw.print(prefix);
- }
- if (label != null) {
- pw.print(label);
- }
- totals.print(pw, totalTime, full);
- if (prefix != null) {
- pw.println();
- }
- }
- }
-
- static void dumpProcessSummaryLocked(PrintWriter pw, String prefix,
- ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates,
- boolean inclUidVers, long now, long totalTime) {
- for (int i=procs.size()-1; i>=0; i--) {
- ProcessState proc = procs.get(i);
- pw.print(prefix);
- pw.print("* ");
- pw.print(proc.mName);
- pw.print(" / ");
- UserHandle.formatUid(pw, proc.mUid);
- pw.print(" / v");
- pw.print(proc.mVersion);
- pw.println(":");
- dumpProcessSummaryDetails(pw, proc, prefix, " TOTAL: ", screenStates, memStates,
- procStates, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Persistent: ", screenStates, memStates,
- new int[] { STATE_PERSISTENT }, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Top: ", screenStates, memStates,
- new int[] {STATE_TOP}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Imp Fg: ", screenStates, memStates,
- new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Imp Bg: ", screenStates, memStates,
- new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Backup: ", screenStates, memStates,
- new int[] {STATE_BACKUP}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Heavy Wgt: ", screenStates, memStates,
- new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Service: ", screenStates, memStates,
- new int[] {STATE_SERVICE}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Service Rs: ", screenStates, memStates,
- new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " Receiver: ", screenStates, memStates,
- new int[] {STATE_RECEIVER}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " (Home): ", screenStates, memStates,
- new int[] {STATE_HOME}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " (Last Act): ", screenStates, memStates,
- new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, proc, prefix, " (Cached): ", screenStates, memStates,
- new int[] {STATE_CACHED_ACTIVITY, STATE_CACHED_ACTIVITY_CLIENT,
- STATE_CACHED_EMPTY}, now, totalTime, true);
- }
- }
-
- static void printPercent(PrintWriter pw, double fraction) {
- fraction *= 100;
- if (fraction < 1) {
- pw.print(String.format("%.2f", fraction));
- } else if (fraction < 10) {
- pw.print(String.format("%.1f", fraction));
- } else {
- pw.print(String.format("%.0f", fraction));
- }
- pw.print("%");
- }
-
- public static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
- boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
- boolean sepProcStates, int[] procStates, long now) {
- pw.print("process");
- pw.print(CSV_SEP);
- pw.print("uid");
- pw.print(CSV_SEP);
- pw.print("vers");
- dumpStateHeadersCsv(pw, CSV_SEP, sepScreenStates ? screenStates : null,
- sepMemStates ? memStates : null,
- sepProcStates ? procStates : null);
- pw.println();
- for (int i=procs.size()-1; i>=0; i--) {
- ProcessState proc = procs.get(i);
- pw.print(proc.mName);
- pw.print(CSV_SEP);
- UserHandle.formatUid(pw, proc.mUid);
- pw.print(CSV_SEP);
- pw.print(proc.mVersion);
- dumpProcessStateCsv(pw, proc, sepScreenStates, screenStates,
- sepMemStates, memStates, sepProcStates, procStates, now);
- pw.println();
- }
- }
-
- static int printArrayEntry(PrintWriter pw, String[] array, int value, int mod) {
- int index = value/mod;
- if (index >= 0 && index < array.length) {
- pw.print(array[index]);
- } else {
- pw.print('?');
- }
- return value - index*mod;
- }
-
- static void printProcStateTag(PrintWriter pw, int state) {
- state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD*STATE_COUNT);
- state = printArrayEntry(pw, ADJ_MEM_TAGS, state, STATE_COUNT);
- printArrayEntry(pw, STATE_TAGS, state, 1);
- }
-
- static void printAdjTag(PrintWriter pw, int state) {
- state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD);
- printArrayEntry(pw, ADJ_MEM_TAGS, state, 1);
- }
-
- static void printProcStateTagAndValue(PrintWriter pw, int state, long value) {
- pw.print(',');
- printProcStateTag(pw, state);
- pw.print(':');
- pw.print(value);
- }
-
- static void printAdjTagAndValue(PrintWriter pw, int state, long value) {
- pw.print(',');
- printAdjTag(pw, state);
- pw.print(':');
- pw.print(value);
- }
-
- static void dumpAllProcessStateCheckin(PrintWriter pw, ProcessState proc, long now) {
- boolean didCurState = false;
- for (int i=0; i<proc.mDurationsTableSize; i++) {
- int off = proc.mDurationsTable[i];
- int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- long time = proc.mStats.getLong(off, 0);
- if (proc.mCurState == type) {
- didCurState = true;
- time += now - proc.mStartTime;
- }
- printProcStateTagAndValue(pw, type, time);
- }
- if (!didCurState && proc.mCurState != STATE_NOTHING) {
- printProcStateTagAndValue(pw, proc.mCurState, now - proc.mStartTime);
- }
- }
-
- static void dumpAllProcessPssCheckin(PrintWriter pw, ProcessState proc) {
- for (int i=0; i<proc.mPssTableSize; i++) {
- int off = proc.mPssTable[i];
- int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- long count = proc.mStats.getLong(off, PSS_SAMPLE_COUNT);
- long min = proc.mStats.getLong(off, PSS_MINIMUM);
- long avg = proc.mStats.getLong(off, PSS_AVERAGE);
- long max = proc.mStats.getLong(off, PSS_MAXIMUM);
- long umin = proc.mStats.getLong(off, PSS_USS_MINIMUM);
- long uavg = proc.mStats.getLong(off, PSS_USS_AVERAGE);
- long umax = proc.mStats.getLong(off, PSS_USS_MAXIMUM);
- pw.print(',');
- printProcStateTag(pw, type);
- pw.print(':');
- pw.print(count);
- pw.print(':');
- pw.print(min);
- pw.print(':');
- pw.print(avg);
- pw.print(':');
- pw.print(max);
- pw.print(':');
- pw.print(umin);
- pw.print(':');
- pw.print(uavg);
- pw.print(':');
- pw.print(umax);
- }
- }
-
- public void reset() {
- if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr);
- resetCommon();
- mPackages.getMap().clear();
- mProcesses.getMap().clear();
- mMemFactor = STATE_NOTHING;
- mStartTime = 0;
- if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
- }
-
- public void resetSafely() {
- if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr);
- resetCommon();
-
- // First initialize use count of all common processes.
- final long now = SystemClock.uptimeMillis();
- final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- for (int ip=procMap.size()-1; ip>=0; ip--) {
- final SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=uids.size()-1; iu>=0; iu--) {
- uids.valueAt(iu).mTmpNumInUse = 0;
- }
- }
-
- // Next reset or prune all per-package processes, and for the ones that are reset
- // track this back to the common processes.
- final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
- for (int ip=pkgMap.size()-1; ip>=0; ip--) {
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- for (int iu=uids.size()-1; iu>=0; iu--) {
- final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
- for (int iv=vpkgs.size()-1; iv>=0; iv--) {
- final PackageState pkgState = vpkgs.valueAt(iv);
- for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
- final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
- if (ps.isInUse()) {
- ps.resetSafely(now);
- ps.mCommonProcess.mTmpNumInUse++;
- ps.mCommonProcess.mTmpFoundSubProc = ps;
- } else {
- pkgState.mProcesses.valueAt(iproc).makeDead();
- pkgState.mProcesses.removeAt(iproc);
- }
- }
- for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
- final ServiceState ss = pkgState.mServices.valueAt(isvc);
- if (ss.isInUse()) {
- ss.resetSafely(now);
- } else {
- pkgState.mServices.removeAt(isvc);
- }
- }
- if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) {
- vpkgs.removeAt(iv);
- }
- }
- if (vpkgs.size() <= 0) {
- uids.removeAt(iu);
- }
- }
- if (uids.size() <= 0) {
- pkgMap.removeAt(ip);
- }
- }
-
- // Finally prune out any common processes that are no longer in use.
- for (int ip=procMap.size()-1; ip>=0; ip--) {
- final SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=uids.size()-1; iu>=0; iu--) {
- ProcessState ps = uids.valueAt(iu);
- if (ps.isInUse() || ps.mTmpNumInUse > 0) {
- // If this is a process for multiple packages, we could at this point
- // be back down to one package. In that case, we want to revert back
- // to a single shared ProcessState. We can do this by converting the
- // current package-specific ProcessState up to the shared ProcessState,
- // throwing away the current one we have here (because nobody else is
- // using it).
- if (!ps.mActive && ps.mMultiPackage && ps.mTmpNumInUse == 1) {
- // Here we go...
- ps = ps.mTmpFoundSubProc;
- ps.mCommonProcess = ps;
- uids.setValueAt(iu, ps);
- } else {
- ps.resetSafely(now);
- }
- } else {
- ps.makeDead();
- uids.removeAt(iu);
- }
- }
- if (uids.size() <= 0) {
- procMap.removeAt(ip);
- }
- }
-
- mStartTime = now;
- if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
- }
-
- private void resetCommon() {
- mTimePeriodStartClock = System.currentTimeMillis();
- buildTimePeriodStartClockStr();
- mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
- mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
- mLongs.clear();
- mLongs.add(new long[LONGS_SIZE]);
- mNextLong = 0;
- Arrays.fill(mMemFactorDurations, 0);
- mSysMemUsageTable = null;
- mSysMemUsageTableSize = 0;
- mStartTime = 0;
- mReadError = null;
- mFlags = 0;
- evaluateSystemProperties(true);
- }
-
- public boolean evaluateSystemProperties(boolean update) {
- boolean changed = false;
- String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2",
- VMRuntime.getRuntime().vmLibrary());
- if (!Objects.equals(runtime, mRuntime)) {
- changed = true;
- if (update) {
- mRuntime = runtime;
- }
- }
- return changed;
- }
-
- private void buildTimePeriodStartClockStr() {
- mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss",
- mTimePeriodStartClock).toString();
- }
-
- static final int[] BAD_TABLE = new int[0];
-
- private int[] readTableFromParcel(Parcel in, String name, String what) {
- final int size = in.readInt();
- if (size < 0) {
- Slog.w(TAG, "Ignoring existing stats; bad " + what + " table size: " + size);
- return BAD_TABLE;
- }
- if (size == 0) {
- return null;
- }
- final int[] table = new int[size];
- for (int i=0; i<size; i++) {
- table[i] = in.readInt();
- if (DEBUG_PARCEL) Slog.i(TAG, "Reading in " + name + " table #" + i + ": "
- + ProcessStats.printLongOffset(table[i]));
- if (!validateLongOffset(table[i])) {
- Slog.w(TAG, "Ignoring existing stats; bad " + what + " table entry: "
- + ProcessStats.printLongOffset(table[i]));
- return null;
- }
- }
- return table;
- }
-
- private void writeCompactedLongArray(Parcel out, long[] array, int num) {
- for (int i=0; i<num; i++) {
- long val = array[i];
- if (val < 0) {
- Slog.w(TAG, "Time val negative: " + val);
- val = 0;
- }
- if (val <= Integer.MAX_VALUE) {
- out.writeInt((int)val);
- } else {
- int top = ~((int)((val>>32)&0x7fffffff));
- int bottom = (int)(val&0xfffffff);
- out.writeInt(top);
- out.writeInt(bottom);
- }
- }
- }
-
- private void readCompactedLongArray(Parcel in, int version, long[] array, int num) {
- if (version <= 10) {
- in.readLongArray(array);
- return;
- }
- final int alen = array.length;
- if (num > alen) {
- throw new RuntimeException("bad array lengths: got " + num + " array is " + alen);
- }
- int i;
- for (i=0; i<num; i++) {
- int val = in.readInt();
- if (val >= 0) {
- array[i] = val;
- } else {
- int bottom = in.readInt();
- array[i] = (((long)~val)<<32) | bottom;
- }
- }
- while (i < alen) {
- array[i] = 0;
- i++;
- }
- }
-
- private void writeCommonString(Parcel out, String name) {
- Integer index = mCommonStringToIndex.get(name);
- if (index != null) {
- out.writeInt(index);
- return;
- }
- index = mCommonStringToIndex.size();
- mCommonStringToIndex.put(name, index);
- out.writeInt(~index);
- out.writeString(name);
- }
-
- private String readCommonString(Parcel in, int version) {
- if (version <= 9) {
- return in.readString();
- }
- int index = in.readInt();
- if (index >= 0) {
- return mIndexToCommonString.get(index);
- }
- index = ~index;
- String name = in.readString();
- while (mIndexToCommonString.size() <= index) {
- mIndexToCommonString.add(null);
- }
- mIndexToCommonString.set(index, name);
- return name;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- writeToParcel(out, SystemClock.uptimeMillis(), flags);
- }
-
- /** @hide */
- public void writeToParcel(Parcel out, long now, int flags) {
- out.writeInt(MAGIC);
- out.writeInt(PARCEL_VERSION);
- out.writeInt(STATE_COUNT);
- out.writeInt(ADJ_COUNT);
- out.writeInt(PSS_COUNT);
- out.writeInt(SYS_MEM_USAGE_COUNT);
- out.writeInt(LONGS_SIZE);
-
- mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.mMap.size());
-
- // First commit all running times.
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- final int NPROC = procMap.size();
- for (int ip=0; ip<NPROC; ip++) {
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
- final int NUID = uids.size();
- for (int iu=0; iu<NUID; iu++) {
- uids.valueAt(iu).commitStateTime(now);
- }
- }
- final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
- final int NPKG = pkgMap.size();
- for (int ip=0; ip<NPKG; ip++) {
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- final int NUID = uids.size();
- for (int iu=0; iu<NUID; iu++) {
- final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
- final int NVERS = vpkgs.size();
- for (int iv=0; iv<NVERS; iv++) {
- PackageState pkgState = vpkgs.valueAt(iv);
- final int NPROCS = pkgState.mProcesses.size();
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- if (proc.mCommonProcess != proc) {
- proc.commitStateTime(now);
- }
- }
- final int NSRVS = pkgState.mServices.size();
- for (int isvc=0; isvc<NSRVS; isvc++) {
- pkgState.mServices.valueAt(isvc).commitStateTime(now);
- }
- }
- }
- }
-
- out.writeLong(mTimePeriodStartClock);
- out.writeLong(mTimePeriodStartRealtime);
- out.writeLong(mTimePeriodEndRealtime);
- out.writeLong(mTimePeriodStartUptime);
- out.writeLong(mTimePeriodEndUptime);
- out.writeString(mRuntime);
- out.writeInt(mFlags);
-
- out.writeInt(mLongs.size());
- out.writeInt(mNextLong);
- for (int i=0; i<(mLongs.size()-1); i++) {
- long[] array = mLongs.get(i);
- writeCompactedLongArray(out, array, array.length);
- }
- long[] lastLongs = mLongs.get(mLongs.size() - 1);
- writeCompactedLongArray(out, lastLongs, mNextLong);
-
- if (mMemFactor != STATE_NOTHING) {
- mMemFactorDurations[mMemFactor] += now - mStartTime;
- mStartTime = now;
- }
- writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length);
-
- out.writeInt(mSysMemUsageTableSize);
- for (int i=0; i<mSysMemUsageTableSize; i++) {
- if (DEBUG_PARCEL) Slog.i(TAG, "Writing sys mem usage #" + i + ": "
- + printLongOffset(mSysMemUsageTable[i]));
- out.writeInt(mSysMemUsageTable[i]);
- }
-
- out.writeInt(NPROC);
- for (int ip=0; ip<NPROC; ip++) {
- writeCommonString(out, procMap.keyAt(ip));
- final SparseArray<ProcessState> uids = procMap.valueAt(ip);
- final int NUID = uids.size();
- out.writeInt(NUID);
- for (int iu=0; iu<NUID; iu++) {
- out.writeInt(uids.keyAt(iu));
- final ProcessState proc = uids.valueAt(iu);
- writeCommonString(out, proc.mPackage);
- out.writeInt(proc.mVersion);
- proc.writeToParcel(out, now);
- }
- }
- out.writeInt(NPKG);
- for (int ip=0; ip<NPKG; ip++) {
- writeCommonString(out, pkgMap.keyAt(ip));
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- final int NUID = uids.size();
- out.writeInt(NUID);
- for (int iu=0; iu<NUID; iu++) {
- out.writeInt(uids.keyAt(iu));
- final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
- final int NVERS = vpkgs.size();
- out.writeInt(NVERS);
- for (int iv=0; iv<NVERS; iv++) {
- out.writeInt(vpkgs.keyAt(iv));
- final PackageState pkgState = vpkgs.valueAt(iv);
- final int NPROCS = pkgState.mProcesses.size();
- out.writeInt(NPROCS);
- for (int iproc=0; iproc<NPROCS; iproc++) {
- writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
- final ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- if (proc.mCommonProcess == proc) {
- // This is the same as the common process we wrote above.
- out.writeInt(0);
- } else {
- // There is separate data for this package's process.
- out.writeInt(1);
- proc.writeToParcel(out, now);
- }
- }
- final int NSRVS = pkgState.mServices.size();
- out.writeInt(NSRVS);
- for (int isvc=0; isvc<NSRVS; isvc++) {
- out.writeString(pkgState.mServices.keyAt(isvc));
- final ServiceState svc = pkgState.mServices.valueAt(isvc);
- writeCommonString(out, svc.mProcessName);
- svc.writeToParcel(out, now);
- }
- }
- }
- }
-
- mCommonStringToIndex = null;
- }
-
- private boolean readCheckedInt(Parcel in, int val, String what) {
- int got;
- if ((got=in.readInt()) != val) {
- mReadError = "bad " + what + ": " + got;
- return false;
- }
- return true;
- }
-
- static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
- int pos = 0;
- final int initialAvail = stream.available();
- byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384];
- while (true) {
- int amt = stream.read(data, pos, data.length-pos);
- if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos
- + " of avail " + data.length);
- if (amt < 0) {
- if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos
- + " len=" + data.length);
- outLen[0] = pos;
- return data;
- }
- pos += amt;
- if (pos >= data.length) {
- byte[] newData = new byte[pos+16384];
- if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len "
- + newData.length);
- System.arraycopy(data, 0, newData, 0, pos);
- data = newData;
- }
- }
- }
-
- public void read(InputStream stream) {
- try {
- int[] len = new int[1];
- byte[] raw = readFully(stream, len);
- Parcel in = Parcel.obtain();
- in.unmarshall(raw, 0, len[0]);
- in.setDataPosition(0);
- stream.close();
-
- readFromParcel(in);
- } catch (IOException e) {
- mReadError = "caught exception: " + e;
- }
- }
-
- public void readFromParcel(Parcel in) {
- final boolean hadData = mPackages.getMap().size() > 0
- || mProcesses.getMap().size() > 0;
- if (hadData) {
- resetSafely();
- }
-
- if (!readCheckedInt(in, MAGIC, "magic number")) {
- return;
- }
- int version = in.readInt();
- if (version != PARCEL_VERSION) {
- mReadError = "bad version: " + version;
- return;
- }
- if (!readCheckedInt(in, STATE_COUNT, "state count")) {
- return;
- }
- if (!readCheckedInt(in, ADJ_COUNT, "adj count")) {
- return;
- }
- if (!readCheckedInt(in, PSS_COUNT, "pss count")) {
- return;
- }
- if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) {
- return;
- }
- if (!readCheckedInt(in, LONGS_SIZE, "longs size")) {
- return;
- }
-
- mIndexToCommonString = new ArrayList<String>();
-
- mTimePeriodStartClock = in.readLong();
- buildTimePeriodStartClockStr();
- mTimePeriodStartRealtime = in.readLong();
- mTimePeriodEndRealtime = in.readLong();
- mTimePeriodStartUptime = in.readLong();
- mTimePeriodEndUptime = in.readLong();
- mRuntime = in.readString();
- mFlags = in.readInt();
-
- final int NLONGS = in.readInt();
- final int NEXTLONG = in.readInt();
- mLongs.clear();
- for (int i=0; i<(NLONGS-1); i++) {
- while (i >= mLongs.size()) {
- mLongs.add(new long[LONGS_SIZE]);
- }
- readCompactedLongArray(in, version, mLongs.get(i), LONGS_SIZE);
- }
- long[] longs = new long[LONGS_SIZE];
- mNextLong = NEXTLONG;
- readCompactedLongArray(in, version, longs, NEXTLONG);
- mLongs.add(longs);
-
- readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length);
-
- mSysMemUsageTable = readTableFromParcel(in, TAG, "sys mem usage");
- if (mSysMemUsageTable == BAD_TABLE) {
- return;
- }
- mSysMemUsageTableSize = mSysMemUsageTable != null ? mSysMemUsageTable.length : 0;
-
- int NPROC = in.readInt();
- if (NPROC < 0) {
- mReadError = "bad process count: " + NPROC;
- return;
- }
- while (NPROC > 0) {
- NPROC--;
- final String procName = readCommonString(in, version);
- if (procName == null) {
- mReadError = "bad process name";
- return;
- }
- int NUID = in.readInt();
- if (NUID < 0) {
- mReadError = "bad uid count: " + NUID;
- return;
- }
- while (NUID > 0) {
- NUID--;
- final int uid = in.readInt();
- if (uid < 0) {
- mReadError = "bad uid: " + uid;
- return;
- }
- final String pkgName = readCommonString(in, version);
- if (pkgName == null) {
- mReadError = "bad process package name";
- return;
- }
- final int vers = in.readInt();
- ProcessState proc = hadData ? mProcesses.get(procName, uid) : null;
- if (proc != null) {
- if (!proc.readFromParcel(in, false)) {
- return;
- }
- } else {
- proc = new ProcessState(this, pkgName, uid, vers, procName);
- if (!proc.readFromParcel(in, true)) {
- return;
- }
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid
- + " " + proc);
- mProcesses.put(procName, uid, proc);
- }
- }
-
- if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes");
-
- int NPKG = in.readInt();
- if (NPKG < 0) {
- mReadError = "bad package count: " + NPKG;
- return;
- }
- while (NPKG > 0) {
- NPKG--;
- final String pkgName = readCommonString(in, version);
- if (pkgName == null) {
- mReadError = "bad package name";
- return;
- }
- int NUID = in.readInt();
- if (NUID < 0) {
- mReadError = "bad uid count: " + NUID;
- return;
- }
- while (NUID > 0) {
- NUID--;
- final int uid = in.readInt();
- if (uid < 0) {
- mReadError = "bad uid: " + uid;
- return;
- }
- int NVERS = in.readInt();
- if (NVERS < 0) {
- mReadError = "bad versions count: " + NVERS;
- return;
- }
- while (NVERS > 0) {
- NVERS--;
- final int vers = in.readInt();
- PackageState pkgState = new PackageState(pkgName, uid);
- SparseArray<PackageState> vpkg = mPackages.get(pkgName, uid);
- if (vpkg == null) {
- vpkg = new SparseArray<PackageState>();
- mPackages.put(pkgName, uid, vpkg);
- }
- vpkg.put(vers, pkgState);
- int NPROCS = in.readInt();
- if (NPROCS < 0) {
- mReadError = "bad package process count: " + NPROCS;
- return;
- }
- while (NPROCS > 0) {
- NPROCS--;
- String procName = readCommonString(in, version);
- if (procName == null) {
- mReadError = "bad package process name";
- return;
- }
- int hasProc = in.readInt();
- if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
- + " process " + procName + " hasProc=" + hasProc);
- ProcessState commonProc = mProcesses.get(procName, uid);
- if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid
- + ": " + commonProc);
- if (commonProc == null) {
- mReadError = "no common proc: " + procName;
- return;
- }
- if (hasProc != 0) {
- // The process for this package is unique to the package; we
- // need to load it. We don't need to do anything about it if
- // it is not unique because if someone later looks for it
- // they will find and use it from the global procs.
- ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null;
- if (proc != null) {
- if (!proc.readFromParcel(in, false)) {
- return;
- }
- } else {
- proc = new ProcessState(commonProc, pkgName, uid, vers, procName,
- 0);
- if (!proc.readFromParcel(in, true)) {
- return;
- }
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
- + procName + " " + uid + " " + proc);
- pkgState.mProcesses.put(procName, proc);
- } else {
- if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
- + procName + " " + uid + " " + commonProc);
- pkgState.mProcesses.put(procName, commonProc);
- }
- }
- int NSRVS = in.readInt();
- if (NSRVS < 0) {
- mReadError = "bad package service count: " + NSRVS;
- return;
- }
- while (NSRVS > 0) {
- NSRVS--;
- String serviceName = in.readString();
- if (serviceName == null) {
- mReadError = "bad package service name";
- return;
- }
- String processName = version > 9 ? readCommonString(in, version) : null;
- ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null;
- if (serv == null) {
- serv = new ServiceState(this, pkgName, serviceName, processName, null);
- }
- if (!serv.readFromParcel(in)) {
- return;
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
- + serviceName + " " + uid + " " + serv);
- pkgState.mServices.put(serviceName, serv);
- }
- }
- }
- }
-
- mIndexToCommonString = null;
-
- if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!");
- }
-
- int addLongData(int index, int type, int num) {
- int off = allocLongData(num);
- mAddLongTable = GrowingArrayUtils.insert(
- mAddLongTable != null ? mAddLongTable : EmptyArray.INT,
- mAddLongTableSize, index, type | off);
- mAddLongTableSize++;
- return off;
- }
-
- int allocLongData(int num) {
- int whichLongs = mLongs.size()-1;
- long[] longs = mLongs.get(whichLongs);
- if (mNextLong + num > longs.length) {
- longs = new long[LONGS_SIZE];
- mLongs.add(longs);
- whichLongs++;
- mNextLong = 0;
- }
- int off = (whichLongs<<OFFSET_ARRAY_SHIFT) | (mNextLong<<OFFSET_INDEX_SHIFT);
- mNextLong += num;
- return off;
- }
-
- boolean validateLongOffset(int off) {
- int arr = (off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK;
- if (arr >= mLongs.size()) {
- return false;
- }
- int idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK;
- if (idx >= LONGS_SIZE) {
- return false;
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Validated long " + printLongOffset(off)
- + ": " + getLong(off, 0));
- return true;
- }
-
- static String printLongOffset(int off) {
- StringBuilder sb = new StringBuilder(16);
- sb.append("a"); sb.append((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- sb.append("i"); sb.append((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK);
- sb.append("t"); sb.append((off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK);
- return sb.toString();
- }
-
- void setLong(int off, int index, long value) {
- long[] longs = mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- longs[index + ((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK)] = value;
- }
-
- long getLong(int off, int index) {
- long[] longs = mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- return longs[index + ((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK)];
- }
-
- static int binarySearch(int[] array, int size, int value) {
- int lo = 0;
- int hi = size - 1;
-
- while (lo <= hi) {
- int mid = (lo + hi) >>> 1;
- int midVal = (array[mid] >> OFFSET_TYPE_SHIFT) & OFFSET_TYPE_MASK;
-
- if (midVal < value) {
- lo = mid + 1;
- } else if (midVal > value) {
- hi = mid - 1;
- } else {
- return mid; // value found
- }
- }
- return ~lo; // value not present
- }
-
- public PackageState getPackageStateLocked(String packageName, int uid, int vers) {
- SparseArray<PackageState> vpkg = mPackages.get(packageName, uid);
- if (vpkg == null) {
- vpkg = new SparseArray<PackageState>();
- mPackages.put(packageName, uid, vpkg);
- }
- PackageState as = vpkg.get(vers);
- if (as != null) {
- return as;
- }
- as = new PackageState(packageName, uid);
- vpkg.put(vers, as);
- return as;
- }
-
- public ProcessState getProcessStateLocked(String packageName, int uid, int vers,
- String processName) {
- final PackageState pkgState = getPackageStateLocked(packageName, uid, vers);
- ProcessState ps = pkgState.mProcesses.get(processName);
- if (ps != null) {
- return ps;
- }
- ProcessState commonProc = mProcesses.get(processName, uid);
- if (commonProc == null) {
- commonProc = new ProcessState(this, packageName, uid, vers, processName);
- mProcesses.put(processName, uid, commonProc);
- if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);
- }
- if (!commonProc.mMultiPackage) {
- if (packageName.equals(commonProc.mPackage) && vers == commonProc.mVersion) {
- // This common process is not in use by multiple packages, and
- // is for the calling package, so we can just use it directly.
- ps = commonProc;
- if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc);
- } else {
- if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!");
- // This common process has not been in use by multiple packages,
- // but it was created for a different package than the caller.
- // We need to convert it to a multi-package process.
- commonProc.mMultiPackage = true;
- // To do this, we need to make two new process states, one a copy
- // of the current state for the process under the original package
- // name, and the second a free new process state for it as the
- // new package name.
- long now = SystemClock.uptimeMillis();
- // First let's make a copy of the current process state and put
- // that under the now unique state for its original package name.
- final PackageState commonPkgState = getPackageStateLocked(commonProc.mPackage,
- uid, commonProc.mVersion);
- if (commonPkgState != null) {
- ProcessState cloned = commonProc.clone(commonProc.mPackage, now);
- if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.mPackage
- + ": " + cloned);
- commonPkgState.mProcesses.put(commonProc.mName, cloned);
- // If this has active services, we need to update their process pointer
- // to point to the new package-specific process state.
- for (int i=commonPkgState.mServices.size()-1; i>=0; i--) {
- ServiceState ss = commonPkgState.mServices.valueAt(i);
- if (ss.mProc == commonProc) {
- if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: "
- + ss);
- ss.mProc = cloned;
- } else if (DEBUG) {
- Slog.d(TAG, "GETPROC leaving proc of " + ss);
- }
- }
- } else {
- Slog.w(TAG, "Cloning proc state: no package state " + commonProc.mPackage
- + "/" + uid + " for proc " + commonProc.mName);
- }
- // And now make a fresh new process state for the new package name.
- ps = new ProcessState(commonProc, packageName, uid, vers, processName, now);
- if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
- }
- } else {
- // The common process is for multiple packages, we need to create a
- // separate object for the per-package data.
- ps = new ProcessState(commonProc, packageName, uid, vers, processName,
- SystemClock.uptimeMillis());
- if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
- }
- pkgState.mProcesses.put(processName, ps);
- if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);
- return ps;
- }
-
- public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid, int vers,
- String processName, String className) {
- final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers);
- ProcessStats.ServiceState ss = as.mServices.get(className);
- if (ss != null) {
- if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss);
- return ss;
- }
- final ProcessStats.ProcessState ps = processName != null
- ? getProcessStateLocked(packageName, uid, vers, processName) : null;
- ss = new ProcessStats.ServiceState(this, packageName, className, processName, ps);
- as.mServices.put(className, ss);
- if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps);
- return ss;
- }
-
- private void dumpProcessInternalLocked(PrintWriter pw, String prefix, ProcessState proc,
- boolean dumpAll) {
- if (dumpAll) {
- pw.print(prefix); pw.print("myID=");
- pw.print(Integer.toHexString(System.identityHashCode(proc)));
- pw.print(" mCommonProcess=");
- pw.print(Integer.toHexString(System.identityHashCode(proc.mCommonProcess)));
- pw.print(" mPackage="); pw.println(proc.mPackage);
- if (proc.mMultiPackage) {
- pw.print(prefix); pw.print("mMultiPackage="); pw.println(proc.mMultiPackage);
- }
- if (proc != proc.mCommonProcess) {
- pw.print(prefix); pw.print("Common Proc: "); pw.print(proc.mCommonProcess.mName);
- pw.print("/"); pw.print(proc.mCommonProcess.mUid);
- pw.print(" pkg="); pw.println(proc.mCommonProcess.mPackage);
- }
- }
- if (proc.mActive) {
- pw.print(prefix); pw.print("mActive="); pw.println(proc.mActive);
- }
- if (proc.mDead) {
- pw.print(prefix); pw.print("mDead="); pw.println(proc.mDead);
- }
- if (proc.mNumActiveServices != 0 || proc.mNumStartedServices != 0) {
- pw.print(prefix); pw.print("mNumActiveServices="); pw.print(proc.mNumActiveServices);
- pw.print(" mNumStartedServices=");
- pw.println(proc.mNumStartedServices);
- }
- }
-
- public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
- boolean dumpAll, boolean activeOnly) {
- long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
- mStartTime, now);
- boolean sepNeeded = false;
- if (mSysMemUsageTable != null) {
- pw.println("System memory usage:");
- dumpSysMemUsage(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
- sepNeeded = true;
- }
- ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
- boolean printedHeader = false;
- for (int ip=0; ip<pkgMap.size(); ip++) {
- final String pkgName = pkgMap.keyAt(ip);
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- final int uid = uids.keyAt(iu);
- final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
- for (int iv=0; iv<vpkgs.size(); iv++) {
- final int vers = vpkgs.keyAt(iv);
- final PackageState pkgState = vpkgs.valueAt(iv);
- final int NPROCS = pkgState.mProcesses.size();
- final int NSRVS = pkgState.mServices.size();
- final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
- if (!pkgMatch) {
- boolean procMatch = false;
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- if (reqPackage.equals(proc.mName)) {
- procMatch = true;
- break;
- }
- }
- if (!procMatch) {
- continue;
- }
- }
- if (NPROCS > 0 || NSRVS > 0) {
- if (!printedHeader) {
- if (sepNeeded) pw.println();
- pw.println("Per-Package Stats:");
- printedHeader = true;
- sepNeeded = true;
- }
- pw.print(" * "); pw.print(pkgName); pw.print(" / ");
- UserHandle.formatUid(pw, uid); pw.print(" / v");
- pw.print(vers); pw.println(":");
- }
- if (!dumpSummary || dumpAll) {
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- if (!pkgMatch && !reqPackage.equals(proc.mName)) {
- continue;
- }
- if (activeOnly && !proc.isInUse()) {
- pw.print(" (Not active: ");
- pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
- continue;
- }
- pw.print(" Process ");
- pw.print(pkgState.mProcesses.keyAt(iproc));
- if (proc.mCommonProcess.mMultiPackage) {
- pw.print(" (multi, ");
- } else {
- pw.print(" (unique, ");
- }
- pw.print(proc.mDurationsTableSize);
- pw.print(" entries)");
- pw.println(":");
- dumpProcessState(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES, now);
- dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES);
- dumpProcessInternalLocked(pw, " ", proc, dumpAll);
- }
- } else {
- ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- if (!pkgMatch && !reqPackage.equals(proc.mName)) {
- continue;
- }
- if (activeOnly && !proc.isInUse()) {
- continue;
- }
- procs.add(proc);
- }
- dumpProcessSummaryLocked(pw, " ", procs, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- NON_CACHED_PROC_STATES, false, now, totalTime);
- }
- for (int isvc=0; isvc<NSRVS; isvc++) {
- ServiceState svc = pkgState.mServices.valueAt(isvc);
- if (!pkgMatch && !reqPackage.equals(svc.mProcessName)) {
- continue;
- }
- if (activeOnly && !svc.isInUse()) {
- pw.print(" (Not active: ");
- pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
- continue;
- }
- if (dumpAll) {
- pw.print(" Service ");
- } else {
- pw.print(" * ");
- }
- pw.print(pkgState.mServices.keyAt(isvc));
- pw.println(":");
- pw.print(" Process: "); pw.println(svc.mProcessName);
- dumpServiceStats(pw, " ", " ", " ", "Running", svc,
- svc.mRunCount, ServiceState.SERVICE_RUN, svc.mRunState,
- svc.mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
- dumpServiceStats(pw, " ", " ", " ", "Started", svc,
- svc.mStartedCount, ServiceState.SERVICE_STARTED, svc.mStartedState,
- svc.mStartedStartTime, now, totalTime, !dumpSummary || dumpAll);
- dumpServiceStats(pw, " ", " ", " ", "Bound", svc,
- svc.mBoundCount, ServiceState.SERVICE_BOUND, svc.mBoundState,
- svc.mBoundStartTime, now, totalTime, !dumpSummary || dumpAll);
- dumpServiceStats(pw, " ", " ", " ", "Executing", svc,
- svc.mExecCount, ServiceState.SERVICE_EXEC, svc.mExecState,
- svc.mExecStartTime, now, totalTime, !dumpSummary || dumpAll);
- if (dumpAll) {
- if (svc.mOwner != null) {
- pw.print(" mOwner="); pw.println(svc.mOwner);
- }
- if (svc.mStarted || svc.mRestarting) {
- pw.print(" mStarted="); pw.print(svc.mStarted);
- pw.print(" mRestarting="); pw.println(svc.mRestarting);
- }
- }
- }
- }
- }
- }
-
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- printedHeader = false;
- int numShownProcs = 0, numTotalProcs = 0;
- for (int ip=0; ip<procMap.size(); ip++) {
- String procName = procMap.keyAt(ip);
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- int uid = uids.keyAt(iu);
- numTotalProcs++;
- ProcessState proc = uids.valueAt(iu);
- if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
- && proc.mPssTableSize == 0) {
- continue;
- }
- if (!proc.mMultiPackage) {
- continue;
- }
- if (reqPackage != null && !reqPackage.equals(procName)
- && !reqPackage.equals(proc.mPackage)) {
- continue;
- }
- numShownProcs++;
- if (sepNeeded) {
- pw.println();
- }
- sepNeeded = true;
- if (!printedHeader) {
- pw.println("Multi-Package Common Processes:");
- printedHeader = true;
- }
- if (activeOnly && !proc.isInUse()) {
- pw.print(" (Not active: "); pw.print(procName); pw.println(")");
- continue;
- }
- pw.print(" * "); pw.print(procName); pw.print(" / ");
- UserHandle.formatUid(pw, uid);
- pw.print(" ("); pw.print(proc.mDurationsTableSize);
- pw.print(" entries)"); pw.println(":");
- dumpProcessState(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES, now);
- dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES);
- dumpProcessInternalLocked(pw, " ", proc, dumpAll);
- }
- }
- if (dumpAll) {
- pw.println();
- pw.print(" Total procs: "); pw.print(numShownProcs);
- pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
- }
-
- if (sepNeeded) {
- pw.println();
- }
- if (dumpSummary) {
- pw.println("Summary:");
- dumpSummaryLocked(pw, reqPackage, now, activeOnly);
- } else {
- dumpTotalsLocked(pw, now);
- }
-
- if (dumpAll) {
- pw.println();
- pw.println("Internal state:");
- pw.print(" Num long arrays: "); pw.println(mLongs.size());
- pw.print(" Next long entry: "); pw.println(mNextLong);
- pw.print(" mRunning="); pw.println(mRunning);
- }
- }
-
- public static long dumpSingleServiceTime(PrintWriter pw, String prefix, ServiceState service,
- int serviceType, int curState, long curStartTime, long now) {
- long totalTime = 0;
- int printedScreen = -1;
- for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
- int printedMem = -1;
- for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
- int state = imem+iscreen;
- long time = service.getDuration(serviceType, curState, curStartTime,
- state, now);
- String running = "";
- if (curState == state && pw != null) {
- running = " (running)";
- }
- if (time != 0) {
- if (pw != null) {
- pw.print(prefix);
- printScreenLabel(pw, printedScreen != iscreen
- ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0);
- printedMem = imem;
- pw.print(": ");
- TimeUtils.formatDuration(time, pw); pw.println(running);
- }
- totalTime += time;
- }
- }
- }
- if (totalTime != 0 && pw != null) {
- pw.print(prefix);
- pw.print(" TOTAL: ");
- TimeUtils.formatDuration(totalTime, pw);
- pw.println();
- }
- return totalTime;
- }
-
- void dumpServiceStats(PrintWriter pw, String prefix, String prefixInner,
- String headerPrefix, String header, ServiceState service,
- int count, int serviceType, int state, long startTime, long now, long totalTime,
- boolean dumpAll) {
- if (count != 0) {
- if (dumpAll) {
- pw.print(prefix); pw.print(header);
- pw.print(" op count "); pw.print(count); pw.println(":");
- dumpSingleServiceTime(pw, prefixInner, service, serviceType, state, startTime,
- now);
- } else {
- long myTime = dumpSingleServiceTime(null, null, service, serviceType, state,
- startTime, now);
- pw.print(prefix); pw.print(headerPrefix); pw.print(header);
- pw.print(" count "); pw.print(count);
- pw.print(" / time ");
- printPercent(pw, (double)myTime/(double)totalTime);
- pw.println();
- }
- }
- }
-
- public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) {
- long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
- mStartTime, now);
- dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly);
- pw.println();
- dumpTotalsLocked(pw, now);
- }
-
- long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight,
- long totalTime, long curTotalMem, int samples) {
- if (memWeight != 0) {
- long mem = (long)(memWeight * 1024 / totalTime);
- pw.print(prefix);
- pw.print(label);
- pw.print(": ");
- DebugUtils.printSizeValue(pw, mem);
- pw.print(" (");
- pw.print(samples);
- pw.print(" samples)");
- pw.println();
- return curTotalMem + mem;
- }
- return curTotalMem;
- }
-
- void dumpTotalsLocked(PrintWriter pw, long now) {
- pw.println("Run time Stats:");
- dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now);
- pw.println();
- pw.println("Memory usage:");
- TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
- ALL_MEM_ADJ);
- computeTotalMemoryUse(totalMem, now);
- long totalPss = 0;
- totalPss = printMemoryCategory(pw, " ", "Kernel ", totalMem.sysMemKernelWeight,
- totalMem.totalTime, totalPss, totalMem.sysMemSamples);
- totalPss = printMemoryCategory(pw, " ", "Native ", totalMem.sysMemNativeWeight,
- totalMem.totalTime, totalPss, totalMem.sysMemSamples);
- for (int i=0; i<STATE_COUNT; i++) {
- // Skip restarting service state -- that is not actually a running process.
- if (i != STATE_SERVICE_RESTARTING) {
- totalPss = printMemoryCategory(pw, " ", STATE_NAMES[i],
- totalMem.processStateWeight[i], totalMem.totalTime, totalPss,
- totalMem.processStateSamples[i]);
- }
- }
- totalPss = printMemoryCategory(pw, " ", "Cached ", totalMem.sysMemCachedWeight,
- totalMem.totalTime, totalPss, totalMem.sysMemSamples);
- totalPss = printMemoryCategory(pw, " ", "Free ", totalMem.sysMemFreeWeight,
- totalMem.totalTime, totalPss, totalMem.sysMemSamples);
- totalPss = printMemoryCategory(pw, " ", "Z-Ram ", totalMem.sysMemZRamWeight,
- totalMem.totalTime, totalPss, totalMem.sysMemSamples);
- pw.print(" TOTAL : ");
- DebugUtils.printSizeValue(pw, totalPss);
- pw.println();
- printMemoryCategory(pw, " ", STATE_NAMES[STATE_SERVICE_RESTARTING],
- totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss,
- totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
- pw.println();
- pw.print(" Start time: ");
- pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
- pw.println();
- pw.print(" Total elapsed time: ");
- TimeUtils.formatDuration(
- (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
- - mTimePeriodStartRealtime, pw);
- boolean partial = true;
- if ((mFlags&FLAG_SHUTDOWN) != 0) {
- pw.print(" (shutdown)");
- partial = false;
- }
- if ((mFlags&FLAG_SYSPROPS) != 0) {
- pw.print(" (sysprops)");
- partial = false;
- }
- if ((mFlags&FLAG_COMPLETE) != 0) {
- pw.print(" (complete)");
- partial = false;
- }
- if (partial) {
- pw.print(" (partial)");
- }
- pw.print(' ');
- pw.print(mRuntime);
- pw.println();
- }
-
- void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
- int[] screenStates, int[] memStates, int[] procStates,
- int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) {
- ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
- procStates, sortProcStates, now, reqPackage, activeOnly);
- if (procs.size() > 0) {
- if (header != null) {
- pw.println();
- pw.println(header);
- }
- dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates,
- sortProcStates, true, now, totalTime);
- }
- }
-
- public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
- int[] procStates, int sortProcStates[], long now, String reqPackage,
- boolean activeOnly) {
- final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
- final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
- for (int ip=0; ip<pkgMap.size(); ip++) {
- final String pkgName = pkgMap.keyAt(ip);
- final SparseArray<SparseArray<PackageState>> procs = pkgMap.valueAt(ip);
- for (int iu=0; iu<procs.size(); iu++) {
- final SparseArray<PackageState> vpkgs = procs.valueAt(iu);
- final int NVERS = vpkgs.size();
- for (int iv=0; iv<NVERS; iv++) {
- final PackageState state = vpkgs.valueAt(iv);
- final int NPROCS = state.mProcesses.size();
- final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
- for (int iproc=0; iproc<NPROCS; iproc++) {
- final ProcessState proc = state.mProcesses.valueAt(iproc);
- if (!pkgMatch && !reqPackage.equals(proc.mName)) {
- continue;
- }
- if (activeOnly && !proc.isInUse()) {
- continue;
- }
- foundProcs.add(proc.mCommonProcess);
- }
- }
- }
- }
- ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size());
- for (int i=0; i<foundProcs.size(); i++) {
- ProcessState proc = foundProcs.valueAt(i);
- if (computeProcessTimeLocked(proc, screenStates, memStates, procStates, now) > 0) {
- outProcs.add(proc);
- if (procStates != sortProcStates) {
- computeProcessTimeLocked(proc, screenStates, memStates, sortProcStates, now);
- }
- }
- }
- Collections.sort(outProcs, new Comparator<ProcessState>() {
- @Override
- public int compare(ProcessState lhs, ProcessState rhs) {
- if (lhs.mTmpTotalTime < rhs.mTmpTotalTime) {
- return -1;
- } else if (lhs.mTmpTotalTime > rhs.mTmpTotalTime) {
- return 1;
- }
- return 0;
- }
- });
- return outProcs;
- }
-
- String collapseString(String pkgName, String itemName) {
- if (itemName.startsWith(pkgName)) {
- final int ITEMLEN = itemName.length();
- final int PKGLEN = pkgName.length();
- if (ITEMLEN == PKGLEN) {
- return "";
- } else if (ITEMLEN >= PKGLEN) {
- if (itemName.charAt(PKGLEN) == '.') {
- return itemName.substring(PKGLEN);
- }
- }
- }
- return itemName;
- }
-
- public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
- final long now = SystemClock.uptimeMillis();
- final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
- pw.println("vers,5");
- pw.print("period,"); pw.print(mTimePeriodStartClockStr);
- pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
- pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
- boolean partial = true;
- if ((mFlags&FLAG_SHUTDOWN) != 0) {
- pw.print(",shutdown");
- partial = false;
- }
- if ((mFlags&FLAG_SYSPROPS) != 0) {
- pw.print(",sysprops");
- partial = false;
- }
- if ((mFlags&FLAG_COMPLETE) != 0) {
- pw.print(",complete");
- partial = false;
- }
- if (partial) {
- pw.print(",partial");
- }
- pw.println();
- pw.print("config,"); pw.println(mRuntime);
- for (int ip=0; ip<pkgMap.size(); ip++) {
- final String pkgName = pkgMap.keyAt(ip);
- if (reqPackage != null && !reqPackage.equals(pkgName)) {
- continue;
- }
- final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- final int uid = uids.keyAt(iu);
- final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
- for (int iv=0; iv<vpkgs.size(); iv++) {
- final int vers = vpkgs.keyAt(iv);
- final PackageState pkgState = vpkgs.valueAt(iv);
- final int NPROCS = pkgState.mProcesses.size();
- final int NSRVS = pkgState.mServices.size();
- for (int iproc=0; iproc<NPROCS; iproc++) {
- ProcessState proc = pkgState.mProcesses.valueAt(iproc);
- pw.print("pkgproc,");
- pw.print(pkgName);
- pw.print(",");
- pw.print(uid);
- pw.print(",");
- pw.print(vers);
- pw.print(",");
- pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
- dumpAllProcessStateCheckin(pw, proc, now);
- pw.println();
- if (proc.mPssTableSize > 0) {
- pw.print("pkgpss,");
- pw.print(pkgName);
- pw.print(",");
- pw.print(uid);
- pw.print(",");
- pw.print(vers);
- pw.print(",");
- pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
- dumpAllProcessPssCheckin(pw, proc);
- pw.println();
- }
- if (proc.mNumExcessiveWake > 0 || proc.mNumExcessiveCpu > 0
- || proc.mNumCachedKill > 0) {
- pw.print("pkgkills,");
- pw.print(pkgName);
- pw.print(",");
- pw.print(uid);
- pw.print(",");
- pw.print(vers);
- pw.print(",");
- pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
- pw.print(",");
- pw.print(proc.mNumExcessiveWake);
- pw.print(",");
- pw.print(proc.mNumExcessiveCpu);
- pw.print(",");
- pw.print(proc.mNumCachedKill);
- pw.print(",");
- pw.print(proc.mMinCachedKillPss);
- pw.print(":");
- pw.print(proc.mAvgCachedKillPss);
- pw.print(":");
- pw.print(proc.mMaxCachedKillPss);
- pw.println();
- }
- }
- for (int isvc=0; isvc<NSRVS; isvc++) {
- String serviceName = collapseString(pkgName,
- pkgState.mServices.keyAt(isvc));
- ServiceState svc = pkgState.mServices.valueAt(isvc);
- dumpServiceTimeCheckin(pw, "pkgsvc-run", pkgName, uid, vers, serviceName,
- svc, ServiceState.SERVICE_RUN, svc.mRunCount,
- svc.mRunState, svc.mRunStartTime, now);
- dumpServiceTimeCheckin(pw, "pkgsvc-start", pkgName, uid, vers, serviceName,
- svc, ServiceState.SERVICE_STARTED, svc.mStartedCount,
- svc.mStartedState, svc.mStartedStartTime, now);
- dumpServiceTimeCheckin(pw, "pkgsvc-bound", pkgName, uid, vers, serviceName,
- svc, ServiceState.SERVICE_BOUND, svc.mBoundCount,
- svc.mBoundState, svc.mBoundStartTime, now);
- dumpServiceTimeCheckin(pw, "pkgsvc-exec", pkgName, uid, vers, serviceName,
- svc, ServiceState.SERVICE_EXEC, svc.mExecCount,
- svc.mExecState, svc.mExecStartTime, now);
- }
- }
- }
- }
-
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- for (int ip=0; ip<procMap.size(); ip++) {
- String procName = procMap.keyAt(ip);
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- int uid = uids.keyAt(iu);
- ProcessState procState = uids.valueAt(iu);
- if (procState.mDurationsTableSize > 0) {
- pw.print("proc,");
- pw.print(procName);
- pw.print(",");
- pw.print(uid);
- dumpAllProcessStateCheckin(pw, procState, now);
- pw.println();
- }
- if (procState.mPssTableSize > 0) {
- pw.print("pss,");
- pw.print(procName);
- pw.print(",");
- pw.print(uid);
- dumpAllProcessPssCheckin(pw, procState);
- pw.println();
- }
- if (procState.mNumExcessiveWake > 0 || procState.mNumExcessiveCpu > 0
- || procState.mNumCachedKill > 0) {
- pw.print("kills,");
- pw.print(procName);
- pw.print(",");
- pw.print(uid);
- pw.print(",");
- pw.print(procState.mNumExcessiveWake);
- pw.print(",");
- pw.print(procState.mNumExcessiveCpu);
- pw.print(",");
- pw.print(procState.mNumCachedKill);
- pw.print(",");
- pw.print(procState.mMinCachedKillPss);
- pw.print(":");
- pw.print(procState.mAvgCachedKillPss);
- pw.print(":");
- pw.print(procState.mMaxCachedKillPss);
- pw.println();
- }
- }
- }
- pw.print("total");
- dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor,
- mStartTime, now);
- pw.println();
- if (mSysMemUsageTable != null) {
- pw.print("sysmemusage");
- for (int i=0; i<mSysMemUsageTableSize; i++) {
- int off = mSysMemUsageTable[i];
- int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- pw.print(",");
- printProcStateTag(pw, type);
- for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) {
- if (j > SYS_MEM_USAGE_CACHED_MINIMUM) {
- pw.print(":");
- }
- pw.print(getLong(off, j));
- }
- }
- }
- pw.println();
- TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
- ALL_MEM_ADJ);
- computeTotalMemoryUse(totalMem, now);
- pw.print("weights,");
- pw.print(totalMem.totalTime);
- pw.print(",");
- pw.print(totalMem.sysMemCachedWeight);
- pw.print(":");
- pw.print(totalMem.sysMemSamples);
- pw.print(",");
- pw.print(totalMem.sysMemFreeWeight);
- pw.print(":");
- pw.print(totalMem.sysMemSamples);
- pw.print(",");
- pw.print(totalMem.sysMemZRamWeight);
- pw.print(":");
- pw.print(totalMem.sysMemSamples);
- pw.print(",");
- pw.print(totalMem.sysMemKernelWeight);
- pw.print(":");
- pw.print(totalMem.sysMemSamples);
- pw.print(",");
- pw.print(totalMem.sysMemNativeWeight);
- pw.print(":");
- pw.print(totalMem.sysMemSamples);
- for (int i=0; i<STATE_COUNT; i++) {
- pw.print(",");
- pw.print(totalMem.processStateWeight[i]);
- pw.print(":");
- pw.print(totalMem.processStateSamples[i]);
- }
- pw.println();
- }
-
- public static class DurationsTable {
- public final ProcessStats mStats;
- public final String mName;
- public int[] mDurationsTable;
- public int mDurationsTableSize;
-
- public DurationsTable(ProcessStats stats, String name) {
- mStats = stats;
- mName = name;
- }
-
- void copyDurationsTo(DurationsTable other) {
- if (mDurationsTable != null) {
- mStats.mAddLongTable = new int[mDurationsTable.length];
- mStats.mAddLongTableSize = 0;
- for (int i=0; i<mDurationsTableSize; i++) {
- int origEnt = mDurationsTable[i];
- int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- int newOff = mStats.addLongData(i, type, 1);
- mStats.mAddLongTable[i] = newOff | type;
- mStats.setLong(newOff, 0, mStats.getLong(origEnt, 0));
- }
- other.mDurationsTable = mStats.mAddLongTable;
- other.mDurationsTableSize = mStats.mAddLongTableSize;
- } else {
- other.mDurationsTable = null;
- other.mDurationsTableSize = 0;
- }
- }
-
- void addDurations(DurationsTable other) {
- for (int i=0; i<other.mDurationsTableSize; i++) {
- int ent = other.mDurationsTable[i];
- int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- if (DEBUG) Slog.d(TAG, "Adding state " + state + " duration "
- + other.mStats.getLong(ent, 0));
- addDuration(state, other.mStats.getLong(ent, 0));
- }
- }
-
- void resetDurationsSafely() {
- mDurationsTable = null;
- mDurationsTableSize = 0;
- }
-
- void writeDurationsToParcel(Parcel out) {
- out.writeInt(mDurationsTableSize);
- for (int i=0; i<mDurationsTableSize; i++) {
- if (DEBUG_PARCEL) Slog.i(TAG, "Writing in " + mName + " dur #" + i + ": "
- + printLongOffset(mDurationsTable[i]));
- out.writeInt(mDurationsTable[i]);
- }
- }
-
- boolean readDurationsFromParcel(Parcel in) {
- mDurationsTable = mStats.readTableFromParcel(in, mName, "durations");
- if (mDurationsTable == BAD_TABLE) {
- return false;
- }
- mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
- return true;
- }
-
- void addDuration(int state, long dur) {
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- int off;
- if (idx >= 0) {
- off = mDurationsTable[idx];
- } else {
- mStats.mAddLongTable = mDurationsTable;
- mStats.mAddLongTableSize = mDurationsTableSize;
- off = mStats.addLongData(~idx, state, 1);
- mDurationsTable = mStats.mAddLongTable;
- mDurationsTableSize = mStats.mAddLongTableSize;
- }
- long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- if (DEBUG) Slog.d(TAG, "Duration of " + mName + " state " + state + " inc by " + dur
- + " from " + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK]);
- longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur;
- }
-
- long getDuration(int state, long now) {
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- return idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
- }
- }
-
- final public static class ProcessStateHolder {
- public final int appVersion;
- public ProcessStats.ProcessState state;
-
- public ProcessStateHolder(int _appVersion) {
- appVersion = _appVersion;
- }
- }
-
- public static final class ProcessState extends DurationsTable {
- public ProcessState mCommonProcess;
- public final String mPackage;
- public final int mUid;
- public final int mVersion;
-
- //final long[] mDurations = new long[STATE_COUNT*ADJ_COUNT];
- int mCurState = STATE_NOTHING;
- long mStartTime;
-
- int mLastPssState = STATE_NOTHING;
- long mLastPssTime;
- int[] mPssTable;
- int mPssTableSize;
-
- boolean mActive;
- int mNumActiveServices;
- int mNumStartedServices;
-
- int mNumExcessiveWake;
- int mNumExcessiveCpu;
-
- int mNumCachedKill;
- long mMinCachedKillPss;
- long mAvgCachedKillPss;
- long mMaxCachedKillPss;
-
- boolean mMultiPackage;
- boolean mDead;
-
- public long mTmpTotalTime;
- int mTmpNumInUse;
- ProcessState mTmpFoundSubProc;
-
- /**
- * Create a new top-level process state, for the initial case where there is only
- * a single package running in a process. The initial state is not running.
- */
- public ProcessState(ProcessStats processStats, String pkg, int uid, int vers, String name) {
- super(processStats, name);
- mCommonProcess = this;
- mPackage = pkg;
- mUid = uid;
- mVersion = vers;
- }
-
- /**
- * Create a new per-package process state for an existing top-level process
- * state. The current running state of the top-level process is also copied,
- * marked as started running at 'now'.
- */
- public ProcessState(ProcessState commonProcess, String pkg, int uid, int vers, String name,
- long now) {
- super(commonProcess.mStats, name);
- mCommonProcess = commonProcess;
- mPackage = pkg;
- mUid = uid;
- mVersion = vers;
- mCurState = commonProcess.mCurState;
- mStartTime = now;
- }
-
- ProcessState clone(String pkg, long now) {
- ProcessState pnew = new ProcessState(this, pkg, mUid, mVersion, mName, now);
- copyDurationsTo(pnew);
- if (mPssTable != null) {
- mStats.mAddLongTable = new int[mPssTable.length];
- mStats.mAddLongTableSize = 0;
- for (int i=0; i<mPssTableSize; i++) {
- int origEnt = mPssTable[i];
- int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- int newOff = mStats.addLongData(i, type, PSS_COUNT);
- mStats.mAddLongTable[i] = newOff | type;
- for (int j=0; j<PSS_COUNT; j++) {
- mStats.setLong(newOff, j, mStats.getLong(origEnt, j));
- }
- }
- pnew.mPssTable = mStats.mAddLongTable;
- pnew.mPssTableSize = mStats.mAddLongTableSize;
- }
- pnew.mNumExcessiveWake = mNumExcessiveWake;
- pnew.mNumExcessiveCpu = mNumExcessiveCpu;
- pnew.mNumCachedKill = mNumCachedKill;
- pnew.mMinCachedKillPss = mMinCachedKillPss;
- pnew.mAvgCachedKillPss = mAvgCachedKillPss;
- pnew.mMaxCachedKillPss = mMaxCachedKillPss;
- pnew.mActive = mActive;
- pnew.mNumActiveServices = mNumActiveServices;
- pnew.mNumStartedServices = mNumStartedServices;
- return pnew;
- }
-
- void add(ProcessState other) {
- addDurations(other);
- for (int i=0; i<other.mPssTableSize; i++) {
- int ent = other.mPssTable[i];
- int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- addPss(state, (int) other.mStats.getLong(ent, PSS_SAMPLE_COUNT),
- other.mStats.getLong(ent, PSS_MINIMUM),
- other.mStats.getLong(ent, PSS_AVERAGE),
- other.mStats.getLong(ent, PSS_MAXIMUM),
- other.mStats.getLong(ent, PSS_USS_MINIMUM),
- other.mStats.getLong(ent, PSS_USS_AVERAGE),
- other.mStats.getLong(ent, PSS_USS_MAXIMUM));
- }
- mNumExcessiveWake += other.mNumExcessiveWake;
- mNumExcessiveCpu += other.mNumExcessiveCpu;
- if (other.mNumCachedKill > 0) {
- addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
- other.mAvgCachedKillPss, other.mMaxCachedKillPss);
- }
- }
-
- void resetSafely(long now) {
- resetDurationsSafely();
- mStartTime = now;
- mLastPssState = STATE_NOTHING;
- mLastPssTime = 0;
- mPssTable = null;
- mPssTableSize = 0;
- mNumExcessiveWake = 0;
- mNumExcessiveCpu = 0;
- mNumCachedKill = 0;
- mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
- }
-
- void makeDead() {
- mDead = true;
- }
-
- private void ensureNotDead() {
- if (!mDead) {
- return;
- }
- Slog.wtfStack(TAG, "ProcessState dead: name=" + mName
- + " pkg=" + mPackage + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
- }
-
- void writeToParcel(Parcel out, long now) {
- out.writeInt(mMultiPackage ? 1 : 0);
- writeDurationsToParcel(out);
- out.writeInt(mPssTableSize);
- for (int i=0; i<mPssTableSize; i++) {
- if (DEBUG_PARCEL) Slog.i(TAG, "Writing in " + mName + " pss #" + i + ": "
- + printLongOffset(mPssTable[i]));
- out.writeInt(mPssTable[i]);
- }
- out.writeInt(mNumExcessiveWake);
- out.writeInt(mNumExcessiveCpu);
- out.writeInt(mNumCachedKill);
- if (mNumCachedKill > 0) {
- out.writeLong(mMinCachedKillPss);
- out.writeLong(mAvgCachedKillPss);
- out.writeLong(mMaxCachedKillPss);
- }
- }
-
- boolean readFromParcel(Parcel in, boolean fully) {
- boolean multiPackage = in.readInt() != 0;
- if (fully) {
- mMultiPackage = multiPackage;
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Reading durations table...");
- if (!readDurationsFromParcel(in)) {
- return false;
- }
- if (DEBUG_PARCEL) Slog.d(TAG, "Reading pss table...");
- mPssTable = mStats.readTableFromParcel(in, mName, "pss");
- if (mPssTable == BAD_TABLE) {
- return false;
- }
- mPssTableSize = mPssTable != null ? mPssTable.length : 0;
- mNumExcessiveWake = in.readInt();
- mNumExcessiveCpu = in.readInt();
- mNumCachedKill = in.readInt();
- if (mNumCachedKill > 0) {
- mMinCachedKillPss = in.readLong();
- mAvgCachedKillPss = in.readLong();
- mMaxCachedKillPss = in.readLong();
- } else {
- mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
- }
- return true;
- }
-
- public void makeActive() {
- ensureNotDead();
- mActive = true;
- }
-
- public void makeInactive() {
- mActive = false;
- }
-
- public boolean isInUse() {
- return mActive || mNumActiveServices > 0 || mNumStartedServices > 0
- || mCurState != STATE_NOTHING;
- }
-
- /**
- * Update the current state of the given list of processes.
- *
- * @param state Current ActivityManager.PROCESS_STATE_*
- * @param memFactor Current mem factor constant.
- * @param now Current time.
- * @param pkgList Processes to update.
- */
- public void setState(int state, int memFactor, long now,
- ArrayMap<String, ProcessStateHolder> pkgList) {
- if (state < 0) {
- state = mNumStartedServices > 0
- ? (STATE_SERVICE_RESTARTING+(memFactor*STATE_COUNT)) : STATE_NOTHING;
- } else {
- state = PROCESS_STATE_TO_STATE[state] + (memFactor*STATE_COUNT);
- }
-
- // First update the common process.
- mCommonProcess.setState(state, now);
-
- // If the common process is not multi-package, there is nothing else to do.
- if (!mCommonProcess.mMultiPackage) {
- return;
- }
-
- if (pkgList != null) {
- for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).setState(state, now);
- }
- }
- }
-
- void setState(int state, long now) {
- ensureNotDead();
- if (mCurState != state) {
- //Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
- commitStateTime(now);
- mCurState = state;
- }
- }
-
- void commitStateTime(long now) {
- if (mCurState != STATE_NOTHING) {
- long dur = now - mStartTime;
- if (dur > 0) {
- addDuration(mCurState, dur);
- }
- }
- mStartTime = now;
- }
-
- void incActiveServices(String serviceName) {
- if (DEBUG && "".equals(mName)) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.d(TAG, "incActiveServices: " + this + " service=" + serviceName
- + " to " + (mNumActiveServices+1), here);
- }
- if (mCommonProcess != this) {
- mCommonProcess.incActiveServices(serviceName);
- }
- mNumActiveServices++;
- }
-
- void decActiveServices(String serviceName) {
- if (DEBUG && "".equals(mName)) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
- + " to " + (mNumActiveServices-1), here);
- }
- if (mCommonProcess != this) {
- mCommonProcess.decActiveServices(serviceName);
- }
- mNumActiveServices--;
- if (mNumActiveServices < 0) {
- Slog.wtfStack(TAG, "Proc active services underrun: pkg=" + mPackage
- + " uid=" + mUid + " proc=" + mName + " service=" + serviceName);
- mNumActiveServices = 0;
- }
- }
-
- void incStartedServices(int memFactor, long now, String serviceName) {
- if (false) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName
- + " to " + (mNumStartedServices+1), here);
- }
- if (mCommonProcess != this) {
- mCommonProcess.incStartedServices(memFactor, now, serviceName);
- }
- mNumStartedServices++;
- if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
- setState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
- }
- }
-
- void decStartedServices(int memFactor, long now, String serviceName) {
- if (false) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
- + " to " + (mNumStartedServices-1), here);
- }
- if (mCommonProcess != this) {
- mCommonProcess.decStartedServices(memFactor, now, serviceName);
- }
- mNumStartedServices--;
- if (mNumStartedServices == 0 && (mCurState%STATE_COUNT) == STATE_SERVICE_RESTARTING) {
- setState(STATE_NOTHING, now);
- } else if (mNumStartedServices < 0) {
- Slog.wtfStack(TAG, "Proc started services underrun: pkg="
- + mPackage + " uid=" + mUid + " name=" + mName);
- mNumStartedServices = 0;
- }
- }
-
- public void addPss(long pss, long uss, boolean always,
- ArrayMap<String, ProcessStateHolder> pkgList) {
- ensureNotDead();
- if (!always) {
- if (mLastPssState == mCurState && SystemClock.uptimeMillis()
- < (mLastPssTime+(30*1000))) {
- return;
- }
- }
- mLastPssState = mCurState;
- mLastPssTime = SystemClock.uptimeMillis();
- if (mCurState != STATE_NOTHING) {
- // First update the common process.
- mCommonProcess.addPss(mCurState, 1, pss, pss, pss, uss, uss, uss);
-
- // If the common process is not multi-package, there is nothing else to do.
- if (!mCommonProcess.mMultiPackage) {
- return;
- }
-
- if (pkgList != null) {
- for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).addPss(mCurState, 1,
- pss, pss, pss, uss, uss, uss);
- }
- }
- }
- }
-
- void addPss(int state, int inCount, long minPss, long avgPss, long maxPss, long minUss,
- long avgUss, long maxUss) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- int off;
- if (idx >= 0) {
- off = mPssTable[idx];
- } else {
- mStats.mAddLongTable = mPssTable;
- mStats.mAddLongTableSize = mPssTableSize;
- off = mStats.addLongData(~idx, state, PSS_COUNT);
- mPssTable = mStats.mAddLongTable;
- mPssTableSize = mStats.mAddLongTableSize;
- }
- long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK;
- long count = longs[idx+PSS_SAMPLE_COUNT];
- if (count == 0) {
- longs[idx+PSS_SAMPLE_COUNT] = inCount;
- longs[idx+PSS_MINIMUM] = minPss;
- longs[idx+PSS_AVERAGE] = avgPss;
- longs[idx+PSS_MAXIMUM] = maxPss;
- longs[idx+PSS_USS_MINIMUM] = minUss;
- longs[idx+PSS_USS_AVERAGE] = avgUss;
- longs[idx+PSS_USS_MAXIMUM] = maxUss;
- } else {
- longs[idx+PSS_SAMPLE_COUNT] = count+inCount;
- if (longs[idx+PSS_MINIMUM] > minPss) {
- longs[idx+PSS_MINIMUM] = minPss;
- }
- longs[idx+PSS_AVERAGE] = (long)(
- ((longs[idx+PSS_AVERAGE]*(double)count)+(avgPss*(double)inCount))
- / (count+inCount) );
- if (longs[idx+PSS_MAXIMUM] < maxPss) {
- longs[idx+PSS_MAXIMUM] = maxPss;
- }
- if (longs[idx+PSS_USS_MINIMUM] > minUss) {
- longs[idx+PSS_USS_MINIMUM] = minUss;
- }
- longs[idx+PSS_USS_AVERAGE] = (long)(
- ((longs[idx+PSS_USS_AVERAGE]*(double)count)+(avgUss*(double)inCount))
- / (count+inCount) );
- if (longs[idx+PSS_USS_MAXIMUM] < maxUss) {
- longs[idx+PSS_USS_MAXIMUM] = maxUss;
- }
- }
- }
-
- public void reportExcessiveWake(ArrayMap<String, ProcessStateHolder> pkgList) {
- ensureNotDead();
- mCommonProcess.mNumExcessiveWake++;
- if (!mCommonProcess.mMultiPackage) {
- return;
- }
-
- for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).mNumExcessiveWake++;
- }
- }
-
- public void reportExcessiveCpu(ArrayMap<String, ProcessStateHolder> pkgList) {
- ensureNotDead();
- mCommonProcess.mNumExcessiveCpu++;
- if (!mCommonProcess.mMultiPackage) {
- return;
- }
-
- for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).mNumExcessiveCpu++;
- }
- }
-
- private void addCachedKill(int num, long minPss, long avgPss, long maxPss) {
- if (mNumCachedKill <= 0) {
- mNumCachedKill = num;
- mMinCachedKillPss = minPss;
- mAvgCachedKillPss = avgPss;
- mMaxCachedKillPss = maxPss;
- } else {
- if (minPss < mMinCachedKillPss) {
- mMinCachedKillPss = minPss;
- }
- if (maxPss > mMaxCachedKillPss) {
- mMaxCachedKillPss = maxPss;
- }
- mAvgCachedKillPss = (long)( ((mAvgCachedKillPss*(double)mNumCachedKill) + avgPss)
- / (mNumCachedKill+num) );
- mNumCachedKill += num;
- }
- }
-
- public void reportCachedKill(ArrayMap<String, ProcessStateHolder> pkgList, long pss) {
- ensureNotDead();
- mCommonProcess.addCachedKill(1, pss, pss, pss);
- if (!mCommonProcess.mMultiPackage) {
- return;
- }
-
- for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).addCachedKill(1, pss, pss, pss);
- }
- }
-
- ProcessState pullFixedProc(String pkgName) {
- if (mMultiPackage) {
- // The array map is still pointing to a common process state
- // that is now shared across packages. Update it to point to
- // the new per-package state.
- SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgName, mUid);
- if (vpkg == null) {
- throw new IllegalStateException("Didn't find package " + pkgName
- + " / " + mUid);
- }
- PackageState pkg = vpkg.get(mVersion);
- if (pkg == null) {
- throw new IllegalStateException("Didn't find package " + pkgName
- + " / " + mUid + " vers " + mVersion);
- }
- ProcessState proc = pkg.mProcesses.get(mName);
- if (proc == null) {
- throw new IllegalStateException("Didn't create per-package process "
- + mName + " in pkg " + pkgName + " / " + mUid + " vers " + mVersion);
- }
- return proc;
- }
- return this;
- }
-
- private ProcessState pullFixedProc(ArrayMap<String, ProcessStateHolder> pkgList,
- int index) {
- ProcessStateHolder holder = pkgList.valueAt(index);
- ProcessState proc = holder.state;
- if (mDead && proc.mCommonProcess != proc) {
- // Somehow we are contining to use a process state that is dead, because
- // it was not being told it was active during the last commit. We can recover
- // from this by generating a fresh new state, but this is bad because we
- // are losing whatever data we had in the old process state.
- Log.wtf(TAG, "Pulling dead proc: name=" + mName + " pkg=" + mPackage
- + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
- proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mVersion,
- proc.mName);
- }
- if (proc.mMultiPackage) {
- // The array map is still pointing to a common process state
- // that is now shared across packages. Update it to point to
- // the new per-package state.
- SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgList.keyAt(index),
- proc.mUid);
- if (vpkg == null) {
- throw new IllegalStateException("No existing package "
- + pkgList.keyAt(index) + "/" + proc.mUid
- + " for multi-proc " + proc.mName);
- }
- PackageState pkg = vpkg.get(proc.mVersion);
- if (pkg == null) {
- throw new IllegalStateException("No existing package "
- + pkgList.keyAt(index) + "/" + proc.mUid
- + " for multi-proc " + proc.mName + " version " + proc.mVersion);
- }
- String savedName = proc.mName;
- proc = pkg.mProcesses.get(proc.mName);
- if (proc == null) {
- throw new IllegalStateException("Didn't create per-package process "
- + savedName + " in pkg " + pkg.mPackageName + "/" + pkg.mUid);
- }
- holder.state = proc;
- }
- return proc;
- }
-
- long getDuration(int state, long now) {
- long time = super.getDuration(state, now);
- if (mCurState == state) {
- time += now - mStartTime;
- }
- return time;
- }
-
- long getPssSampleCount(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_SAMPLE_COUNT) : 0;
- }
-
- long getPssMinimum(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_MINIMUM) : 0;
- }
-
- long getPssAverage(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_AVERAGE) : 0;
- }
-
- long getPssMaximum(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_MAXIMUM) : 0;
- }
-
- long getPssUssMinimum(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_MINIMUM) : 0;
- }
-
- long getPssUssAverage(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_AVERAGE) : 0;
- }
-
- long getPssUssMaximum(int state) {
- int idx = binarySearch(mPssTable, mPssTableSize, state);
- return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_MAXIMUM) : 0;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder(128);
- sb.append("ProcessState{").append(Integer.toHexString(System.identityHashCode(this)))
- .append(" ").append(mName).append("/").append(mUid)
- .append(" pkg=").append(mPackage);
- if (mMultiPackage) sb.append(" (multi)");
- if (mCommonProcess != this) sb.append(" (sub)");
- sb.append("}");
- return sb.toString();
- }
- }
-
- public static final class ServiceState extends DurationsTable {
- public final String mPackage;
- public final String mProcessName;
- ProcessState mProc;
-
- Object mOwner;
-
- public static final int SERVICE_RUN = 0;
- public static final int SERVICE_STARTED = 1;
- public static final int SERVICE_BOUND = 2;
- public static final int SERVICE_EXEC = 3;
- static final int SERVICE_COUNT = 4;
-
- int mRunCount;
- public int mRunState = STATE_NOTHING;
- long mRunStartTime;
-
- boolean mStarted;
- boolean mRestarting;
- int mStartedCount;
- public int mStartedState = STATE_NOTHING;
- long mStartedStartTime;
-
- int mBoundCount;
- public int mBoundState = STATE_NOTHING;
- long mBoundStartTime;
-
- int mExecCount;
- public int mExecState = STATE_NOTHING;
- long mExecStartTime;
-
- public ServiceState(ProcessStats processStats, String pkg, String name,
- String processName, ProcessState proc) {
- super(processStats, name);
- mPackage = pkg;
- mProcessName = processName;
- mProc = proc;
- }
-
- public void applyNewOwner(Object newOwner) {
- if (mOwner != newOwner) {
- if (mOwner == null) {
- mOwner = newOwner;
- mProc.incActiveServices(mName);
- } else {
- // There was already an old owner, reset this object for its
- // new owner.
- mOwner = newOwner;
- if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
- long now = SystemClock.uptimeMillis();
- if (mStarted) {
- if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
- + " from " + mOwner + " while started: pkg="
- + mPackage + " service=" + mName + " proc=" + mProc);
- setStarted(false, 0, now);
- }
- if (mBoundState != STATE_NOTHING) {
- if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
- + " from " + mOwner + " while bound: pkg="
- + mPackage + " service=" + mName + " proc=" + mProc);
- setBound(false, 0, now);
- }
- if (mExecState != STATE_NOTHING) {
- if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
- + " from " + mOwner + " while executing: pkg="
- + mPackage + " service=" + mName + " proc=" + mProc);
- setExecuting(false, 0, now);
- }
- }
- }
- }
- }
-
- public void clearCurrentOwner(Object owner, boolean silently) {
- if (mOwner == owner) {
- mProc.decActiveServices(mName);
- if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
- long now = SystemClock.uptimeMillis();
- if (mStarted) {
- if (!silently) {
- Slog.wtfStack(TAG, "Service owner " + owner
- + " cleared while started: pkg=" + mPackage + " service="
- + mName + " proc=" + mProc);
- }
- setStarted(false, 0, now);
- }
- if (mBoundState != STATE_NOTHING) {
- if (!silently) {
- Slog.wtfStack(TAG, "Service owner " + owner
- + " cleared while bound: pkg=" + mPackage + " service="
- + mName + " proc=" + mProc);
- }
- setBound(false, 0, now);
- }
- if (mExecState != STATE_NOTHING) {
- if (!silently) {
- Slog.wtfStack(TAG, "Service owner " + owner
- + " cleared while exec: pkg=" + mPackage + " service="
- + mName + " proc=" + mProc);
- }
- setExecuting(false, 0, now);
- }
- }
- mOwner = null;
- }
- }
-
- public boolean isInUse() {
- return mOwner != null || mRestarting;
- }
-
- public boolean isRestarting() {
- return mRestarting;
- }
-
- void add(ServiceState other) {
- addDurations(other);
- mRunCount += other.mRunCount;
- mStartedCount += other.mStartedCount;
- mBoundCount += other.mBoundCount;
- mExecCount += other.mExecCount;
- }
-
- void resetSafely(long now) {
- resetDurationsSafely();
- mRunCount = mRunState != STATE_NOTHING ? 1 : 0;
- mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0;
- mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0;
- mExecCount = mExecState != STATE_NOTHING ? 1 : 0;
- mRunStartTime = mStartedStartTime = mBoundStartTime = mExecStartTime = now;
- }
-
- void writeToParcel(Parcel out, long now) {
- writeDurationsToParcel(out);
- out.writeInt(mRunCount);
- out.writeInt(mStartedCount);
- out.writeInt(mBoundCount);
- out.writeInt(mExecCount);
- }
-
- boolean readFromParcel(Parcel in) {
- if (!readDurationsFromParcel(in)) {
- return false;
- }
- mRunCount = in.readInt();
- mStartedCount = in.readInt();
- mBoundCount = in.readInt();
- mExecCount = in.readInt();
- return true;
- }
-
- void commitStateTime(long now) {
- if (mRunState != STATE_NOTHING) {
- addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT), now - mRunStartTime);
- mRunStartTime = now;
- }
- if (mStartedState != STATE_NOTHING) {
- addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
- now - mStartedStartTime);
- mStartedStartTime = now;
- }
- if (mBoundState != STATE_NOTHING) {
- addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), now - mBoundStartTime);
- mBoundStartTime = now;
- }
- if (mExecState != STATE_NOTHING) {
- addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
- mExecStartTime = now;
- }
- }
-
- private void updateRunning(int memFactor, long now) {
- final int state = (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
- || mExecState != STATE_NOTHING) ? memFactor : STATE_NOTHING;
- if (mRunState != state) {
- if (mRunState != STATE_NOTHING) {
- addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
- now - mRunStartTime);
- } else if (state != STATE_NOTHING) {
- mRunCount++;
- }
- mRunState = state;
- mRunStartTime = now;
- }
- }
-
- public void setStarted(boolean started, int memFactor, long now) {
- if (mOwner == null) {
- Slog.wtf(TAG, "Starting service " + this + " without owner");
- }
- mStarted = started;
- updateStartedState(memFactor, now);
- }
-
- public void setRestarting(boolean restarting, int memFactor, long now) {
- mRestarting = restarting;
- updateStartedState(memFactor, now);
- }
-
- void updateStartedState(int memFactor, long now) {
- final boolean wasStarted = mStartedState != STATE_NOTHING;
- final boolean started = mStarted || mRestarting;
- final int state = started ? memFactor : STATE_NOTHING;
- if (mStartedState != state) {
- if (mStartedState != STATE_NOTHING) {
- addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
- now - mStartedStartTime);
- } else if (started) {
- mStartedCount++;
- }
- mStartedState = state;
- mStartedStartTime = now;
- mProc = mProc.pullFixedProc(mPackage);
- if (wasStarted != started) {
- if (started) {
- mProc.incStartedServices(memFactor, now, mName);
- } else {
- mProc.decStartedServices(memFactor, now, mName);
- }
- }
- updateRunning(memFactor, now);
- }
- }
-
- public void setBound(boolean bound, int memFactor, long now) {
- if (mOwner == null) {
- Slog.wtf(TAG, "Binding service " + this + " without owner");
- }
- final int state = bound ? memFactor : STATE_NOTHING;
- if (mBoundState != state) {
- if (mBoundState != STATE_NOTHING) {
- addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
- now - mBoundStartTime);
- } else if (bound) {
- mBoundCount++;
- }
- mBoundState = state;
- mBoundStartTime = now;
- updateRunning(memFactor, now);
- }
- }
-
- public void setExecuting(boolean executing, int memFactor, long now) {
- if (mOwner == null) {
- Slog.wtf(TAG, "Executing service " + this + " without owner");
- }
- final int state = executing ? memFactor : STATE_NOTHING;
- if (mExecState != state) {
- if (mExecState != STATE_NOTHING) {
- addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
- } else if (executing) {
- mExecCount++;
- }
- mExecState = state;
- mExecStartTime = now;
- updateRunning(memFactor, now);
- }
- }
-
- private long getDuration(int opType, int curState, long startTime, int memFactor,
- long now) {
- int state = opType + (memFactor*SERVICE_COUNT);
- long time = getDuration(state, now);
- if (curState == memFactor) {
- time += now - startTime;
- }
- return time;
- }
-
- public String toString() {
- return "ServiceState{" + Integer.toHexString(System.identityHashCode(this))
- + " " + mName + " pkg=" + mPackage + " proc="
- + Integer.toHexString(System.identityHashCode(this)) + "}";
- }
- }
-
- public static final class PackageState {
- public final ArrayMap<String, ProcessState> mProcesses
- = new ArrayMap<String, ProcessState>();
- public final ArrayMap<String, ServiceState> mServices
- = new ArrayMap<String, ServiceState>();
- public final String mPackageName;
- public final int mUid;
-
- public PackageState(String packageName, int uid) {
- mUid = uid;
- mPackageName = packageName;
- }
- }
-
- public static final class ProcessDataCollection {
- final int[] screenStates;
- final int[] memStates;
- final int[] procStates;
-
- public long totalTime;
- public long numPss;
- public long minPss;
- public long avgPss;
- public long maxPss;
- public long minUss;
- public long avgUss;
- public long maxUss;
-
- public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
- screenStates = _screenStates;
- memStates = _memStates;
- procStates = _procStates;
- }
-
- void print(PrintWriter pw, long overallTime, boolean full) {
- if (totalTime > overallTime) {
- pw.print("*");
- }
- printPercent(pw, (double) totalTime / (double) overallTime);
- if (numPss > 0) {
- pw.print(" (");
- DebugUtils.printSizeValue(pw, minPss * 1024);
- pw.print("-");
- DebugUtils.printSizeValue(pw, avgPss * 1024);
- pw.print("-");
- DebugUtils.printSizeValue(pw, maxPss * 1024);
- pw.print("/");
- DebugUtils.printSizeValue(pw, minUss * 1024);
- pw.print("-");
- DebugUtils.printSizeValue(pw, avgUss * 1024);
- pw.print("-");
- DebugUtils.printSizeValue(pw, maxUss * 1024);
- if (full) {
- pw.print(" over ");
- pw.print(numPss);
- }
- pw.print(")");
- }
- }
- }
-
- public static class TotalMemoryUseCollection {
- final int[] screenStates;
- final int[] memStates;
-
- public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) {
- screenStates = _screenStates;
- memStates = _memStates;
- }
-
- public long totalTime;
- public long[] processStatePss = new long[STATE_COUNT];
- public double[] processStateWeight = new double[STATE_COUNT];
- public long[] processStateTime = new long[STATE_COUNT];
- public int[] processStateSamples = new int[STATE_COUNT];
- public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT];
- public double sysMemCachedWeight;
- public double sysMemFreeWeight;
- public double sysMemZRamWeight;
- public double sysMemKernelWeight;
- public double sysMemNativeWeight;
- public int sysMemSamples;
- }
-}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 5726de1..0e02ed6 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -393,12 +393,7 @@
final DisplayResolveInfo dri = mAdapter.getOtherProfile();
if (dri != null) {
mProfileView.setVisibility(View.VISIBLE);
- final ImageView icon = (ImageView) mProfileView.findViewById(R.id.icon);
- final TextView text = (TextView) mProfileView.findViewById(R.id.text1);
- if (!dri.hasDisplayIcon()) {
- new LoadIconIntoViewTask(dri, icon).execute();
- }
- icon.setImageDrawable(dri.getDisplayIcon());
+ final TextView text = (TextView) mProfileView.findViewById(R.id.profile_button);
text.setText(dri.getDisplayLabel());
} else {
mProfileView.setVisibility(View.GONE);
diff --git a/core/java/com/android/internal/app/procstats/DumpUtils.java b/core/java/com/android/internal/app/procstats/DumpUtils.java
new file mode 100644
index 0000000..ebedc89
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/DumpUtils.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.format.DateFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+
+import static com.android.internal.app.procstats.ProcessStats.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * Utilities for dumping.
+ */
+public final class DumpUtils {
+ public static final String[] STATE_NAMES = new String[] {
+ "Persist", "Top ", "ImpFg ", "ImpBg ",
+ "Backup ", "HeavyWt", "Service", "ServRst",
+ "Receivr", "Home ",
+ "LastAct", "CchAct ", "CchCAct", "CchEmty"
+ };
+
+ public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] {
+ "off", "on"
+ };
+
+ public static final String[] ADJ_MEM_NAMES_CSV = new String[] {
+ "norm", "mod", "low", "crit"
+ };
+
+ public static final String[] STATE_NAMES_CSV = new String[] {
+ "pers", "top", "impfg", "impbg", "backup", "heavy",
+ "service", "service-rs", "receiver", "home", "lastact",
+ "cch-activity", "cch-aclient", "cch-empty"
+ };
+
+ static final String[] ADJ_SCREEN_TAGS = new String[] {
+ "0", "1"
+ };
+
+ static final String[] ADJ_MEM_TAGS = new String[] {
+ "n", "m", "l", "c"
+ };
+
+ static final String[] STATE_TAGS = new String[] {
+ "p", "t", "f", "b", "u", "w",
+ "s", "x", "r", "h", "l", "a", "c", "e"
+ };
+
+ static final String CSV_SEP = "\t";
+
+ /**
+ * No instantiate
+ */
+ private DumpUtils() {
+ }
+
+ public static void printScreenLabel(PrintWriter pw, int offset) {
+ switch (offset) {
+ case ADJ_NOTHING:
+ pw.print(" ");
+ break;
+ case ADJ_SCREEN_OFF:
+ pw.print("SOff/");
+ break;
+ case ADJ_SCREEN_ON:
+ pw.print("SOn /");
+ break;
+ default:
+ pw.print("????/");
+ break;
+ }
+ }
+
+ public static void printScreenLabelCsv(PrintWriter pw, int offset) {
+ switch (offset) {
+ case ADJ_NOTHING:
+ break;
+ case ADJ_SCREEN_OFF:
+ pw.print(ADJ_SCREEN_NAMES_CSV[0]);
+ break;
+ case ADJ_SCREEN_ON:
+ pw.print(ADJ_SCREEN_NAMES_CSV[1]);
+ break;
+ default:
+ pw.print("???");
+ break;
+ }
+ }
+
+ public static void printMemLabel(PrintWriter pw, int offset, char sep) {
+ switch (offset) {
+ case ADJ_NOTHING:
+ pw.print(" ");
+ if (sep != 0) pw.print(' ');
+ break;
+ case ADJ_MEM_FACTOR_NORMAL:
+ pw.print("Norm");
+ if (sep != 0) pw.print(sep);
+ break;
+ case ADJ_MEM_FACTOR_MODERATE:
+ pw.print("Mod ");
+ if (sep != 0) pw.print(sep);
+ break;
+ case ADJ_MEM_FACTOR_LOW:
+ pw.print("Low ");
+ if (sep != 0) pw.print(sep);
+ break;
+ case ADJ_MEM_FACTOR_CRITICAL:
+ pw.print("Crit");
+ if (sep != 0) pw.print(sep);
+ break;
+ default:
+ pw.print("????");
+ if (sep != 0) pw.print(sep);
+ break;
+ }
+ }
+
+ public static void printMemLabelCsv(PrintWriter pw, int offset) {
+ if (offset >= ADJ_MEM_FACTOR_NORMAL) {
+ if (offset <= ADJ_MEM_FACTOR_CRITICAL) {
+ pw.print(ADJ_MEM_NAMES_CSV[offset]);
+ } else {
+ pw.print("???");
+ }
+ }
+ }
+
+ public static void printPercent(PrintWriter pw, double fraction) {
+ fraction *= 100;
+ if (fraction < 1) {
+ pw.print(String.format("%.2f", fraction));
+ } else if (fraction < 10) {
+ pw.print(String.format("%.1f", fraction));
+ } else {
+ pw.print(String.format("%.0f", fraction));
+ }
+ pw.print("%");
+ }
+
+ public static void printProcStateTag(PrintWriter pw, int state) {
+ state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD*STATE_COUNT);
+ state = printArrayEntry(pw, ADJ_MEM_TAGS, state, STATE_COUNT);
+ printArrayEntry(pw, STATE_TAGS, state, 1);
+ }
+
+ public static void printAdjTag(PrintWriter pw, int state) {
+ state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD);
+ printArrayEntry(pw, ADJ_MEM_TAGS, state, 1);
+ }
+
+ public static void printProcStateTagAndValue(PrintWriter pw, int state, long value) {
+ pw.print(',');
+ printProcStateTag(pw, state);
+ pw.print(':');
+ pw.print(value);
+ }
+
+ public static void printAdjTagAndValue(PrintWriter pw, int state, long value) {
+ pw.print(',');
+ printAdjTag(pw, state);
+ pw.print(':');
+ pw.print(value);
+ }
+
+ public static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations,
+ int curState, long curStartTime, long now) {
+ long totalTime = 0;
+ int printedScreen = -1;
+ for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
+ int printedMem = -1;
+ for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
+ int state = imem+iscreen;
+ long time = durations[state];
+ String running = "";
+ if (curState == state) {
+ time += now - curStartTime;
+ if (pw != null) {
+ running = " (running)";
+ }
+ }
+ if (time != 0) {
+ if (pw != null) {
+ pw.print(prefix);
+ printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0);
+ printedMem = imem;
+ pw.print(": ");
+ TimeUtils.formatDuration(time, pw); pw.println(running);
+ }
+ totalTime += time;
+ }
+ }
+ }
+ if (totalTime != 0 && pw != null) {
+ pw.print(prefix);
+ pw.print(" TOTAL: ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
+ return totalTime;
+ }
+
+ public static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations,
+ int curState, long curStartTime, long now) {
+ for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
+ for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
+ int state = imem+iscreen;
+ long time = durations[state];
+ if (curState == state) {
+ time += now - curStartTime;
+ }
+ if (time != 0) {
+ printAdjTagAndValue(pw, state, time);
+ }
+ }
+ }
+ }
+
+ private static void dumpStateHeadersCsv(PrintWriter pw, String sep, int[] screenStates,
+ int[] memStates, int[] procStates) {
+ final int NS = screenStates != null ? screenStates.length : 1;
+ final int NM = memStates != null ? memStates.length : 1;
+ final int NP = procStates != null ? procStates.length : 1;
+ for (int is=0; is<NS; is++) {
+ for (int im=0; im<NM; im++) {
+ for (int ip=0; ip<NP; ip++) {
+ pw.print(sep);
+ boolean printed = false;
+ if (screenStates != null && screenStates.length > 1) {
+ printScreenLabelCsv(pw, screenStates[is]);
+ printed = true;
+ }
+ if (memStates != null && memStates.length > 1) {
+ if (printed) {
+ pw.print("-");
+ }
+ printMemLabelCsv(pw, memStates[im]);
+ printed = true;
+ }
+ if (procStates != null && procStates.length > 1) {
+ if (printed) {
+ pw.print("-");
+ }
+ pw.print(STATE_NAMES_CSV[procStates[ip]]);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Doesn't seem to be used.
+ *
+ public static void dumpProcessList(PrintWriter pw, String prefix, ArrayList<ProcessState> procs,
+ int[] screenStates, int[] memStates, int[] procStates, long now) {
+ String innerPrefix = prefix + " ";
+ for (int i=procs.size()-1; i>=0; i--) {
+ ProcessState proc = procs.get(i);
+ pw.print(prefix);
+ pw.print(proc.mName);
+ pw.print(" / ");
+ UserHandle.formatUid(pw, proc.mUid);
+ pw.print(" (");
+ pw.print(proc.durations.getKeyCount());
+ pw.print(" entries)");
+ pw.println(":");
+ proc.dumpProcessState(pw, innerPrefix, screenStates, memStates, procStates, now);
+ if (proc.pssTable.getKeyCount() > 0) {
+ proc.dumpPss(pw, innerPrefix, screenStates, memStates, procStates);
+ }
+ }
+ }
+ */
+
+ public static void dumpProcessSummaryLocked(PrintWriter pw, String prefix,
+ ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates,
+ long now, long totalTime) {
+ for (int i=procs.size()-1; i>=0; i--) {
+ final ProcessState proc = procs.get(i);
+ proc.dumpSummary(pw, prefix, screenStates, memStates, procStates, now, totalTime);
+ }
+ }
+
+ public static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
+ boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
+ boolean sepProcStates, int[] procStates, long now) {
+ pw.print("process");
+ pw.print(CSV_SEP);
+ pw.print("uid");
+ pw.print(CSV_SEP);
+ pw.print("vers");
+ dumpStateHeadersCsv(pw, CSV_SEP, sepScreenStates ? screenStates : null,
+ sepMemStates ? memStates : null,
+ sepProcStates ? procStates : null);
+ pw.println();
+ for (int i=procs.size()-1; i>=0; i--) {
+ ProcessState proc = procs.get(i);
+ pw.print(proc.getName());
+ pw.print(CSV_SEP);
+ UserHandle.formatUid(pw, proc.getUid());
+ pw.print(CSV_SEP);
+ pw.print(proc.getVersion());
+ proc.dumpCsv(pw, sepScreenStates, screenStates, sepMemStates,
+ memStates, sepProcStates, procStates, now);
+ pw.println();
+ }
+ }
+
+ public static int printArrayEntry(PrintWriter pw, String[] array, int value, int mod) {
+ int index = value/mod;
+ if (index >= 0 && index < array.length) {
+ pw.print(array[index]);
+ } else {
+ pw.print('?');
+ }
+ return value - index*mod;
+ }
+
+ public static String collapseString(String pkgName, String itemName) {
+ if (itemName.startsWith(pkgName)) {
+ final int ITEMLEN = itemName.length();
+ final int PKGLEN = pkgName.length();
+ if (ITEMLEN == PKGLEN) {
+ return "";
+ } else if (ITEMLEN >= PKGLEN) {
+ if (itemName.charAt(PKGLEN) == '.') {
+ return itemName.substring(PKGLEN);
+ }
+ }
+ }
+ return itemName;
+ }
+}
diff --git a/core/java/com/android/internal/app/procstats/DurationsTable.java b/core/java/com/android/internal/app/procstats/DurationsTable.java
new file mode 100644
index 0000000..b711ca1
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/DurationsTable.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+/**
+ * Sparse mapping table to store durations of processes, etc running in different
+ * states.
+ */
+public class DurationsTable extends SparseMappingTable.Table {
+ public DurationsTable(SparseMappingTable tableData) {
+ super(tableData);
+ }
+
+ /**
+ * Add all of the durations from the other table into this one.
+ * Resultant durations will be the sum of what is currently in the table
+ * and the new value.
+ */
+ public void addDurations(DurationsTable from) {
+ final int N = from.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = from.getKeyAt(i);
+ this.addDuration(SparseMappingTable.getIdFromKey(key), from.getValue(key));
+ }
+ }
+
+ /**
+ * Add the value into the value stored for the state.
+ *
+ * Resultant duration will be the sum of what is currently in the table
+ * and the new value.
+ */
+ public void addDuration(int state, long value) {
+ final int key = getOrAddKey((byte)state, 1);
+ setValue(key, getValue(key) + value);
+ }
+
+ /*
+ public long getDuration(int state, long now) {
+ final int key = getKey((byte)state);
+ if (key != SparseMappingTable.INVALID_KEY) {
+ return getValue(key);
+ } else {
+ return 0;
+ }
+ }
+ */
+}
+
+
diff --git a/core/java/com/android/internal/app/IProcessStats.aidl b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
similarity index 89%
rename from core/java/com/android/internal/app/IProcessStats.aidl
rename to core/java/com/android/internal/app/procstats/IProcessStats.aidl
index 6fadf2f..44867c7 100644
--- a/core/java/com/android/internal/app/IProcessStats.aidl
+++ b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.internal.app;
+package com.android.internal.app.procstats;
import android.content.ComponentName;
import android.os.ParcelFileDescriptor;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
interface IProcessStats {
byte[] getCurrentStats(out List<ParcelFileDescriptor> historic);
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
new file mode 100644
index 0000000..80d6070
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.format.DateFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats.PackageState;
+import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
+import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
+import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
+import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
+import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
+import static com.android.internal.app.procstats.ProcessStats.STATE_PERSISTENT;
+import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;
+import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_FOREGROUND;
+import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_BACKGROUND;
+import static com.android.internal.app.procstats.ProcessStats.STATE_BACKUP;
+import static com.android.internal.app.procstats.ProcessStats.STATE_HEAVY_WEIGHT;
+import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE;
+import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING;
+import static com.android.internal.app.procstats.ProcessStats.STATE_RECEIVER;
+import static com.android.internal.app.procstats.ProcessStats.STATE_HOME;
+import static com.android.internal.app.procstats.ProcessStats.STATE_LAST_ACTIVITY;
+import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY;
+import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY_CLIENT;
+import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY;
+import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;
+
+import dalvik.system.VMRuntime;
+import libcore.util.EmptyArray;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+
+public final class ProcessState {
+ private static final String TAG = "ProcessStats";
+ private static final boolean DEBUG = false;
+ private static final boolean DEBUG_PARCEL = false;
+
+ // Map from process states to the states we track.
+ private static final int[] PROCESS_STATE_TO_STATE = new int[] {
+ STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
+ STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+ STATE_TOP, // ActivityManager.PROCESS_STATE_TOP
+ STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+ STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+ STATE_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+ STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+ STATE_BACKUP, // ActivityManager.PROCESS_STATE_BACKUP
+ STATE_HEAVY_WEIGHT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+ STATE_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
+ STATE_RECEIVER, // ActivityManager.PROCESS_STATE_RECEIVER
+ STATE_HOME, // ActivityManager.PROCESS_STATE_HOME
+ STATE_LAST_ACTIVITY, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+ STATE_CACHED_ACTIVITY, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+ STATE_CACHED_ACTIVITY_CLIENT, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+ STATE_CACHED_EMPTY, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+ };
+
+ public static final Comparator<ProcessState> COMPARATOR = new Comparator<ProcessState>() {
+ @Override
+ public int compare(ProcessState lhs, ProcessState rhs) {
+ if (lhs.mTmpTotalTime < rhs.mTmpTotalTime) {
+ return -1;
+ } else if (lhs.mTmpTotalTime > rhs.mTmpTotalTime) {
+ return 1;
+ }
+ return 0;
+ }
+ };
+
+ static class PssAggr {
+ long pss = 0;
+ long samples = 0;
+
+ void add(long newPss, long newSamples) {
+ pss = (long)( (pss*(double)samples) + (newPss*(double)newSamples) )
+ / (samples+newSamples);
+ samples += newSamples;
+ }
+ }
+
+ // Used by reset to count rather than storing extra maps. Be careful.
+ public int tmpNumInUse;
+ public ProcessState tmpFoundSubProc;
+
+ private final ProcessStats mStats;
+ private final String mName;
+ private final String mPackage;
+ private final int mUid;
+ private final int mVersion;
+ private final DurationsTable mDurations;
+ private final PssTable mPssTable;
+
+ private ProcessState mCommonProcess;
+ private int mCurState = STATE_NOTHING;
+ private long mStartTime;
+
+ private int mLastPssState = STATE_NOTHING;
+ private long mLastPssTime;
+
+ private boolean mActive;
+ private int mNumActiveServices;
+ private int mNumStartedServices;
+
+ private int mNumExcessiveWake;
+ private int mNumExcessiveCpu;
+
+ private int mNumCachedKill;
+ private long mMinCachedKillPss;
+ private long mAvgCachedKillPss;
+ private long mMaxCachedKillPss;
+
+ private boolean mMultiPackage;
+ private boolean mDead;
+
+ // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful.
+ private long mTmpTotalTime;
+
+ /**
+ * Create a new top-level process state, for the initial case where there is only
+ * a single package running in a process. The initial state is not running.
+ */
+ public ProcessState(ProcessStats processStats, String pkg, int uid, int vers, String name) {
+ mStats = processStats;
+ mName = name;
+ mCommonProcess = this;
+ mPackage = pkg;
+ mUid = uid;
+ mVersion = vers;
+ mDurations = new DurationsTable(processStats.mTableData);
+ mPssTable = new PssTable(processStats.mTableData);
+ }
+
+ /**
+ * Create a new per-package process state for an existing top-level process
+ * state. The current running state of the top-level process is also copied,
+ * marked as started running at 'now'.
+ */
+ public ProcessState(ProcessState commonProcess, String pkg, int uid, int vers, String name,
+ long now) {
+ mStats = commonProcess.mStats;
+ mName = name;
+ mCommonProcess = commonProcess;
+ mPackage = pkg;
+ mUid = uid;
+ mVersion = vers;
+ mCurState = commonProcess.mCurState;
+ mStartTime = now;
+ mDurations = new DurationsTable(commonProcess.mStats.mTableData);
+ mPssTable = new PssTable(commonProcess.mStats.mTableData);
+ }
+
+ public ProcessState clone(long now) {
+ ProcessState pnew = new ProcessState(this, mPackage, mUid, mVersion, mName, now);
+ pnew.mDurations.addDurations(mDurations);
+ pnew.mPssTable.copyFrom(mPssTable, PSS_COUNT);
+ pnew.mNumExcessiveWake = mNumExcessiveWake;
+ pnew.mNumExcessiveCpu = mNumExcessiveCpu;
+ pnew.mNumCachedKill = mNumCachedKill;
+ pnew.mMinCachedKillPss = mMinCachedKillPss;
+ pnew.mAvgCachedKillPss = mAvgCachedKillPss;
+ pnew.mMaxCachedKillPss = mMaxCachedKillPss;
+ pnew.mActive = mActive;
+ pnew.mNumActiveServices = mNumActiveServices;
+ pnew.mNumStartedServices = mNumStartedServices;
+ return pnew;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public ProcessState getCommonProcess() {
+ return mCommonProcess;
+ }
+
+ /**
+ * Say that we are not part of a shared process, so mCommonProcess = this.
+ */
+ public void makeStandalone() {
+ mCommonProcess = this;
+ }
+
+ public String getPackage() {
+ return mPackage;
+ }
+
+ public int getUid() {
+ return mUid;
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public boolean isMultiPackage() {
+ return mMultiPackage;
+ }
+
+ public void setMultiPackage(boolean val) {
+ mMultiPackage = val;
+ }
+
+ public int getDurationsBucketCount() {
+ return mDurations.getKeyCount();
+ }
+
+ public void add(ProcessState other) {
+ mDurations.addDurations(other.mDurations);
+ mPssTable.mergeStats(other.mPssTable);
+ mNumExcessiveWake += other.mNumExcessiveWake;
+ mNumExcessiveCpu += other.mNumExcessiveCpu;
+ if (other.mNumCachedKill > 0) {
+ addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
+ other.mAvgCachedKillPss, other.mMaxCachedKillPss);
+ }
+ }
+
+ public void resetSafely(long now) {
+ mDurations.resetTable();
+ mPssTable.resetTable();
+ mStartTime = now;
+ mLastPssState = STATE_NOTHING;
+ mLastPssTime = 0;
+ mNumExcessiveWake = 0;
+ mNumExcessiveCpu = 0;
+ mNumCachedKill = 0;
+ mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
+ }
+
+ public void makeDead() {
+ mDead = true;
+ }
+
+ private void ensureNotDead() {
+ if (!mDead) {
+ return;
+ }
+ Slog.wtfStack(TAG, "ProcessState dead: name=" + mName
+ + " pkg=" + mPackage + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
+ }
+
+ public void writeToParcel(Parcel out, long now) {
+ out.writeInt(mMultiPackage ? 1 : 0);
+ mDurations.writeToParcel(out);
+ mPssTable.writeToParcel(out);
+ out.writeInt(mNumExcessiveWake);
+ out.writeInt(mNumExcessiveCpu);
+ out.writeInt(mNumCachedKill);
+ if (mNumCachedKill > 0) {
+ out.writeLong(mMinCachedKillPss);
+ out.writeLong(mAvgCachedKillPss);
+ out.writeLong(mMaxCachedKillPss);
+ }
+ }
+
+ public boolean readFromParcel(Parcel in, boolean fully) {
+ boolean multiPackage = in.readInt() != 0;
+ if (fully) {
+ mMultiPackage = multiPackage;
+ }
+ if (DEBUG_PARCEL) Slog.d(TAG, "Reading durations table...");
+ if (!mDurations.readFromParcel(in)) {
+ return false;
+ }
+ if (DEBUG_PARCEL) Slog.d(TAG, "Reading pss table...");
+ if (!mPssTable.readFromParcel(in)) {
+ return false;
+ }
+ mNumExcessiveWake = in.readInt();
+ mNumExcessiveCpu = in.readInt();
+ mNumCachedKill = in.readInt();
+ if (mNumCachedKill > 0) {
+ mMinCachedKillPss = in.readLong();
+ mAvgCachedKillPss = in.readLong();
+ mMaxCachedKillPss = in.readLong();
+ } else {
+ mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
+ }
+ return true;
+ }
+
+ public void makeActive() {
+ ensureNotDead();
+ mActive = true;
+ }
+
+ public void makeInactive() {
+ mActive = false;
+ }
+
+ public boolean isInUse() {
+ return mActive || mNumActiveServices > 0 || mNumStartedServices > 0
+ || mCurState != STATE_NOTHING;
+ }
+
+ public boolean isActive() {
+ return mActive;
+ }
+
+ public boolean hasAnyData() {
+ return !(mDurations.getKeyCount() == 0
+ && mCurState == STATE_NOTHING
+ && mPssTable.getKeyCount() == 0);
+ }
+
+ /**
+ * Update the current state of the given list of processes.
+ *
+ * @param state Current ActivityManager.PROCESS_STATE_*
+ * @param memFactor Current mem factor constant.
+ * @param now Current time.
+ * @param pkgList Processes to update.
+ */
+ public void setState(int state, int memFactor, long now,
+ ArrayMap<String, ProcessStateHolder> pkgList) {
+ if (state < 0) {
+ state = mNumStartedServices > 0
+ ? (STATE_SERVICE_RESTARTING+(memFactor*STATE_COUNT)) : STATE_NOTHING;
+ } else {
+ state = PROCESS_STATE_TO_STATE[state] + (memFactor*STATE_COUNT);
+ }
+
+ // First update the common process.
+ mCommonProcess.setState(state, now);
+
+ // If the common process is not multi-package, there is nothing else to do.
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ if (pkgList != null) {
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).setState(state, now);
+ }
+ }
+ }
+
+ public void setState(int state, long now) {
+ ensureNotDead();
+ if (mCurState != state) {
+ //Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
+ commitStateTime(now);
+ mCurState = state;
+ }
+ }
+
+ public void commitStateTime(long now) {
+ if (mCurState != STATE_NOTHING) {
+ long dur = now - mStartTime;
+ if (dur > 0) {
+ mDurations.addDuration(mCurState, dur);
+ }
+ }
+ mStartTime = now;
+ }
+
+ public void incActiveServices(String serviceName) {
+ if (DEBUG && "".equals(mName)) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "incActiveServices: " + this + " service=" + serviceName
+ + " to " + (mNumActiveServices+1), here);
+ }
+ if (mCommonProcess != this) {
+ mCommonProcess.incActiveServices(serviceName);
+ }
+ mNumActiveServices++;
+ }
+
+ public void decActiveServices(String serviceName) {
+ if (DEBUG && "".equals(mName)) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
+ + " to " + (mNumActiveServices-1), here);
+ }
+ if (mCommonProcess != this) {
+ mCommonProcess.decActiveServices(serviceName);
+ }
+ mNumActiveServices--;
+ if (mNumActiveServices < 0) {
+ Slog.wtfStack(TAG, "Proc active services underrun: pkg=" + mPackage
+ + " uid=" + mUid + " proc=" + mName + " service=" + serviceName);
+ mNumActiveServices = 0;
+ }
+ }
+
+ public void incStartedServices(int memFactor, long now, String serviceName) {
+ if (false) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName
+ + " to " + (mNumStartedServices+1), here);
+ }
+ if (mCommonProcess != this) {
+ mCommonProcess.incStartedServices(memFactor, now, serviceName);
+ }
+ mNumStartedServices++;
+ if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
+ setState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
+ }
+ }
+
+ public void decStartedServices(int memFactor, long now, String serviceName) {
+ if (false) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
+ + " to " + (mNumStartedServices-1), here);
+ }
+ if (mCommonProcess != this) {
+ mCommonProcess.decStartedServices(memFactor, now, serviceName);
+ }
+ mNumStartedServices--;
+ if (mNumStartedServices == 0 && (mCurState%STATE_COUNT) == STATE_SERVICE_RESTARTING) {
+ setState(STATE_NOTHING, now);
+ } else if (mNumStartedServices < 0) {
+ Slog.wtfStack(TAG, "Proc started services underrun: pkg="
+ + mPackage + " uid=" + mUid + " name=" + mName);
+ mNumStartedServices = 0;
+ }
+ }
+
+ public void addPss(long pss, long uss, boolean always,
+ ArrayMap<String, ProcessStateHolder> pkgList) {
+ ensureNotDead();
+ if (!always) {
+ if (mLastPssState == mCurState && SystemClock.uptimeMillis()
+ < (mLastPssTime+(30*1000))) {
+ return;
+ }
+ }
+ mLastPssState = mCurState;
+ mLastPssTime = SystemClock.uptimeMillis();
+ if (mCurState != STATE_NOTHING) {
+ // First update the common process.
+ mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss);
+
+ // If the common process is not multi-package, there is nothing else to do.
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ if (pkgList != null) {
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurState, 1,
+ pss, pss, pss, uss, uss, uss);
+ }
+ }
+ }
+ }
+
+ public void reportExcessiveWake(ArrayMap<String, ProcessStateHolder> pkgList) {
+ ensureNotDead();
+ mCommonProcess.mNumExcessiveWake++;
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).mNumExcessiveWake++;
+ }
+ }
+
+ public void reportExcessiveCpu(ArrayMap<String, ProcessStateHolder> pkgList) {
+ ensureNotDead();
+ mCommonProcess.mNumExcessiveCpu++;
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).mNumExcessiveCpu++;
+ }
+ }
+
+ private void addCachedKill(int num, long minPss, long avgPss, long maxPss) {
+ if (mNumCachedKill <= 0) {
+ mNumCachedKill = num;
+ mMinCachedKillPss = minPss;
+ mAvgCachedKillPss = avgPss;
+ mMaxCachedKillPss = maxPss;
+ } else {
+ if (minPss < mMinCachedKillPss) {
+ mMinCachedKillPss = minPss;
+ }
+ if (maxPss > mMaxCachedKillPss) {
+ mMaxCachedKillPss = maxPss;
+ }
+ mAvgCachedKillPss = (long)( ((mAvgCachedKillPss*(double)mNumCachedKill) + avgPss)
+ / (mNumCachedKill+num) );
+ mNumCachedKill += num;
+ }
+ }
+
+ public void reportCachedKill(ArrayMap<String, ProcessStateHolder> pkgList, long pss) {
+ ensureNotDead();
+ mCommonProcess.addCachedKill(1, pss, pss, pss);
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).addCachedKill(1, pss, pss, pss);
+ }
+ }
+
+ public ProcessState pullFixedProc(String pkgName) {
+ if (mMultiPackage) {
+ // The array map is still pointing to a common process state
+ // that is now shared across packages. Update it to point to
+ // the new per-package state.
+ SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgName, mUid);
+ if (vpkg == null) {
+ throw new IllegalStateException("Didn't find package " + pkgName
+ + " / " + mUid);
+ }
+ PackageState pkg = vpkg.get(mVersion);
+ if (pkg == null) {
+ throw new IllegalStateException("Didn't find package " + pkgName
+ + " / " + mUid + " vers " + mVersion);
+ }
+ ProcessState proc = pkg.mProcesses.get(mName);
+ if (proc == null) {
+ throw new IllegalStateException("Didn't create per-package process "
+ + mName + " in pkg " + pkgName + " / " + mUid + " vers " + mVersion);
+ }
+ return proc;
+ }
+ return this;
+ }
+
+ private ProcessState pullFixedProc(ArrayMap<String, ProcessStateHolder> pkgList,
+ int index) {
+ ProcessStateHolder holder = pkgList.valueAt(index);
+ ProcessState proc = holder.state;
+ if (mDead && proc.mCommonProcess != proc) {
+ // Somehow we are contining to use a process state that is dead, because
+ // it was not being told it was active during the last commit. We can recover
+ // from this by generating a fresh new state, but this is bad because we
+ // are losing whatever data we had in the old process state.
+ Log.wtf(TAG, "Pulling dead proc: name=" + mName + " pkg=" + mPackage
+ + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
+ proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mVersion,
+ proc.mName);
+ }
+ if (proc.mMultiPackage) {
+ // The array map is still pointing to a common process state
+ // that is now shared across packages. Update it to point to
+ // the new per-package state.
+ SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgList.keyAt(index),
+ proc.mUid);
+ if (vpkg == null) {
+ throw new IllegalStateException("No existing package "
+ + pkgList.keyAt(index) + "/" + proc.mUid
+ + " for multi-proc " + proc.mName);
+ }
+ PackageState pkg = vpkg.get(proc.mVersion);
+ if (pkg == null) {
+ throw new IllegalStateException("No existing package "
+ + pkgList.keyAt(index) + "/" + proc.mUid
+ + " for multi-proc " + proc.mName + " version " + proc.mVersion);
+ }
+ String savedName = proc.mName;
+ proc = pkg.mProcesses.get(proc.mName);
+ if (proc == null) {
+ throw new IllegalStateException("Didn't create per-package process "
+ + savedName + " in pkg " + pkg.mPackageName + "/" + pkg.mUid);
+ }
+ holder.state = proc;
+ }
+ return proc;
+ }
+
+ public long getDuration(int state, long now) {
+ long time = mDurations.getValueForId((byte)state);
+ if (mCurState == state) {
+ time += now - mStartTime;
+ }
+ return time;
+ }
+
+ public long getPssSampleCount(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_SAMPLE_COUNT);
+ }
+
+ public long getPssMinimum(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_MINIMUM);
+ }
+
+ public long getPssAverage(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_AVERAGE);
+ }
+
+ public long getPssMaximum(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_MAXIMUM);
+ }
+
+ public long getPssUssMinimum(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_USS_MINIMUM);
+ }
+
+ public long getPssUssAverage(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_USS_AVERAGE);
+ }
+
+ public long getPssUssMaximum(int state) {
+ return mPssTable.getValueForId((byte)state, PSS_USS_MAXIMUM);
+ }
+
+ /**
+ * Sums up the PSS data and adds it to 'data'.
+ *
+ * @param data The aggregate data is added here.
+ * @param now SystemClock.uptimeMillis()
+ */
+ public void aggregatePss(TotalMemoryUseCollection data, long now) {
+ final PssAggr fgPss = new PssAggr();
+ final PssAggr bgPss = new PssAggr();
+ final PssAggr cachedPss = new PssAggr();
+ boolean havePss = false;
+ for (int i=0; i<mDurations.getKeyCount(); i++) {
+ final int key = mDurations.getKeyAt(i);
+ int type = SparseMappingTable.getIdFromKey(key);
+ int procState = type % STATE_COUNT;
+ long samples = getPssSampleCount(type);
+ if (samples > 0) {
+ long avg = getPssAverage(type);
+ havePss = true;
+ if (procState <= STATE_IMPORTANT_FOREGROUND) {
+ fgPss.add(avg, samples);
+ } else if (procState <= STATE_RECEIVER) {
+ bgPss.add(avg, samples);
+ } else {
+ cachedPss.add(avg, samples);
+ }
+ }
+ }
+ if (!havePss) {
+ return;
+ }
+ boolean fgHasBg = false;
+ boolean fgHasCached = false;
+ boolean bgHasCached = false;
+ if (fgPss.samples < 3 && bgPss.samples > 0) {
+ fgHasBg = true;
+ fgPss.add(bgPss.pss, bgPss.samples);
+ }
+ if (fgPss.samples < 3 && cachedPss.samples > 0) {
+ fgHasCached = true;
+ fgPss.add(cachedPss.pss, cachedPss.samples);
+ }
+ if (bgPss.samples < 3 && cachedPss.samples > 0) {
+ bgHasCached = true;
+ bgPss.add(cachedPss.pss, cachedPss.samples);
+ }
+ if (bgPss.samples < 3 && !fgHasBg && fgPss.samples > 0) {
+ bgPss.add(fgPss.pss, fgPss.samples);
+ }
+ if (cachedPss.samples < 3 && !bgHasCached && bgPss.samples > 0) {
+ cachedPss.add(bgPss.pss, bgPss.samples);
+ }
+ if (cachedPss.samples < 3 && !fgHasCached && fgPss.samples > 0) {
+ cachedPss.add(fgPss.pss, fgPss.samples);
+ }
+ for (int i=0; i<mDurations.getKeyCount(); i++) {
+ final int key = mDurations.getKeyAt(i);
+ final int type = SparseMappingTable.getIdFromKey(key);
+ long time = mDurations.getValue(key);
+ if (mCurState == type) {
+ time += now - mStartTime;
+ }
+ final int procState = type % STATE_COUNT;
+ data.processStateTime[procState] += time;
+ long samples = getPssSampleCount(type);
+ long avg;
+ if (samples > 0) {
+ avg = getPssAverage(type);
+ } else if (procState <= STATE_IMPORTANT_FOREGROUND) {
+ samples = fgPss.samples;
+ avg = fgPss.pss;
+ } else if (procState <= STATE_RECEIVER) {
+ samples = bgPss.samples;
+ avg = bgPss.pss;
+ } else {
+ samples = cachedPss.samples;
+ avg = cachedPss.pss;
+ }
+ double newAvg = ( (data.processStatePss[procState]
+ * (double)data.processStateSamples[procState])
+ + (avg*(double)samples)
+ ) / (data.processStateSamples[procState]+samples);
+ data.processStatePss[procState] = (long)newAvg;
+ data.processStateSamples[procState] += samples;
+ data.processStateWeight[procState] += avg * (double)time;
+ }
+ }
+
+ public long computeProcessTimeLocked(int[] screenStates, int[] memStates,
+ int[] procStates, long now) {
+ long totalTime = 0;
+ for (int is=0; is<screenStates.length; is++) {
+ for (int im=0; im<memStates.length; im++) {
+ for (int ip=0; ip<procStates.length; ip++) {
+ int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
+ + procStates[ip];
+ totalTime += getDuration(bucket, now);
+ }
+ }
+ }
+ mTmpTotalTime = totalTime;
+ return totalTime;
+ }
+
+ public void dumpSummary(PrintWriter pw, String prefix,
+ int[] screenStates, int[] memStates, int[] procStates,
+ long now, long totalTime) {
+ pw.print(prefix);
+ pw.print("* ");
+ pw.print(mName);
+ pw.print(" / ");
+ UserHandle.formatUid(pw, mUid);
+ pw.print(" / v");
+ pw.print(mVersion);
+ pw.println(":");
+ dumpProcessSummaryDetails(pw, prefix, " TOTAL: ", screenStates, memStates,
+ procStates, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Persistent: ", screenStates, memStates,
+ new int[] { STATE_PERSISTENT }, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Top: ", screenStates, memStates,
+ new int[] {STATE_TOP}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Imp Fg: ", screenStates, memStates,
+ new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Imp Bg: ", screenStates, memStates,
+ new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Backup: ", screenStates, memStates,
+ new int[] {STATE_BACKUP}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Heavy Wgt: ", screenStates, memStates,
+ new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Service: ", screenStates, memStates,
+ new int[] {STATE_SERVICE}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Service Rs: ", screenStates, memStates,
+ new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " Receiver: ", screenStates, memStates,
+ new int[] {STATE_RECEIVER}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " (Home): ", screenStates, memStates,
+ new int[] {STATE_HOME}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " (Last Act): ", screenStates, memStates,
+ new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, " (Cached): ", screenStates, memStates,
+ new int[] {STATE_CACHED_ACTIVITY, STATE_CACHED_ACTIVITY_CLIENT,
+ STATE_CACHED_EMPTY}, now, totalTime, true);
+ }
+
+ public void dumpProcessState(PrintWriter pw, String prefix,
+ int[] screenStates, int[] memStates, int[] procStates, long now) {
+ long totalTime = 0;
+ int printedScreen = -1;
+ for (int is=0; is<screenStates.length; is++) {
+ int printedMem = -1;
+ for (int im=0; im<memStates.length; im++) {
+ for (int ip=0; ip<procStates.length; ip++) {
+ final int iscreen = screenStates[is];
+ final int imem = memStates[im];
+ final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
+ long time = mDurations.getValueForId((byte)bucket);
+ String running = "";
+ if (mCurState == bucket) {
+ running = " (running)";
+ }
+ if (time != 0) {
+ pw.print(prefix);
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw,
+ printedMem != imem ? imem : STATE_NOTHING, '/');
+ printedMem = imem;
+ }
+ pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
+ TimeUtils.formatDuration(time, pw); pw.println(running);
+ totalTime += time;
+ }
+ }
+ }
+ }
+ if (totalTime != 0) {
+ pw.print(prefix);
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw, STATE_NOTHING);
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw, STATE_NOTHING, '/');
+ }
+ pw.print("TOTAL : ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
+ }
+
+ public void dumpPss(PrintWriter pw, String prefix,
+ int[] screenStates, int[] memStates, int[] procStates) {
+ boolean printedHeader = false;
+ int printedScreen = -1;
+ for (int is=0; is<screenStates.length; is++) {
+ int printedMem = -1;
+ for (int im=0; im<memStates.length; im++) {
+ for (int ip=0; ip<procStates.length; ip++) {
+ final int iscreen = screenStates[is];
+ final int imem = memStates[im];
+ final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
+ long count = getPssSampleCount(bucket);
+ if (count > 0) {
+ if (!printedHeader) {
+ pw.print(prefix);
+ pw.print("PSS/USS (");
+ pw.print(mPssTable.getKeyCount());
+ pw.println(" entries):");
+ printedHeader = true;
+ }
+ pw.print(prefix);
+ pw.print(" ");
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw,
+ printedScreen != iscreen ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw,
+ printedMem != imem ? imem : STATE_NOTHING, '/');
+ printedMem = imem;
+ }
+ pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
+ pw.print(count);
+ pw.print(" samples ");
+ DebugUtils.printSizeValue(pw, getPssMinimum(bucket) * 1024);
+ pw.print(" ");
+ DebugUtils.printSizeValue(pw, getPssAverage(bucket) * 1024);
+ pw.print(" ");
+ DebugUtils.printSizeValue(pw, getPssMaximum(bucket) * 1024);
+ pw.print(" / ");
+ DebugUtils.printSizeValue(pw, getPssUssMinimum(bucket) * 1024);
+ pw.print(" ");
+ DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024);
+ pw.print(" ");
+ DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024);
+ pw.println();
+ }
+ }
+ }
+ }
+ if (mNumExcessiveWake != 0) {
+ pw.print(prefix); pw.print("Killed for excessive wake locks: ");
+ pw.print(mNumExcessiveWake); pw.println(" times");
+ }
+ if (mNumExcessiveCpu != 0) {
+ pw.print(prefix); pw.print("Killed for excessive CPU use: ");
+ pw.print(mNumExcessiveCpu); pw.println(" times");
+ }
+ if (mNumCachedKill != 0) {
+ pw.print(prefix); pw.print("Killed from cached state: ");
+ pw.print(mNumCachedKill); pw.print(" times from pss ");
+ DebugUtils.printSizeValue(pw, mMinCachedKillPss * 1024); pw.print("-");
+ DebugUtils.printSizeValue(pw, mAvgCachedKillPss * 1024); pw.print("-");
+ DebugUtils.printSizeValue(pw, mMaxCachedKillPss * 1024); pw.println();
+ }
+ }
+
+ private void dumpProcessSummaryDetails(PrintWriter pw, String prefix,
+ String label, int[] screenStates, int[] memStates, int[] procStates,
+ long now, long totalTime, boolean full) {
+ ProcessStats.ProcessDataCollection totals = new ProcessStats.ProcessDataCollection(
+ screenStates, memStates, procStates);
+ computeProcessData(totals, now);
+ final double percentage = (double) totals.totalTime / (double) totalTime * 100;
+ // We don't print percentages < .01, so just drop those.
+ if (percentage >= 0.005 || totals.numPss != 0) {
+ if (prefix != null) {
+ pw.print(prefix);
+ }
+ if (label != null) {
+ pw.print(label);
+ }
+ totals.print(pw, totalTime, full);
+ if (prefix != null) {
+ pw.println();
+ }
+ }
+ }
+
+ public void dumpInternalLocked(PrintWriter pw, String prefix, boolean dumpAll) {
+ if (dumpAll) {
+ pw.print(prefix); pw.print("myID=");
+ pw.print(Integer.toHexString(System.identityHashCode(this)));
+ pw.print(" mCommonProcess=");
+ pw.print(Integer.toHexString(System.identityHashCode(mCommonProcess)));
+ pw.print(" mPackage="); pw.println(mPackage);
+ if (mMultiPackage) {
+ pw.print(prefix); pw.print("mMultiPackage="); pw.println(mMultiPackage);
+ }
+ if (this != mCommonProcess) {
+ pw.print(prefix); pw.print("Common Proc: "); pw.print(mCommonProcess.mName);
+ pw.print("/"); pw.print(mCommonProcess.mUid);
+ pw.print(" pkg="); pw.println(mCommonProcess.mPackage);
+ }
+ }
+ if (mActive) {
+ pw.print(prefix); pw.print("mActive="); pw.println(mActive);
+ }
+ if (mDead) {
+ pw.print(prefix); pw.print("mDead="); pw.println(mDead);
+ }
+ if (mNumActiveServices != 0 || mNumStartedServices != 0) {
+ pw.print(prefix); pw.print("mNumActiveServices="); pw.print(mNumActiveServices);
+ pw.print(" mNumStartedServices=");
+ pw.println(mNumStartedServices);
+ }
+ }
+
+ public void computeProcessData(ProcessStats.ProcessDataCollection data, long now) {
+ data.totalTime = 0;
+ data.numPss = data.minPss = data.avgPss = data.maxPss =
+ data.minUss = data.avgUss = data.maxUss = 0;
+ for (int is=0; is<data.screenStates.length; is++) {
+ for (int im=0; im<data.memStates.length; im++) {
+ for (int ip=0; ip<data.procStates.length; ip++) {
+ int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
+ + data.procStates[ip];
+ data.totalTime += getDuration(bucket, now);
+ long samples = getPssSampleCount(bucket);
+ if (samples > 0) {
+ long minPss = getPssMinimum(bucket);
+ long avgPss = getPssAverage(bucket);
+ long maxPss = getPssMaximum(bucket);
+ long minUss = getPssUssMinimum(bucket);
+ long avgUss = getPssUssAverage(bucket);
+ long maxUss = getPssUssMaximum(bucket);
+ if (data.numPss == 0) {
+ data.minPss = minPss;
+ data.avgPss = avgPss;
+ data.maxPss = maxPss;
+ data.minUss = minUss;
+ data.avgUss = avgUss;
+ data.maxUss = maxUss;
+ } else {
+ if (minPss < data.minPss) {
+ data.minPss = minPss;
+ }
+ data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
+ + (avgPss*(double)samples)) / (data.numPss+samples) );
+ if (maxPss > data.maxPss) {
+ data.maxPss = maxPss;
+ }
+ if (minUss < data.minUss) {
+ data.minUss = minUss;
+ }
+ data.avgUss = (long)( ((data.avgUss*(double)data.numPss)
+ + (avgUss*(double)samples)) / (data.numPss+samples) );
+ if (maxUss > data.maxUss) {
+ data.maxUss = maxUss;
+ }
+ }
+ data.numPss += samples;
+ }
+ }
+ }
+ }
+ }
+
+ public void dumpCsv(PrintWriter pw,
+ boolean sepScreenStates, int[] screenStates, boolean sepMemStates,
+ int[] memStates, boolean sepProcStates, int[] procStates, long now) {
+ final int NSS = sepScreenStates ? screenStates.length : 1;
+ final int NMS = sepMemStates ? memStates.length : 1;
+ final int NPS = sepProcStates ? procStates.length : 1;
+ for (int iss=0; iss<NSS; iss++) {
+ for (int ims=0; ims<NMS; ims++) {
+ for (int ips=0; ips<NPS; ips++) {
+ final int vsscreen = sepScreenStates ? screenStates[iss] : 0;
+ final int vsmem = sepMemStates ? memStates[ims] : 0;
+ final int vsproc = sepProcStates ? procStates[ips] : 0;
+ final int NSA = sepScreenStates ? 1 : screenStates.length;
+ final int NMA = sepMemStates ? 1 : memStates.length;
+ final int NPA = sepProcStates ? 1 : procStates.length;
+ long totalTime = 0;
+ for (int isa=0; isa<NSA; isa++) {
+ for (int ima=0; ima<NMA; ima++) {
+ for (int ipa=0; ipa<NPA; ipa++) {
+ final int vascreen = sepScreenStates ? 0 : screenStates[isa];
+ final int vamem = sepMemStates ? 0 : memStates[ima];
+ final int vaproc = sepProcStates ? 0 : procStates[ipa];
+ final int bucket = ((vsscreen + vascreen + vsmem + vamem)
+ * STATE_COUNT) + vsproc + vaproc;
+ totalTime += getDuration(bucket, now);
+ }
+ }
+ }
+ pw.print(DumpUtils.CSV_SEP);
+ pw.print(totalTime);
+ }
+ }
+ }
+ }
+
+ public void dumpPackageProcCheckin(PrintWriter pw, String pkgName, int uid, int vers,
+ String itemName, long now) {
+ pw.print("pkgproc,");
+ pw.print(pkgName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(DumpUtils.collapseString(pkgName, itemName));
+ dumpAllStateCheckin(pw, now);
+ pw.println();
+ if (mPssTable.getKeyCount() > 0) {
+ pw.print("pkgpss,");
+ pw.print(pkgName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(DumpUtils.collapseString(pkgName, itemName));
+ dumpAllPssCheckin(pw);
+ pw.println();
+ }
+ if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
+ pw.print("pkgkills,");
+ pw.print(pkgName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(DumpUtils.collapseString(pkgName, itemName));
+ pw.print(",");
+ pw.print(mNumExcessiveWake);
+ pw.print(",");
+ pw.print(mNumExcessiveCpu);
+ pw.print(",");
+ pw.print(mNumCachedKill);
+ pw.print(",");
+ pw.print(mMinCachedKillPss);
+ pw.print(":");
+ pw.print(mAvgCachedKillPss);
+ pw.print(":");
+ pw.print(mMaxCachedKillPss);
+ pw.println();
+ }
+ }
+
+ public void dumpProcCheckin(PrintWriter pw, String procName, int uid, long now) {
+ if (mDurations.getKeyCount() > 0) {
+ pw.print("proc,");
+ pw.print(procName);
+ pw.print(",");
+ pw.print(uid);
+ dumpAllStateCheckin(pw, now);
+ pw.println();
+ }
+ if (mPssTable.getKeyCount() > 0) {
+ pw.print("pss,");
+ pw.print(procName);
+ pw.print(",");
+ pw.print(uid);
+ dumpAllPssCheckin(pw);
+ pw.println();
+ }
+ if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
+ pw.print("kills,");
+ pw.print(procName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(mNumExcessiveWake);
+ pw.print(",");
+ pw.print(mNumExcessiveCpu);
+ pw.print(",");
+ pw.print(mNumCachedKill);
+ pw.print(",");
+ pw.print(mMinCachedKillPss);
+ pw.print(":");
+ pw.print(mAvgCachedKillPss);
+ pw.print(":");
+ pw.print(mMaxCachedKillPss);
+ pw.println();
+ }
+ }
+
+ public void dumpAllStateCheckin(PrintWriter pw, long now) {
+ boolean didCurState = false;
+ for (int i=0; i<mDurations.getKeyCount(); i++) {
+ final int key = mDurations.getKeyAt(i);
+ final int type = SparseMappingTable.getIdFromKey(key);
+ long time = mDurations.getValue(key);
+ if (mCurState == type) {
+ didCurState = true;
+ time += now - mStartTime;
+ }
+ DumpUtils.printProcStateTagAndValue(pw, type, time);
+ }
+ if (!didCurState && mCurState != STATE_NOTHING) {
+ DumpUtils.printProcStateTagAndValue(pw, mCurState, now - mStartTime);
+ }
+ }
+
+ public void dumpAllPssCheckin(PrintWriter pw) {
+ final int N = mPssTable.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = mPssTable.getKeyAt(i);
+ final int type = SparseMappingTable.getIdFromKey(key);
+ pw.print(',');
+ DumpUtils.printProcStateTag(pw, type);
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_SAMPLE_COUNT));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_MINIMUM));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_AVERAGE));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_MAXIMUM));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_USS_MINIMUM));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE));
+ pw.print(':');
+ pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM));
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("ProcessState{").append(Integer.toHexString(System.identityHashCode(this)))
+ .append(" ").append(mName).append("/").append(mUid)
+ .append(" pkg=").append(mPackage);
+ if (mMultiPackage) sb.append(" (multi)");
+ if (mCommonProcess != this) sb.append(" (sub)");
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/core/java/com/android/internal/app/ProcessStats.aidl b/core/java/com/android/internal/app/procstats/ProcessStats.aidl
similarity index 93%
rename from core/java/com/android/internal/app/ProcessStats.aidl
rename to core/java/com/android/internal/app/procstats/ProcessStats.aidl
index 48b1f85..33639a0 100644
--- a/core/java/com/android/internal/app/ProcessStats.aidl
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.aidl
@@ -14,6 +14,6 @@
** limitations under the License.
*/
-package com.android.internal.app;
+package com.android.internal.app.procstats;
parcelable ProcessStats;
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
new file mode 100644
index 0000000..06542f7
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -0,0 +1,1621 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.format.DateFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+
+import com.android.internal.app.ProcessMap;
+import com.android.internal.app.procstats.DurationsTable;
+import com.android.internal.app.procstats.ProcessState;
+import com.android.internal.app.procstats.PssTable;
+import com.android.internal.app.procstats.ServiceState;
+import com.android.internal.app.procstats.SparseMappingTable;
+import com.android.internal.app.procstats.SysMemUsageTable;
+import com.android.internal.app.procstats.DumpUtils.*;
+
+import dalvik.system.VMRuntime;
+import libcore.util.EmptyArray;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+
+public final class ProcessStats implements Parcelable {
+ public static final String TAG = "ProcessStats";
+ static final boolean DEBUG = false;
+ static final boolean DEBUG_PARCEL = false;
+
+ public static final String SERVICE_NAME = "procstats";
+
+ // How often the service commits its data, giving the minimum batching
+ // that is done.
+ public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours
+
+ // Minimum uptime period before committing. If the COMMIT_PERIOD has elapsed but
+ // the total uptime has not exceeded this amount, then the commit will be held until
+ // it is reached.
+ public static long COMMIT_UPTIME_PERIOD = 60*60*1000; // Must have at least 1 hour elapsed
+
+ public static final int STATE_NOTHING = -1;
+ public static final int STATE_PERSISTENT = 0;
+ public static final int STATE_TOP = 1;
+ public static final int STATE_IMPORTANT_FOREGROUND = 2;
+ public static final int STATE_IMPORTANT_BACKGROUND = 3;
+ public static final int STATE_BACKUP = 4;
+ public static final int STATE_HEAVY_WEIGHT = 5;
+ public static final int STATE_SERVICE = 6;
+ public static final int STATE_SERVICE_RESTARTING = 7;
+ public static final int STATE_RECEIVER = 8;
+ public static final int STATE_HOME = 9;
+ public static final int STATE_LAST_ACTIVITY = 10;
+ public static final int STATE_CACHED_ACTIVITY = 11;
+ public static final int STATE_CACHED_ACTIVITY_CLIENT = 12;
+ public static final int STATE_CACHED_EMPTY = 13;
+ public static final int STATE_COUNT = STATE_CACHED_EMPTY+1;
+
+ public static final int PSS_SAMPLE_COUNT = 0;
+ public static final int PSS_MINIMUM = 1;
+ public static final int PSS_AVERAGE = 2;
+ public static final int PSS_MAXIMUM = 3;
+ public static final int PSS_USS_MINIMUM = 4;
+ public static final int PSS_USS_AVERAGE = 5;
+ public static final int PSS_USS_MAXIMUM = 6;
+ public static final int PSS_COUNT = PSS_USS_MAXIMUM+1;
+
+ public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0;
+ public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1;
+ public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2;
+ public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3;
+ public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4;
+ public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5;
+ public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6;
+ public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7;
+ public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8;
+ public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9;
+ public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10;
+ public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11;
+ public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12;
+ public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13;
+ public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14;
+ public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15;
+ public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1;
+
+ public static final int ADJ_NOTHING = -1;
+ public static final int ADJ_MEM_FACTOR_NORMAL = 0;
+ public static final int ADJ_MEM_FACTOR_MODERATE = 1;
+ public static final int ADJ_MEM_FACTOR_LOW = 2;
+ public static final int ADJ_MEM_FACTOR_CRITICAL = 3;
+ public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1;
+ public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT;
+ public static final int ADJ_SCREEN_OFF = 0;
+ public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD;
+ public static final int ADJ_COUNT = ADJ_SCREEN_ON*2;
+
+ public static final int FLAG_COMPLETE = 1<<0;
+ public static final int FLAG_SHUTDOWN = 1<<1;
+ public static final int FLAG_SYSPROPS = 1<<2;
+
+ public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
+ ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };
+
+ public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON };
+
+ public static final int[] NON_CACHED_PROC_STATES = new int[] {
+ STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
+ STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT,
+ STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
+ };
+
+ public static final int[] BACKGROUND_PROC_STATES = new int[] {
+ STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
+ STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
+ };
+
+ public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
+ STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
+ STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
+ STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
+ STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
+ };
+
+ // Current version of the parcel format.
+ private static final int PARCEL_VERSION = 19;
+ // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
+ private static final int MAGIC = 0x50535454;
+
+ public String mReadError;
+ public String mTimePeriodStartClockStr;
+ public int mFlags;
+
+ public final ProcessMap<SparseArray<PackageState>> mPackages
+ = new ProcessMap<SparseArray<PackageState>>();
+ public final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
+
+ public final long[] mMemFactorDurations = new long[ADJ_COUNT];
+ public int mMemFactor = STATE_NOTHING;
+ public long mStartTime;
+
+ public long mTimePeriodStartClock;
+ public long mTimePeriodStartRealtime;
+ public long mTimePeriodEndRealtime;
+ public long mTimePeriodStartUptime;
+ public long mTimePeriodEndUptime;
+ String mRuntime;
+ boolean mRunning;
+
+ public final SparseMappingTable mTableData = new SparseMappingTable();
+
+ int[] mAddLongTable;
+ int mAddLongTableSize;
+
+ public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT];
+ public final SysMemUsageTable mSysMemUsage = new SysMemUsageTable(mTableData);
+
+ // For writing parcels.
+ ArrayMap<String, Integer> mCommonStringToIndex;
+
+ // For reading parcels.
+ ArrayList<String> mIndexToCommonString;
+
+ public ProcessStats(boolean running) {
+ mRunning = running;
+ reset();
+ }
+
+ public ProcessStats(Parcel in) {
+ reset();
+ readFromParcel(in);
+ }
+
+ public void add(ProcessStats other) {
+ ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = other.mPackages.getMap();
+ for (int ip=0; ip<pkgMap.size(); ip++) {
+ final String pkgName = pkgMap.keyAt(ip);
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ final int uid = uids.keyAt(iu);
+ final SparseArray<PackageState> versions = uids.valueAt(iu);
+ for (int iv=0; iv<versions.size(); iv++) {
+ final int vers = versions.keyAt(iv);
+ final PackageState otherState = versions.valueAt(iv);
+ final int NPROCS = otherState.mProcesses.size();
+ final int NSRVS = otherState.mServices.size();
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState otherProc = otherState.mProcesses.valueAt(iproc);
+ if (otherProc.getCommonProcess() != otherProc) {
+ if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
+ + " vers " + vers + " proc " + otherProc.getName());
+ ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers,
+ otherProc.getName());
+ if (thisProc.getCommonProcess() == thisProc) {
+ if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting");
+ thisProc.setMultiPackage(true);
+ long now = SystemClock.uptimeMillis();
+ final PackageState pkgState = getPackageStateLocked(pkgName, uid,
+ vers);
+ thisProc = thisProc.clone(now);
+ pkgState.mProcesses.put(thisProc.getName(), thisProc);
+ }
+ thisProc.add(otherProc);
+ }
+ }
+ for (int isvc=0; isvc<NSRVS; isvc++) {
+ ServiceState otherSvc = otherState.mServices.valueAt(isvc);
+ if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
+ + " service " + otherSvc.getName());
+ ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers,
+ otherSvc.getProcessName(), otherSvc.getName());
+ thisSvc.add(otherSvc);
+ }
+ }
+ }
+ }
+
+ ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap();
+ for (int ip=0; ip<procMap.size(); ip++) {
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ int uid = uids.keyAt(iu);
+ ProcessState otherProc = uids.valueAt(iu);
+ final String name = otherProc.getName();
+ final String pkg = otherProc.getPackage();
+ final int vers = otherProc.getVersion();
+ ProcessState thisProc = mProcesses.get(name, uid);
+ if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + name);
+ if (thisProc == null) {
+ if (DEBUG) Slog.d(TAG, "Creating new process!");
+ thisProc = new ProcessState(this, pkg, uid, vers, name);
+ mProcesses.put(name, uid, thisProc);
+ PackageState thisState = getPackageStateLocked(pkg, uid, vers);
+ if (!thisState.mProcesses.containsKey(name)) {
+ thisState.mProcesses.put(name, thisProc);
+ }
+ }
+ thisProc.add(otherProc);
+ }
+ }
+
+ for (int i=0; i<ADJ_COUNT; i++) {
+ if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by "
+ + other.mMemFactorDurations[i] + " from "
+ + mMemFactorDurations[i]);
+ mMemFactorDurations[i] += other.mMemFactorDurations[i];
+ }
+
+ mSysMemUsage.mergeStats(other.mSysMemUsage);
+
+ if (other.mTimePeriodStartClock < mTimePeriodStartClock) {
+ mTimePeriodStartClock = other.mTimePeriodStartClock;
+ mTimePeriodStartClockStr = other.mTimePeriodStartClockStr;
+ }
+ mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
+ mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;
+ }
+
+ public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem,
+ long nativeMem) {
+ if (mMemFactor != STATE_NOTHING) {
+ int state = mMemFactor * STATE_COUNT;
+ mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1;
+ for (int i=0; i<3; i++) {
+ mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem;
+ mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem;
+ mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem;
+ mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem;
+ mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem;
+ }
+ mSysMemUsage.mergeStats(state, mSysMemUsageArgs, 0);
+ }
+ }
+
+ public static final Parcelable.Creator<ProcessStats> CREATOR
+ = new Parcelable.Creator<ProcessStats>() {
+ public ProcessStats createFromParcel(Parcel in) {
+ return new ProcessStats(in);
+ }
+
+ public ProcessStats[] newArray(int size) {
+ return new ProcessStats[size];
+ }
+ };
+
+ public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) {
+ data.totalTime = 0;
+ for (int i=0; i<STATE_COUNT; i++) {
+ data.processStateWeight[i] = 0;
+ data.processStatePss[i] = 0;
+ data.processStateTime[i] = 0;
+ data.processStateSamples[i] = 0;
+ }
+ for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) {
+ data.sysMemUsage[i] = 0;
+ }
+ data.sysMemCachedWeight = 0;
+ data.sysMemFreeWeight = 0;
+ data.sysMemZRamWeight = 0;
+ data.sysMemKernelWeight = 0;
+ data.sysMemNativeWeight = 0;
+ data.sysMemSamples = 0;
+ final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage();
+ for (int is=0; is<data.screenStates.length; is++) {
+ for (int im=0; im<data.memStates.length; im++) {
+ int memBucket = data.screenStates[is] + data.memStates[im];
+ int stateBucket = memBucket * STATE_COUNT;
+ long memTime = mMemFactorDurations[memBucket];
+ if (mMemFactor == memBucket) {
+ memTime += now - mStartTime;
+ }
+ data.totalTime += memTime;
+ final int sysKey = mSysMemUsage.getKey((byte)stateBucket);
+ long[] longs = totalMemUsage;
+ int idx = 0;
+ if (sysKey != SparseMappingTable.INVALID_KEY) {
+ final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey);
+ final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey);
+ if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) {
+ SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx);
+ longs = tmpLongs;
+ idx = tmpIndex;
+ }
+ }
+ data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE]
+ * (double)memTime;
+ data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE]
+ * (double)memTime;
+ data.sysMemZRamWeight += longs[idx+SYS_MEM_USAGE_ZRAM_AVERAGE]
+ * (double)memTime;
+ data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE]
+ * (double)memTime;
+ data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE]
+ * (double)memTime;
+ data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT];
+ }
+ }
+ ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ for (int iproc=0; iproc<procMap.size(); iproc++) {
+ SparseArray<ProcessState> uids = procMap.valueAt(iproc);
+ for (int iu=0; iu<uids.size(); iu++) {
+ final ProcessState proc = uids.valueAt(iu);
+ proc.aggregatePss(data, now);
+ }
+ }
+ }
+
+ public void reset() {
+ if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr);
+ resetCommon();
+ mPackages.getMap().clear();
+ mProcesses.getMap().clear();
+ mMemFactor = STATE_NOTHING;
+ mStartTime = 0;
+ if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
+ }
+
+ public void resetSafely() {
+ if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr);
+ resetCommon();
+
+ // First initialize use count of all common processes.
+ final long now = SystemClock.uptimeMillis();
+ final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ for (int ip=procMap.size()-1; ip>=0; ip--) {
+ final SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=uids.size()-1; iu>=0; iu--) {
+ uids.valueAt(iu).tmpNumInUse = 0;
+ }
+ }
+
+ // Next reset or prune all per-package processes, and for the ones that are reset
+ // track this back to the common processes.
+ final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+ for (int ip=pkgMap.size()-1; ip>=0; ip--) {
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ for (int iu=uids.size()-1; iu>=0; iu--) {
+ final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+ for (int iv=vpkgs.size()-1; iv>=0; iv--) {
+ final PackageState pkgState = vpkgs.valueAt(iv);
+ for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
+ final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
+ if (ps.isInUse()) {
+ ps.resetSafely(now);
+ ps.getCommonProcess().tmpNumInUse++;
+ ps.getCommonProcess().tmpFoundSubProc = ps;
+ } else {
+ pkgState.mProcesses.valueAt(iproc).makeDead();
+ pkgState.mProcesses.removeAt(iproc);
+ }
+ }
+ for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
+ final ServiceState ss = pkgState.mServices.valueAt(isvc);
+ if (ss.isInUse()) {
+ ss.resetSafely(now);
+ } else {
+ pkgState.mServices.removeAt(isvc);
+ }
+ }
+ if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) {
+ vpkgs.removeAt(iv);
+ }
+ }
+ if (vpkgs.size() <= 0) {
+ uids.removeAt(iu);
+ }
+ }
+ if (uids.size() <= 0) {
+ pkgMap.removeAt(ip);
+ }
+ }
+
+ // Finally prune out any common processes that are no longer in use.
+ for (int ip=procMap.size()-1; ip>=0; ip--) {
+ final SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=uids.size()-1; iu>=0; iu--) {
+ ProcessState ps = uids.valueAt(iu);
+ if (ps.isInUse() || ps.tmpNumInUse > 0) {
+ // If this is a process for multiple packages, we could at this point
+ // be back down to one package. In that case, we want to revert back
+ // to a single shared ProcessState. We can do this by converting the
+ // current package-specific ProcessState up to the shared ProcessState,
+ // throwing away the current one we have here (because nobody else is
+ // using it).
+ if (!ps.isActive() && ps.isMultiPackage() && ps.tmpNumInUse == 1) {
+ // Here we go...
+ ps = ps.tmpFoundSubProc;
+ ps.makeStandalone();
+ uids.setValueAt(iu, ps);
+ } else {
+ ps.resetSafely(now);
+ }
+ } else {
+ ps.makeDead();
+ uids.removeAt(iu);
+ }
+ }
+ if (uids.size() <= 0) {
+ procMap.removeAt(ip);
+ }
+ }
+
+ mStartTime = now;
+ if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
+ }
+
+ private void resetCommon() {
+ mTimePeriodStartClock = System.currentTimeMillis();
+ buildTimePeriodStartClockStr();
+ mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+ mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
+ mTableData.reset();
+ Arrays.fill(mMemFactorDurations, 0);
+ mSysMemUsage.resetTable();
+ mStartTime = 0;
+ mReadError = null;
+ mFlags = 0;
+ evaluateSystemProperties(true);
+ }
+
+ public boolean evaluateSystemProperties(boolean update) {
+ boolean changed = false;
+ String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2",
+ VMRuntime.getRuntime().vmLibrary());
+ if (!Objects.equals(runtime, mRuntime)) {
+ changed = true;
+ if (update) {
+ mRuntime = runtime;
+ }
+ }
+ return changed;
+ }
+
+ private void buildTimePeriodStartClockStr() {
+ mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+ mTimePeriodStartClock).toString();
+ }
+
+ static final int[] BAD_TABLE = new int[0];
+
+ private void writeCompactedLongArray(Parcel out, long[] array, int num) {
+ for (int i=0; i<num; i++) {
+ long val = array[i];
+ if (val < 0) {
+ Slog.w(TAG, "Time val negative: " + val);
+ val = 0;
+ }
+ if (val <= Integer.MAX_VALUE) {
+ out.writeInt((int)val);
+ } else {
+ int top = ~((int)((val>>32)&0x7fffffff));
+ int bottom = (int)(val&0xfffffff);
+ out.writeInt(top);
+ out.writeInt(bottom);
+ }
+ }
+ }
+
+ private void readCompactedLongArray(Parcel in, int version, long[] array, int num) {
+ if (version <= 10) {
+ in.readLongArray(array);
+ return;
+ }
+ final int alen = array.length;
+ if (num > alen) {
+ throw new RuntimeException("bad array lengths: got " + num + " array is " + alen);
+ }
+ int i;
+ for (i=0; i<num; i++) {
+ int val = in.readInt();
+ if (val >= 0) {
+ array[i] = val;
+ } else {
+ int bottom = in.readInt();
+ array[i] = (((long)~val)<<32) | bottom;
+ }
+ }
+ while (i < alen) {
+ array[i] = 0;
+ i++;
+ }
+ }
+
+ private void writeCommonString(Parcel out, String name) {
+ Integer index = mCommonStringToIndex.get(name);
+ if (index != null) {
+ out.writeInt(index);
+ return;
+ }
+ index = mCommonStringToIndex.size();
+ mCommonStringToIndex.put(name, index);
+ out.writeInt(~index);
+ out.writeString(name);
+ }
+
+ private String readCommonString(Parcel in, int version) {
+ if (version <= 9) {
+ return in.readString();
+ }
+ int index = in.readInt();
+ if (index >= 0) {
+ return mIndexToCommonString.get(index);
+ }
+ index = ~index;
+ String name = in.readString();
+ while (mIndexToCommonString.size() <= index) {
+ mIndexToCommonString.add(null);
+ }
+ mIndexToCommonString.set(index, name);
+ return name;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ writeToParcel(out, SystemClock.uptimeMillis(), flags);
+ }
+
+ /** @hide */
+ public void writeToParcel(Parcel out, long now, int flags) {
+ out.writeInt(MAGIC);
+ out.writeInt(PARCEL_VERSION);
+ out.writeInt(STATE_COUNT);
+ out.writeInt(ADJ_COUNT);
+ out.writeInt(PSS_COUNT);
+ out.writeInt(SYS_MEM_USAGE_COUNT);
+ out.writeInt(SparseMappingTable.ARRAY_SIZE);
+
+ mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.size());
+
+ // First commit all running times.
+ ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ final int NPROC = procMap.size();
+ for (int ip=0; ip<NPROC; ip++) {
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ final int NUID = uids.size();
+ for (int iu=0; iu<NUID; iu++) {
+ uids.valueAt(iu).commitStateTime(now);
+ }
+ }
+ final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+ final int NPKG = pkgMap.size();
+ for (int ip=0; ip<NPKG; ip++) {
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ final int NUID = uids.size();
+ for (int iu=0; iu<NUID; iu++) {
+ final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+ final int NVERS = vpkgs.size();
+ for (int iv=0; iv<NVERS; iv++) {
+ PackageState pkgState = vpkgs.valueAt(iv);
+ final int NPROCS = pkgState.mProcesses.size();
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (proc.getCommonProcess() != proc) {
+ proc.commitStateTime(now);
+ }
+ }
+ final int NSRVS = pkgState.mServices.size();
+ for (int isvc=0; isvc<NSRVS; isvc++) {
+ pkgState.mServices.valueAt(isvc).commitStateTime(now);
+ }
+ }
+ }
+ }
+
+ out.writeLong(mTimePeriodStartClock);
+ out.writeLong(mTimePeriodStartRealtime);
+ out.writeLong(mTimePeriodEndRealtime);
+ out.writeLong(mTimePeriodStartUptime);
+ out.writeLong(mTimePeriodEndUptime);
+ out.writeString(mRuntime);
+ out.writeInt(mFlags);
+
+ mTableData.writeToParcel(out);
+
+ if (mMemFactor != STATE_NOTHING) {
+ mMemFactorDurations[mMemFactor] += now - mStartTime;
+ mStartTime = now;
+ }
+ writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length);
+
+ mSysMemUsage.writeToParcel(out);
+
+ out.writeInt(NPROC);
+ for (int ip=0; ip<NPROC; ip++) {
+ writeCommonString(out, procMap.keyAt(ip));
+ final SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ final int NUID = uids.size();
+ out.writeInt(NUID);
+ for (int iu=0; iu<NUID; iu++) {
+ out.writeInt(uids.keyAt(iu));
+ final ProcessState proc = uids.valueAt(iu);
+ writeCommonString(out, proc.getPackage());
+ out.writeInt(proc.getVersion());
+ proc.writeToParcel(out, now);
+ }
+ }
+ out.writeInt(NPKG);
+ for (int ip=0; ip<NPKG; ip++) {
+ writeCommonString(out, pkgMap.keyAt(ip));
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ final int NUID = uids.size();
+ out.writeInt(NUID);
+ for (int iu=0; iu<NUID; iu++) {
+ out.writeInt(uids.keyAt(iu));
+ final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+ final int NVERS = vpkgs.size();
+ out.writeInt(NVERS);
+ for (int iv=0; iv<NVERS; iv++) {
+ out.writeInt(vpkgs.keyAt(iv));
+ final PackageState pkgState = vpkgs.valueAt(iv);
+ final int NPROCS = pkgState.mProcesses.size();
+ out.writeInt(NPROCS);
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
+ final ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (proc.getCommonProcess() == proc) {
+ // This is the same as the common process we wrote above.
+ out.writeInt(0);
+ } else {
+ // There is separate data for this package's process.
+ out.writeInt(1);
+ proc.writeToParcel(out, now);
+ }
+ }
+ final int NSRVS = pkgState.mServices.size();
+ out.writeInt(NSRVS);
+ for (int isvc=0; isvc<NSRVS; isvc++) {
+ out.writeString(pkgState.mServices.keyAt(isvc));
+ final ServiceState svc = pkgState.mServices.valueAt(isvc);
+ writeCommonString(out, svc.getProcessName());
+ svc.writeToParcel(out, now);
+ }
+ }
+ }
+ }
+
+ mCommonStringToIndex = null;
+ }
+
+ private boolean readCheckedInt(Parcel in, int val, String what) {
+ int got;
+ if ((got=in.readInt()) != val) {
+ mReadError = "bad " + what + ": " + got;
+ return false;
+ }
+ return true;
+ }
+
+ static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
+ int pos = 0;
+ final int initialAvail = stream.available();
+ byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384];
+ while (true) {
+ int amt = stream.read(data, pos, data.length-pos);
+ if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos
+ + " of avail " + data.length);
+ if (amt < 0) {
+ if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos
+ + " len=" + data.length);
+ outLen[0] = pos;
+ return data;
+ }
+ pos += amt;
+ if (pos >= data.length) {
+ byte[] newData = new byte[pos+16384];
+ if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len "
+ + newData.length);
+ System.arraycopy(data, 0, newData, 0, pos);
+ data = newData;
+ }
+ }
+ }
+
+ public void read(InputStream stream) {
+ try {
+ int[] len = new int[1];
+ byte[] raw = readFully(stream, len);
+ Parcel in = Parcel.obtain();
+ in.unmarshall(raw, 0, len[0]);
+ in.setDataPosition(0);
+ stream.close();
+
+ readFromParcel(in);
+ } catch (IOException e) {
+ mReadError = "caught exception: " + e;
+ }
+ }
+
+ public void readFromParcel(Parcel in) {
+ final boolean hadData = mPackages.getMap().size() > 0
+ || mProcesses.getMap().size() > 0;
+ if (hadData) {
+ resetSafely();
+ }
+
+ if (!readCheckedInt(in, MAGIC, "magic number")) {
+ return;
+ }
+ int version = in.readInt();
+ if (version != PARCEL_VERSION) {
+ mReadError = "bad version: " + version;
+ return;
+ }
+ if (!readCheckedInt(in, STATE_COUNT, "state count")) {
+ return;
+ }
+ if (!readCheckedInt(in, ADJ_COUNT, "adj count")) {
+ return;
+ }
+ if (!readCheckedInt(in, PSS_COUNT, "pss count")) {
+ return;
+ }
+ if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) {
+ return;
+ }
+ if (!readCheckedInt(in, SparseMappingTable.ARRAY_SIZE, "longs size")) {
+ return;
+ }
+
+ mIndexToCommonString = new ArrayList<String>();
+
+ mTimePeriodStartClock = in.readLong();
+ buildTimePeriodStartClockStr();
+ mTimePeriodStartRealtime = in.readLong();
+ mTimePeriodEndRealtime = in.readLong();
+ mTimePeriodStartUptime = in.readLong();
+ mTimePeriodEndUptime = in.readLong();
+ mRuntime = in.readString();
+ mFlags = in.readInt();
+ mTableData.readFromParcel(in);
+ readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length);
+ if (!mSysMemUsage.readFromParcel(in)) {
+ return;
+ }
+
+ int NPROC = in.readInt();
+ if (NPROC < 0) {
+ mReadError = "bad process count: " + NPROC;
+ return;
+ }
+ while (NPROC > 0) {
+ NPROC--;
+ final String procName = readCommonString(in, version);
+ if (procName == null) {
+ mReadError = "bad process name";
+ return;
+ }
+ int NUID = in.readInt();
+ if (NUID < 0) {
+ mReadError = "bad uid count: " + NUID;
+ return;
+ }
+ while (NUID > 0) {
+ NUID--;
+ final int uid = in.readInt();
+ if (uid < 0) {
+ mReadError = "bad uid: " + uid;
+ return;
+ }
+ final String pkgName = readCommonString(in, version);
+ if (pkgName == null) {
+ mReadError = "bad process package name";
+ return;
+ }
+ final int vers = in.readInt();
+ ProcessState proc = hadData ? mProcesses.get(procName, uid) : null;
+ if (proc != null) {
+ if (!proc.readFromParcel(in, false)) {
+ return;
+ }
+ } else {
+ proc = new ProcessState(this, pkgName, uid, vers, procName);
+ if (!proc.readFromParcel(in, true)) {
+ return;
+ }
+ }
+ if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid
+ + " " + proc);
+ mProcesses.put(procName, uid, proc);
+ }
+ }
+
+ if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes");
+
+ int NPKG = in.readInt();
+ if (NPKG < 0) {
+ mReadError = "bad package count: " + NPKG;
+ return;
+ }
+ while (NPKG > 0) {
+ NPKG--;
+ final String pkgName = readCommonString(in, version);
+ if (pkgName == null) {
+ mReadError = "bad package name";
+ return;
+ }
+ int NUID = in.readInt();
+ if (NUID < 0) {
+ mReadError = "bad uid count: " + NUID;
+ return;
+ }
+ while (NUID > 0) {
+ NUID--;
+ final int uid = in.readInt();
+ if (uid < 0) {
+ mReadError = "bad uid: " + uid;
+ return;
+ }
+ int NVERS = in.readInt();
+ if (NVERS < 0) {
+ mReadError = "bad versions count: " + NVERS;
+ return;
+ }
+ while (NVERS > 0) {
+ NVERS--;
+ final int vers = in.readInt();
+ PackageState pkgState = new PackageState(pkgName, uid);
+ SparseArray<PackageState> vpkg = mPackages.get(pkgName, uid);
+ if (vpkg == null) {
+ vpkg = new SparseArray<PackageState>();
+ mPackages.put(pkgName, uid, vpkg);
+ }
+ vpkg.put(vers, pkgState);
+ int NPROCS = in.readInt();
+ if (NPROCS < 0) {
+ mReadError = "bad package process count: " + NPROCS;
+ return;
+ }
+ while (NPROCS > 0) {
+ NPROCS--;
+ String procName = readCommonString(in, version);
+ if (procName == null) {
+ mReadError = "bad package process name";
+ return;
+ }
+ int hasProc = in.readInt();
+ if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
+ + " process " + procName + " hasProc=" + hasProc);
+ ProcessState commonProc = mProcesses.get(procName, uid);
+ if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid
+ + ": " + commonProc);
+ if (commonProc == null) {
+ mReadError = "no common proc: " + procName;
+ return;
+ }
+ if (hasProc != 0) {
+ // The process for this package is unique to the package; we
+ // need to load it. We don't need to do anything about it if
+ // it is not unique because if someone later looks for it
+ // they will find and use it from the global procs.
+ ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null;
+ if (proc != null) {
+ if (!proc.readFromParcel(in, false)) {
+ return;
+ }
+ } else {
+ proc = new ProcessState(commonProc, pkgName, uid, vers, procName,
+ 0);
+ if (!proc.readFromParcel(in, true)) {
+ return;
+ }
+ }
+ if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
+ + procName + " " + uid + " " + proc);
+ pkgState.mProcesses.put(procName, proc);
+ } else {
+ if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
+ + procName + " " + uid + " " + commonProc);
+ pkgState.mProcesses.put(procName, commonProc);
+ }
+ }
+ int NSRVS = in.readInt();
+ if (NSRVS < 0) {
+ mReadError = "bad package service count: " + NSRVS;
+ return;
+ }
+ while (NSRVS > 0) {
+ NSRVS--;
+ String serviceName = in.readString();
+ if (serviceName == null) {
+ mReadError = "bad package service name";
+ return;
+ }
+ String processName = version > 9 ? readCommonString(in, version) : null;
+ ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null;
+ if (serv == null) {
+ serv = new ServiceState(this, pkgName, serviceName, processName, null);
+ }
+ if (!serv.readFromParcel(in)) {
+ return;
+ }
+ if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
+ + serviceName + " " + uid + " " + serv);
+ pkgState.mServices.put(serviceName, serv);
+ }
+ }
+ }
+ }
+
+ mIndexToCommonString = null;
+
+ if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!");
+ }
+
+ public PackageState getPackageStateLocked(String packageName, int uid, int vers) {
+ SparseArray<PackageState> vpkg = mPackages.get(packageName, uid);
+ if (vpkg == null) {
+ vpkg = new SparseArray<PackageState>();
+ mPackages.put(packageName, uid, vpkg);
+ }
+ PackageState as = vpkg.get(vers);
+ if (as != null) {
+ return as;
+ }
+ as = new PackageState(packageName, uid);
+ vpkg.put(vers, as);
+ return as;
+ }
+
+ public ProcessState getProcessStateLocked(String packageName, int uid, int vers,
+ String processName) {
+ final PackageState pkgState = getPackageStateLocked(packageName, uid, vers);
+ ProcessState ps = pkgState.mProcesses.get(processName);
+ if (ps != null) {
+ return ps;
+ }
+ ProcessState commonProc = mProcesses.get(processName, uid);
+ if (commonProc == null) {
+ commonProc = new ProcessState(this, packageName, uid, vers, processName);
+ mProcesses.put(processName, uid, commonProc);
+ if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);
+ }
+ if (!commonProc.isMultiPackage()) {
+ if (packageName.equals(commonProc.getPackage()) && vers == commonProc.getVersion()) {
+ // This common process is not in use by multiple packages, and
+ // is for the calling package, so we can just use it directly.
+ ps = commonProc;
+ if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc);
+ } else {
+ if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!");
+ // This common process has not been in use by multiple packages,
+ // but it was created for a different package than the caller.
+ // We need to convert it to a multi-package process.
+ commonProc.setMultiPackage(true);
+ // To do this, we need to make two new process states, one a copy
+ // of the current state for the process under the original package
+ // name, and the second a free new process state for it as the
+ // new package name.
+ long now = SystemClock.uptimeMillis();
+ // First let's make a copy of the current process state and put
+ // that under the now unique state for its original package name.
+ final PackageState commonPkgState = getPackageStateLocked(commonProc.getPackage(),
+ uid, commonProc.getVersion());
+ if (commonPkgState != null) {
+ ProcessState cloned = commonProc.clone(now);
+ if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.getPackage()
+ + ": " + cloned);
+ commonPkgState.mProcesses.put(commonProc.getName(), cloned);
+ // If this has active services, we need to update their process pointer
+ // to point to the new package-specific process state.
+ for (int i=commonPkgState.mServices.size()-1; i>=0; i--) {
+ ServiceState ss = commonPkgState.mServices.valueAt(i);
+ if (ss.getProcess() == commonProc) {
+ if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: " + ss);
+ ss.setProcess(cloned);
+ } else if (DEBUG) {
+ Slog.d(TAG, "GETPROC leaving proc of " + ss);
+ }
+ }
+ } else {
+ Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage()
+ + "/" + uid + " for proc " + commonProc.getName());
+ }
+ // And now make a fresh new process state for the new package name.
+ ps = new ProcessState(commonProc, packageName, uid, vers, processName, now);
+ if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
+ }
+ } else {
+ // The common process is for multiple packages, we need to create a
+ // separate object for the per-package data.
+ ps = new ProcessState(commonProc, packageName, uid, vers, processName,
+ SystemClock.uptimeMillis());
+ if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
+ }
+ pkgState.mProcesses.put(processName, ps);
+ if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);
+ return ps;
+ }
+
+ public ServiceState getServiceStateLocked(String packageName, int uid, int vers,
+ String processName, String className) {
+ final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers);
+ ServiceState ss = as.mServices.get(className);
+ if (ss != null) {
+ if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss);
+ return ss;
+ }
+ final ProcessState ps = processName != null
+ ? getProcessStateLocked(packageName, uid, vers, processName) : null;
+ ss = new ServiceState(this, packageName, className, processName, ps);
+ as.mServices.put(className, ss);
+ if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps);
+ return ss;
+ }
+
+ public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
+ boolean dumpAll, boolean activeOnly) {
+ long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
+ mStartTime, now);
+ boolean sepNeeded = false;
+ if (mSysMemUsage.getKeyCount() > 0) {
+ pw.println("System memory usage:");
+ mSysMemUsage.dump(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
+ sepNeeded = true;
+ }
+ ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+ boolean printedHeader = false;
+ for (int ip=0; ip<pkgMap.size(); ip++) {
+ final String pkgName = pkgMap.keyAt(ip);
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ final int uid = uids.keyAt(iu);
+ final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+ for (int iv=0; iv<vpkgs.size(); iv++) {
+ final int vers = vpkgs.keyAt(iv);
+ final PackageState pkgState = vpkgs.valueAt(iv);
+ final int NPROCS = pkgState.mProcesses.size();
+ final int NSRVS = pkgState.mServices.size();
+ final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+ if (!pkgMatch) {
+ boolean procMatch = false;
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (reqPackage.equals(proc.getName())) {
+ procMatch = true;
+ break;
+ }
+ }
+ if (!procMatch) {
+ continue;
+ }
+ }
+ if (NPROCS > 0 || NSRVS > 0) {
+ if (!printedHeader) {
+ if (sepNeeded) pw.println();
+ pw.println("Per-Package Stats:");
+ printedHeader = true;
+ sepNeeded = true;
+ }
+ pw.print(" * "); pw.print(pkgName); pw.print(" / ");
+ UserHandle.formatUid(pw, uid); pw.print(" / v");
+ pw.print(vers); pw.println(":");
+ }
+ if (!dumpSummary || dumpAll) {
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+ continue;
+ }
+ if (activeOnly && !proc.isInUse()) {
+ pw.print(" (Not active: ");
+ pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
+ continue;
+ }
+ pw.print(" Process ");
+ pw.print(pkgState.mProcesses.keyAt(iproc));
+ if (proc.getCommonProcess().isMultiPackage()) {
+ pw.print(" (multi, ");
+ } else {
+ pw.print(" (unique, ");
+ }
+ pw.print(proc.getDurationsBucketCount());
+ pw.print(" entries)");
+ pw.println(":");
+ proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES, now);
+ proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES);
+ proc.dumpInternalLocked(pw, " ", dumpAll);
+ }
+ } else {
+ ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+ continue;
+ }
+ if (activeOnly && !proc.isInUse()) {
+ continue;
+ }
+ procs.add(proc);
+ }
+ DumpUtils.dumpProcessSummaryLocked(pw, " ", procs,
+ ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES,
+ now, totalTime);
+ }
+ for (int isvc=0; isvc<NSRVS; isvc++) {
+ ServiceState svc = pkgState.mServices.valueAt(isvc);
+ if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
+ continue;
+ }
+ if (activeOnly && !svc.isInUse()) {
+ pw.print(" (Not active: ");
+ pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
+ continue;
+ }
+ if (dumpAll) {
+ pw.print(" Service ");
+ } else {
+ pw.print(" * ");
+ }
+ pw.print(pkgState.mServices.keyAt(isvc));
+ pw.println(":");
+ pw.print(" Process: "); pw.println(svc.getProcessName());
+ svc.dumpStats(pw, " ", " ", " ",
+ now, totalTime, dumpSummary, dumpAll);
+ }
+ }
+ }
+ }
+
+ ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ printedHeader = false;
+ int numShownProcs = 0, numTotalProcs = 0;
+ for (int ip=0; ip<procMap.size(); ip++) {
+ String procName = procMap.keyAt(ip);
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ int uid = uids.keyAt(iu);
+ numTotalProcs++;
+ final ProcessState proc = uids.valueAt(iu);
+ if (proc.hasAnyData()) {
+ continue;
+ }
+ if (!proc.isMultiPackage()) {
+ continue;
+ }
+ if (reqPackage != null && !reqPackage.equals(procName)
+ && !reqPackage.equals(proc.getPackage())) {
+ continue;
+ }
+ numShownProcs++;
+ if (sepNeeded) {
+ pw.println();
+ }
+ sepNeeded = true;
+ if (!printedHeader) {
+ pw.println("Multi-Package Common Processes:");
+ printedHeader = true;
+ }
+ if (activeOnly && !proc.isInUse()) {
+ pw.print(" (Not active: "); pw.print(procName); pw.println(")");
+ continue;
+ }
+ pw.print(" * "); pw.print(procName); pw.print(" / ");
+ UserHandle.formatUid(pw, uid);
+ pw.print(" ("); pw.print(proc.getDurationsBucketCount());
+ pw.print(" entries)"); pw.println(":");
+ proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES, now);
+ proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES);
+ proc.dumpInternalLocked(pw, " ", dumpAll);
+ }
+ }
+ if (dumpAll) {
+ pw.println();
+ pw.print(" Total procs: "); pw.print(numShownProcs);
+ pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
+ }
+
+ if (sepNeeded) {
+ pw.println();
+ }
+ if (dumpSummary) {
+ pw.println("Summary:");
+ dumpSummaryLocked(pw, reqPackage, now, activeOnly);
+ } else {
+ dumpTotalsLocked(pw, now);
+ }
+
+ if (dumpAll) {
+ pw.println();
+ pw.println("Internal state:");
+ /*
+ pw.print(" Num long arrays: "); pw.println(mLongs.size());
+ pw.print(" Next long entry: "); pw.println(mNextLong);
+ */
+ pw.print(" mRunning="); pw.println(mRunning);
+ }
+ }
+
+ public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) {
+ long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
+ mStartTime, now);
+ dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly);
+ pw.println();
+ dumpTotalsLocked(pw, now);
+ }
+
+ long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight,
+ long totalTime, long curTotalMem, int samples) {
+ if (memWeight != 0) {
+ long mem = (long)(memWeight * 1024 / totalTime);
+ pw.print(prefix);
+ pw.print(label);
+ pw.print(": ");
+ DebugUtils.printSizeValue(pw, mem);
+ pw.print(" (");
+ pw.print(samples);
+ pw.print(" samples)");
+ pw.println();
+ return curTotalMem + mem;
+ }
+ return curTotalMem;
+ }
+
+ void dumpTotalsLocked(PrintWriter pw, long now) {
+ pw.println("Run time Stats:");
+ DumpUtils.dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now);
+ pw.println();
+ pw.println("Memory usage:");
+ TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
+ ALL_MEM_ADJ);
+ computeTotalMemoryUse(totalMem, now);
+ long totalPss = 0;
+ totalPss = printMemoryCategory(pw, " ", "Kernel ", totalMem.sysMemKernelWeight,
+ totalMem.totalTime, totalPss, totalMem.sysMemSamples);
+ totalPss = printMemoryCategory(pw, " ", "Native ", totalMem.sysMemNativeWeight,
+ totalMem.totalTime, totalPss, totalMem.sysMemSamples);
+ for (int i=0; i<STATE_COUNT; i++) {
+ // Skip restarting service state -- that is not actually a running process.
+ if (i != STATE_SERVICE_RESTARTING) {
+ totalPss = printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[i],
+ totalMem.processStateWeight[i], totalMem.totalTime, totalPss,
+ totalMem.processStateSamples[i]);
+ }
+ }
+ totalPss = printMemoryCategory(pw, " ", "Cached ", totalMem.sysMemCachedWeight,
+ totalMem.totalTime, totalPss, totalMem.sysMemSamples);
+ totalPss = printMemoryCategory(pw, " ", "Free ", totalMem.sysMemFreeWeight,
+ totalMem.totalTime, totalPss, totalMem.sysMemSamples);
+ totalPss = printMemoryCategory(pw, " ", "Z-Ram ", totalMem.sysMemZRamWeight,
+ totalMem.totalTime, totalPss, totalMem.sysMemSamples);
+ pw.print(" TOTAL : ");
+ DebugUtils.printSizeValue(pw, totalPss);
+ pw.println();
+ printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[STATE_SERVICE_RESTARTING],
+ totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss,
+ totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
+ pw.println();
+ pw.print(" Start time: ");
+ pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
+ pw.println();
+ pw.print(" Total elapsed time: ");
+ TimeUtils.formatDuration(
+ (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
+ - mTimePeriodStartRealtime, pw);
+ boolean partial = true;
+ if ((mFlags&FLAG_SHUTDOWN) != 0) {
+ pw.print(" (shutdown)");
+ partial = false;
+ }
+ if ((mFlags&FLAG_SYSPROPS) != 0) {
+ pw.print(" (sysprops)");
+ partial = false;
+ }
+ if ((mFlags&FLAG_COMPLETE) != 0) {
+ pw.print(" (complete)");
+ partial = false;
+ }
+ if (partial) {
+ pw.print(" (partial)");
+ }
+ pw.print(' ');
+ pw.print(mRuntime);
+ pw.println();
+ }
+
+ void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
+ int[] screenStates, int[] memStates, int[] procStates,
+ int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) {
+ ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
+ procStates, sortProcStates, now, reqPackage, activeOnly);
+ if (procs.size() > 0) {
+ if (header != null) {
+ pw.println();
+ pw.println(header);
+ }
+ DumpUtils.dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates,
+ sortProcStates, now, totalTime);
+ }
+ }
+
+ public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
+ int[] procStates, int sortProcStates[], long now, String reqPackage,
+ boolean activeOnly) {
+ final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
+ final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+ for (int ip=0; ip<pkgMap.size(); ip++) {
+ final String pkgName = pkgMap.keyAt(ip);
+ final SparseArray<SparseArray<PackageState>> procs = pkgMap.valueAt(ip);
+ for (int iu=0; iu<procs.size(); iu++) {
+ final SparseArray<PackageState> vpkgs = procs.valueAt(iu);
+ final int NVERS = vpkgs.size();
+ for (int iv=0; iv<NVERS; iv++) {
+ final PackageState state = vpkgs.valueAt(iv);
+ final int NPROCS = state.mProcesses.size();
+ final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ final ProcessState proc = state.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+ continue;
+ }
+ if (activeOnly && !proc.isInUse()) {
+ continue;
+ }
+ foundProcs.add(proc.getCommonProcess());
+ }
+ }
+ }
+ }
+ ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size());
+ for (int i=0; i<foundProcs.size(); i++) {
+ ProcessState proc = foundProcs.valueAt(i);
+ if (proc.computeProcessTimeLocked(screenStates, memStates, procStates, now) > 0) {
+ outProcs.add(proc);
+ if (procStates != sortProcStates) {
+ proc.computeProcessTimeLocked(screenStates, memStates, sortProcStates, now);
+ }
+ }
+ }
+ Collections.sort(outProcs, ProcessState.COMPARATOR);
+ return outProcs;
+ }
+
+ public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
+ final long now = SystemClock.uptimeMillis();
+ final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+ pw.println("vers,5");
+ pw.print("period,"); pw.print(mTimePeriodStartClockStr);
+ pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
+ pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
+ boolean partial = true;
+ if ((mFlags&FLAG_SHUTDOWN) != 0) {
+ pw.print(",shutdown");
+ partial = false;
+ }
+ if ((mFlags&FLAG_SYSPROPS) != 0) {
+ pw.print(",sysprops");
+ partial = false;
+ }
+ if ((mFlags&FLAG_COMPLETE) != 0) {
+ pw.print(",complete");
+ partial = false;
+ }
+ if (partial) {
+ pw.print(",partial");
+ }
+ pw.println();
+ pw.print("config,"); pw.println(mRuntime);
+ for (int ip=0; ip<pkgMap.size(); ip++) {
+ final String pkgName = pkgMap.keyAt(ip);
+ if (reqPackage != null && !reqPackage.equals(pkgName)) {
+ continue;
+ }
+ final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ final int uid = uids.keyAt(iu);
+ final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+ for (int iv=0; iv<vpkgs.size(); iv++) {
+ final int vers = vpkgs.keyAt(iv);
+ final PackageState pkgState = vpkgs.valueAt(iv);
+ final int NPROCS = pkgState.mProcesses.size();
+ final int NSRVS = pkgState.mServices.size();
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ proc.dumpPackageProcCheckin(pw, pkgName, uid, vers,
+ pkgState.mProcesses.keyAt(iproc), now);
+ }
+ for (int isvc=0; isvc<NSRVS; isvc++) {
+ final String serviceName = DumpUtils.collapseString(pkgName,
+ pkgState.mServices.keyAt(isvc));
+ final ServiceState svc = pkgState.mServices.valueAt(isvc);
+ svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now);
+ }
+ }
+ }
+ }
+
+ ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ for (int ip=0; ip<procMap.size(); ip++) {
+ String procName = procMap.keyAt(ip);
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ final int uid = uids.keyAt(iu);
+ final ProcessState procState = uids.valueAt(iu);
+ procState.dumpProcCheckin(pw, procName, uid, now);
+ }
+ }
+ pw.print("total");
+ DumpUtils.dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor, mStartTime, now);
+ pw.println();
+ final int sysMemUsageCount = mSysMemUsage.getKeyCount();
+ if (sysMemUsageCount > 0) {
+ pw.print("sysmemusage");
+ for (int i=0; i<sysMemUsageCount; i++) {
+ final int key = mSysMemUsage.getKeyAt(i);
+ final int type = SparseMappingTable.getIdFromKey(key);
+ pw.print(",");
+ DumpUtils.printProcStateTag(pw, type);
+ for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) {
+ if (j > SYS_MEM_USAGE_CACHED_MINIMUM) {
+ pw.print(":");
+ }
+ pw.print(mSysMemUsage.getValue(key, j));
+ }
+ }
+ }
+ pw.println();
+ TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
+ ALL_MEM_ADJ);
+ computeTotalMemoryUse(totalMem, now);
+ pw.print("weights,");
+ pw.print(totalMem.totalTime);
+ pw.print(",");
+ pw.print(totalMem.sysMemCachedWeight);
+ pw.print(":");
+ pw.print(totalMem.sysMemSamples);
+ pw.print(",");
+ pw.print(totalMem.sysMemFreeWeight);
+ pw.print(":");
+ pw.print(totalMem.sysMemSamples);
+ pw.print(",");
+ pw.print(totalMem.sysMemZRamWeight);
+ pw.print(":");
+ pw.print(totalMem.sysMemSamples);
+ pw.print(",");
+ pw.print(totalMem.sysMemKernelWeight);
+ pw.print(":");
+ pw.print(totalMem.sysMemSamples);
+ pw.print(",");
+ pw.print(totalMem.sysMemNativeWeight);
+ pw.print(":");
+ pw.print(totalMem.sysMemSamples);
+ for (int i=0; i<STATE_COUNT; i++) {
+ pw.print(",");
+ pw.print(totalMem.processStateWeight[i]);
+ pw.print(":");
+ pw.print(totalMem.processStateSamples[i]);
+ }
+ pw.println();
+ }
+
+
+ final public static class ProcessStateHolder {
+ public final int appVersion;
+ public ProcessState state;
+
+ public ProcessStateHolder(int _appVersion) {
+ appVersion = _appVersion;
+ }
+ }
+
+ public static final class PackageState {
+ public final ArrayMap<String, ProcessState> mProcesses
+ = new ArrayMap<String, ProcessState>();
+ public final ArrayMap<String, ServiceState> mServices
+ = new ArrayMap<String, ServiceState>();
+ public final String mPackageName;
+ public final int mUid;
+
+ public PackageState(String packageName, int uid) {
+ mUid = uid;
+ mPackageName = packageName;
+ }
+ }
+
+ public static final class ProcessDataCollection {
+ final int[] screenStates;
+ final int[] memStates;
+ final int[] procStates;
+
+ public long totalTime;
+ public long numPss;
+ public long minPss;
+ public long avgPss;
+ public long maxPss;
+ public long minUss;
+ public long avgUss;
+ public long maxUss;
+
+ public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
+ screenStates = _screenStates;
+ memStates = _memStates;
+ procStates = _procStates;
+ }
+
+ void print(PrintWriter pw, long overallTime, boolean full) {
+ if (totalTime > overallTime) {
+ pw.print("*");
+ }
+ DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime);
+ if (numPss > 0) {
+ pw.print(" (");
+ DebugUtils.printSizeValue(pw, minPss * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, avgPss * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, maxPss * 1024);
+ pw.print("/");
+ DebugUtils.printSizeValue(pw, minUss * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, avgUss * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, maxUss * 1024);
+ if (full) {
+ pw.print(" over ");
+ pw.print(numPss);
+ }
+ pw.print(")");
+ }
+ }
+ }
+
+ public static class TotalMemoryUseCollection {
+ final int[] screenStates;
+ final int[] memStates;
+
+ public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) {
+ screenStates = _screenStates;
+ memStates = _memStates;
+ }
+
+ public long totalTime;
+ public long[] processStatePss = new long[STATE_COUNT];
+ public double[] processStateWeight = new double[STATE_COUNT];
+ public long[] processStateTime = new long[STATE_COUNT];
+ public int[] processStateSamples = new int[STATE_COUNT];
+ public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT];
+ public double sysMemCachedWeight;
+ public double sysMemFreeWeight;
+ public double sysMemZRamWeight;
+ public double sysMemKernelWeight;
+ public double sysMemNativeWeight;
+ public int sysMemSamples;
+ }
+
+}
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
new file mode 100644
index 0000000..b6df983
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
+import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
+
+/**
+ * Class to accumulate PSS data.
+ */
+public class PssTable extends SparseMappingTable.Table {
+ /**
+ * Construct the PssTable with 'tableData' as backing store
+ * for the longs data.
+ */
+ public PssTable(SparseMappingTable tableData) {
+ super(tableData);
+ }
+
+ /**
+ * Merge the the values from the other table into this one.
+ */
+ public void mergeStats(PssTable that) {
+ final int N = that.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = that.getKeyAt(i);
+ final int state = SparseMappingTable.getIdFromKey(key);
+ mergeStats(state, (int)that.getValue(key, PSS_SAMPLE_COUNT),
+ that.getValue(key, PSS_MINIMUM),
+ that.getValue(key, PSS_AVERAGE),
+ that.getValue(key, PSS_MAXIMUM),
+ that.getValue(key, PSS_USS_MINIMUM),
+ that.getValue(key, PSS_USS_AVERAGE),
+ that.getValue(key, PSS_USS_MAXIMUM));
+ }
+ }
+
+ /**
+ * Merge the supplied PSS data in. The new min pss will be the minimum of the existing
+ * one and the new one, the average will now incorporate the new average, etc.
+ */
+ public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss,
+ long minUss, long avgUss, long maxUss) {
+ final int key = getOrAddKey((byte)state, PSS_COUNT);
+ final long count = getValue(key, PSS_SAMPLE_COUNT);
+ if (count == 0) {
+ setValue(key, PSS_SAMPLE_COUNT, inCount);
+ setValue(key, PSS_MINIMUM, minPss);
+ setValue(key, PSS_AVERAGE, avgPss);
+ setValue(key, PSS_MAXIMUM, maxPss);
+ setValue(key, PSS_USS_MINIMUM, minUss);
+ setValue(key, PSS_USS_AVERAGE, avgUss);
+ setValue(key, PSS_USS_MAXIMUM, maxUss);
+ } else {
+ setValue(key, PSS_SAMPLE_COUNT, count + inCount);
+
+ long val;
+
+ val = getValue(key, PSS_MINIMUM);
+ if (val > minPss) {
+ setValue(key, PSS_MINIMUM, minPss);
+ }
+
+ val = getValue(key, PSS_AVERAGE);
+ setValue(key, PSS_AVERAGE,
+ (long)(((val*(double)count)+(avgPss*(double)inCount)) / (count+inCount)));
+
+ val = getValue(key, PSS_MAXIMUM);
+ if (val < maxPss) {
+ setValue(key, PSS_MAXIMUM, maxPss);
+ }
+
+ val = getValue(key, PSS_USS_MINIMUM);
+ if (val > minUss) {
+ setValue(key, PSS_USS_MINIMUM, minUss);
+ }
+
+ val = getValue(key, PSS_USS_AVERAGE);
+ setValue(key, PSS_AVERAGE,
+ (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+
+ val = getValue(key, PSS_USS_MAXIMUM);
+ if (val < maxUss) {
+ setValue(key, PSS_USS_MAXIMUM, maxUss);
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/app/procstats/ServiceState.java b/core/java/com/android/internal/app/procstats/ServiceState.java
new file mode 100644
index 0000000..2e11c43
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/ServiceState.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.format.DateFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+
+import com.android.internal.app.procstats.ProcessStats;
+import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+
+public final class ServiceState {
+ private static final String TAG = "ProcessStats";
+ private static final boolean DEBUG = false;
+
+ public static final int SERVICE_RUN = 0;
+ public static final int SERVICE_STARTED = 1;
+ public static final int SERVICE_BOUND = 2;
+ public static final int SERVICE_EXEC = 3;
+ public static final int SERVICE_COUNT = 4;
+
+ private final String mPackage;
+ private final String mProcessName;
+ private final String mName;
+ private final DurationsTable mDurations;
+
+ private ProcessState mProc;
+ private Object mOwner;
+
+ private int mRunCount;
+ private int mRunState = STATE_NOTHING;
+ private long mRunStartTime;
+
+ private boolean mStarted;
+ private boolean mRestarting;
+ private int mStartedCount;
+ private int mStartedState = STATE_NOTHING;
+ private long mStartedStartTime;
+
+ private int mBoundCount;
+ private int mBoundState = STATE_NOTHING;
+ private long mBoundStartTime;
+
+ private int mExecCount;
+ private int mExecState = STATE_NOTHING;
+ private long mExecStartTime;
+
+ public ServiceState(ProcessStats processStats, String pkg, String name,
+ String processName, ProcessState proc) {
+ mPackage = pkg;
+ mName = name;
+ mProcessName = processName;
+ mProc = proc;
+ mDurations = new DurationsTable(processStats.mTableData);
+ }
+
+ public String getPackage() {
+ return mPackage;
+ }
+
+ public String getProcessName() {
+ return mProcessName;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public ProcessState getProcess() {
+ return mProc;
+ }
+
+ public void setProcess(ProcessState proc) {
+ mProc = proc;
+ }
+
+ public void setMemFactor(int memFactor, long now) {
+ if (isRestarting()) {
+ setRestarting(true, memFactor, now);
+ } else if (isInUse()) {
+ if (mStartedState != ProcessStats.STATE_NOTHING) {
+ setStarted(true, memFactor, now);
+ }
+ if (mBoundState != ProcessStats.STATE_NOTHING) {
+ setBound(true, memFactor, now);
+ }
+ if (mExecState != ProcessStats.STATE_NOTHING) {
+ setExecuting(true, memFactor, now);
+ }
+ }
+ }
+
+ public void applyNewOwner(Object newOwner) {
+ if (mOwner != newOwner) {
+ if (mOwner == null) {
+ mOwner = newOwner;
+ mProc.incActiveServices(mName);
+ } else {
+ // There was already an old owner, reset this object for its
+ // new owner.
+ mOwner = newOwner;
+ if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
+ long now = SystemClock.uptimeMillis();
+ if (mStarted) {
+ if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
+ + " from " + mOwner + " while started: pkg="
+ + mPackage + " service=" + mName + " proc=" + mProc);
+ setStarted(false, 0, now);
+ }
+ if (mBoundState != STATE_NOTHING) {
+ if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
+ + " from " + mOwner + " while bound: pkg="
+ + mPackage + " service=" + mName + " proc=" + mProc);
+ setBound(false, 0, now);
+ }
+ if (mExecState != STATE_NOTHING) {
+ if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
+ + " from " + mOwner + " while executing: pkg="
+ + mPackage + " service=" + mName + " proc=" + mProc);
+ setExecuting(false, 0, now);
+ }
+ }
+ }
+ }
+ }
+
+ public void clearCurrentOwner(Object owner, boolean silently) {
+ if (mOwner == owner) {
+ mProc.decActiveServices(mName);
+ if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
+ long now = SystemClock.uptimeMillis();
+ if (mStarted) {
+ if (!silently) {
+ Slog.wtfStack(TAG, "Service owner " + owner
+ + " cleared while started: pkg=" + mPackage + " service="
+ + mName + " proc=" + mProc);
+ }
+ setStarted(false, 0, now);
+ }
+ if (mBoundState != STATE_NOTHING) {
+ if (!silently) {
+ Slog.wtfStack(TAG, "Service owner " + owner
+ + " cleared while bound: pkg=" + mPackage + " service="
+ + mName + " proc=" + mProc);
+ }
+ setBound(false, 0, now);
+ }
+ if (mExecState != STATE_NOTHING) {
+ if (!silently) {
+ Slog.wtfStack(TAG, "Service owner " + owner
+ + " cleared while exec: pkg=" + mPackage + " service="
+ + mName + " proc=" + mProc);
+ }
+ setExecuting(false, 0, now);
+ }
+ }
+ mOwner = null;
+ }
+ }
+
+ public boolean isInUse() {
+ return mOwner != null || mRestarting;
+ }
+
+ public boolean isRestarting() {
+ return mRestarting;
+ }
+
+ public void add(ServiceState other) {
+ mDurations.addDurations(other.mDurations);
+ mRunCount += other.mRunCount;
+ mStartedCount += other.mStartedCount;
+ mBoundCount += other.mBoundCount;
+ mExecCount += other.mExecCount;
+ }
+
+ public void resetSafely(long now) {
+ mDurations.resetTable();
+ mRunCount = mRunState != STATE_NOTHING ? 1 : 0;
+ mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0;
+ mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0;
+ mExecCount = mExecState != STATE_NOTHING ? 1 : 0;
+ mRunStartTime = mStartedStartTime = mBoundStartTime = mExecStartTime = now;
+ }
+
+ public void writeToParcel(Parcel out, long now) {
+ mDurations.writeToParcel(out);
+ out.writeInt(mRunCount);
+ out.writeInt(mStartedCount);
+ out.writeInt(mBoundCount);
+ out.writeInt(mExecCount);
+ }
+
+ public boolean readFromParcel(Parcel in) {
+ if (!mDurations.readFromParcel(in)) {
+ return false;
+ }
+ mRunCount = in.readInt();
+ mStartedCount = in.readInt();
+ mBoundCount = in.readInt();
+ mExecCount = in.readInt();
+ return true;
+ }
+
+ public void commitStateTime(long now) {
+ if (mRunState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
+ now - mRunStartTime);
+ mRunStartTime = now;
+ }
+ if (mStartedState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+ now - mStartedStartTime);
+ mStartedStartTime = now;
+ }
+ if (mBoundState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
+ now - mBoundStartTime);
+ mBoundStartTime = now;
+ }
+ if (mExecState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT),
+ now - mExecStartTime);
+ mExecStartTime = now;
+ }
+ }
+
+ private void updateRunning(int memFactor, long now) {
+ final int state = (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
+ || mExecState != STATE_NOTHING) ? memFactor : STATE_NOTHING;
+ if (mRunState != state) {
+ if (mRunState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
+ now - mRunStartTime);
+ } else if (state != STATE_NOTHING) {
+ mRunCount++;
+ }
+ mRunState = state;
+ mRunStartTime = now;
+ }
+ }
+
+ public void setStarted(boolean started, int memFactor, long now) {
+ if (mOwner == null) {
+ Slog.wtf(TAG, "Starting service " + this + " without owner");
+ }
+ mStarted = started;
+ updateStartedState(memFactor, now);
+ }
+
+ public void setRestarting(boolean restarting, int memFactor, long now) {
+ mRestarting = restarting;
+ updateStartedState(memFactor, now);
+ }
+
+ public void updateStartedState(int memFactor, long now) {
+ final boolean wasStarted = mStartedState != STATE_NOTHING;
+ final boolean started = mStarted || mRestarting;
+ final int state = started ? memFactor : STATE_NOTHING;
+ if (mStartedState != state) {
+ if (mStartedState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+ now - mStartedStartTime);
+ } else if (started) {
+ mStartedCount++;
+ }
+ mStartedState = state;
+ mStartedStartTime = now;
+ mProc = mProc.pullFixedProc(mPackage);
+ if (wasStarted != started) {
+ if (started) {
+ mProc.incStartedServices(memFactor, now, mName);
+ } else {
+ mProc.decStartedServices(memFactor, now, mName);
+ }
+ }
+ updateRunning(memFactor, now);
+ }
+ }
+
+ public void setBound(boolean bound, int memFactor, long now) {
+ if (mOwner == null) {
+ Slog.wtf(TAG, "Binding service " + this + " without owner");
+ }
+ final int state = bound ? memFactor : STATE_NOTHING;
+ if (mBoundState != state) {
+ if (mBoundState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
+ now - mBoundStartTime);
+ } else if (bound) {
+ mBoundCount++;
+ }
+ mBoundState = state;
+ mBoundStartTime = now;
+ updateRunning(memFactor, now);
+ }
+ }
+
+ public void setExecuting(boolean executing, int memFactor, long now) {
+ if (mOwner == null) {
+ Slog.wtf(TAG, "Executing service " + this + " without owner");
+ }
+ final int state = executing ? memFactor : STATE_NOTHING;
+ if (mExecState != state) {
+ if (mExecState != STATE_NOTHING) {
+ mDurations.addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT),
+ now - mExecStartTime);
+ } else if (executing) {
+ mExecCount++;
+ }
+ mExecState = state;
+ mExecStartTime = now;
+ updateRunning(memFactor, now);
+ }
+ }
+
+ public long getDuration(int opType, int curState, long startTime, int memFactor,
+ long now) {
+ int state = opType + (memFactor*SERVICE_COUNT);
+ long time = mDurations.getValueForId((byte)state);
+ if (curState == memFactor) {
+ time += now - startTime;
+ }
+ return time;
+ }
+
+ public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix,
+ long now, long totalTime, boolean dumpSummary, boolean dumpAll) {
+ dumpStats(pw, prefix, prefixInner, headerPrefix, "Running",
+ mRunCount, ServiceState.SERVICE_RUN, mRunState,
+ mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
+ dumpStats(pw, prefix, prefixInner, headerPrefix, "Started",
+ mStartedCount, ServiceState.SERVICE_STARTED, mStartedState,
+ mStartedStartTime, now, totalTime, !dumpSummary || dumpAll);
+ dumpStats(pw, prefix, prefixInner, headerPrefix, "Bound",
+ mBoundCount, ServiceState.SERVICE_BOUND, mBoundState,
+ mBoundStartTime, now, totalTime, !dumpSummary || dumpAll);
+ dumpStats(pw, prefix, prefixInner, headerPrefix, "Executing",
+ mExecCount, ServiceState.SERVICE_EXEC, mExecState,
+ mExecStartTime, now, totalTime, !dumpSummary || dumpAll);
+ if (dumpAll) {
+ if (mOwner != null) {
+ pw.print(" mOwner="); pw.println(mOwner);
+ }
+ if (mStarted || mRestarting) {
+ pw.print(" mStarted="); pw.print(mStarted);
+ pw.print(" mRestarting="); pw.println(mRestarting);
+ }
+ }
+ }
+
+ private void dumpStats(PrintWriter pw, String prefix, String prefixInner,
+ String headerPrefix, String header,
+ int count, int serviceType, int state, long startTime, long now, long totalTime,
+ boolean dumpAll) {
+ if (count != 0) {
+ if (dumpAll) {
+ pw.print(prefix); pw.print(header);
+ pw.print(" op count "); pw.print(count); pw.println(":");
+ dumpTime(pw, prefixInner, serviceType, state, startTime, now);
+ } else {
+ long myTime = dumpTime(null, null, serviceType, state, startTime, now);
+ pw.print(prefix); pw.print(headerPrefix); pw.print(header);
+ pw.print(" count "); pw.print(count);
+ pw.print(" / time ");
+ DumpUtils.printPercent(pw, (double)myTime/(double)totalTime);
+ pw.println();
+ }
+ }
+ }
+
+ public long dumpTime(PrintWriter pw, String prefix,
+ int serviceType, int curState, long curStartTime, long now) {
+ long totalTime = 0;
+ int printedScreen = -1;
+ for (int iscreen=0; iscreen<ProcessStats.ADJ_COUNT; iscreen+=ProcessStats.ADJ_SCREEN_MOD) {
+ int printedMem = -1;
+ for (int imem=0; imem<ProcessStats.ADJ_MEM_FACTOR_COUNT; imem++) {
+ int state = imem+iscreen;
+ long time = getDuration(serviceType, curState, curStartTime, state, now);
+ String running = "";
+ if (curState == state && pw != null) {
+ running = " (running)";
+ }
+ if (time != 0) {
+ if (pw != null) {
+ pw.print(prefix);
+ DumpUtils.printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ DumpUtils.printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING,
+ (char)0);
+ printedMem = imem;
+ pw.print(": ");
+ TimeUtils.formatDuration(time, pw); pw.println(running);
+ }
+ totalTime += time;
+ }
+ }
+ }
+ if (totalTime != 0 && pw != null) {
+ pw.print(prefix);
+ pw.print(" TOTAL: ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
+ return totalTime;
+ }
+
+ public void dumpTimesCheckin(PrintWriter pw, String pkgName, int uid, int vers,
+ String serviceName, long now) {
+ dumpTimeCheckin(pw, "pkgsvc-run", pkgName, uid, vers, serviceName,
+ ServiceState.SERVICE_RUN, mRunCount, mRunState, mRunStartTime, now);
+ dumpTimeCheckin(pw, "pkgsvc-start", pkgName, uid, vers, serviceName,
+ ServiceState.SERVICE_STARTED, mStartedCount, mStartedState, mStartedStartTime, now);
+ dumpTimeCheckin(pw, "pkgsvc-bound", pkgName, uid, vers, serviceName,
+ ServiceState.SERVICE_BOUND, mBoundCount, mBoundState, mBoundStartTime, now);
+ dumpTimeCheckin(pw, "pkgsvc-exec", pkgName, uid, vers, serviceName,
+ ServiceState.SERVICE_EXEC, mExecCount, mExecState, mExecStartTime, now);
+ }
+
+ private void dumpTimeCheckin(PrintWriter pw, String label, String packageName,
+ int uid, int vers, String serviceName, int serviceType, int opCount,
+ int curState, long curStartTime, long now) {
+ if (opCount <= 0) {
+ return;
+ }
+ pw.print(label);
+ pw.print(",");
+ pw.print(packageName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(serviceName);
+ pw.print(",");
+ pw.print(opCount);
+ boolean didCurState = false;
+ final int N = mDurations.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = mDurations.getKeyAt(i);
+ long time = mDurations.getValue(key);
+ int type = SparseMappingTable.getIdFromKey(key);
+ int memFactor = type / ServiceState.SERVICE_COUNT;
+ type %= ServiceState.SERVICE_COUNT;
+ if (type != serviceType) {
+ continue;
+ }
+ if (curState == memFactor) {
+ didCurState = true;
+ time += now - curStartTime;
+ }
+ DumpUtils.printAdjTagAndValue(pw, memFactor, time);
+ }
+ if (!didCurState && curState != STATE_NOTHING) {
+ DumpUtils.printAdjTagAndValue(pw, curState, now - curStartTime);
+ }
+ pw.println();
+ }
+
+
+ public String toString() {
+ return "ServiceState{" + Integer.toHexString(System.identityHashCode(this))
+ + " " + mName + " pkg=" + mPackage + " proc="
+ + Integer.toHexString(System.identityHashCode(this)) + "}";
+ }
+}
diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
new file mode 100644
index 0000000..64c49a2
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import android.os.Build;
+import android.os.Parcel;
+import android.util.Slog;
+import libcore.util.EmptyArray;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.android.internal.util.GrowingArrayUtils;
+
+/**
+ * Class that contains a set of tables mapping byte ids to long values.
+ *
+ * This class is used to store the ProcessStats data. This data happens to be
+ * a set of very sparse tables, that is mostly append or overwrite, with infrequent
+ * resets of the data.
+ *
+ * Data is stored as a list of large long[] arrays containing the actual values. There are a
+ * set of Table objects that each contain a small array mapping the byte IDs to a position
+ * in the larger arrays.
+ *
+ * The data itself is either a single long value or a range of long values which are always
+ * stored continguously in one of the long arrays. When the caller allocates a slot with
+ * getOrAddKey, an int key is returned. That key can be re-retreived with getKey without
+ * allocating the value. The data can then be set or retrieved with that key.
+ */
+public class SparseMappingTable {
+ private static final String TAG = "SparseMappingTable";
+
+ // How big each array is.
+ public static final int ARRAY_SIZE = 4096;
+
+ public static final int INVALID_KEY = 0xffffffff;
+
+ // Where the "type"/"state" part of the data appears in an offset integer.
+ private static final int ID_SHIFT = 0;
+ private static final int ID_MASK = 0xff;
+ // Where the "which array" part of the data appears in an offset integer.
+ private static final int ARRAY_SHIFT = 8;
+ private static final int ARRAY_MASK = 0xff;
+ // Where the "index into array" part of the data appears in an offset integer.
+ private static final int INDEX_SHIFT = 16;
+ private static final int INDEX_MASK = 0xffff;
+
+ private int mSequence;
+ private int mNextIndex;
+ private final ArrayList<long[]> mLongs = new ArrayList<long[]>();
+
+ /**
+ * A table of data as stored in a SparseMappingTable.
+ */
+ public static class Table {
+ // When mSequence is this this our data better be empty
+ private static final int UNINITIALIZED_SEQUENCE = -1;
+
+ private SparseMappingTable mParent;
+ private int mSequence = UNINITIALIZED_SEQUENCE;
+ private int[] mTable;
+ private int mSize;
+
+ public Table(SparseMappingTable parent) {
+ mParent = parent;
+ mSequence = parent.mSequence;
+ }
+
+ /**
+ * Pulls the data from 'copyFrom' and stores it in our own longs table.
+ *
+ * @param copyFrom The Table to copy from
+ * @param valueCount The number of values to copy for each key
+ */
+ public void copyFrom(Table copyFrom, int valueCount) {
+ mTable = null;
+ mSize = 0;
+
+ final int N = copyFrom.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int theirKey = copyFrom.getKeyAt(i);
+ final long[] theirLongs = copyFrom.mParent.mLongs.get(getArrayFromKey(theirKey));
+
+ final byte id = SparseMappingTable.getIdFromKey(theirKey);
+
+ final int myKey = this.getOrAddKey((byte)id, valueCount);
+ final long[] myLongs = mParent.mLongs.get(getArrayFromKey(myKey));
+
+ System.arraycopy(theirLongs, getIndexFromKey(theirKey),
+ myLongs, getIndexFromKey(myKey), valueCount);
+ }
+ }
+
+ /**
+ * Allocates data in the buffer, and stores that key in the mapping for this
+ * table.
+ *
+ * @param id The id of the item (will be used in making the key)
+ * @param count The number of bytes to allocate. Must be less than
+ * SparseMappingTable.ARRAY_SIZE.
+ *
+ * @return The 'key' for this data value, which contains both the id itself
+ * and the location in the long arrays that the data is actually stored
+ * but should be considered opaque to the caller.
+ */
+ public int getOrAddKey(byte id, int count) {
+ // This is the only place we add data to mParent.mLongs, so this is the time
+ // to update our sequence to match there.
+ if (mSequence == UNINITIALIZED_SEQUENCE) {
+ mSequence = mParent.mSequence;
+ }
+
+ assertConsistency();
+
+ final int idx = binarySearch(id);
+ if (idx >= 0) {
+ // Found
+ return mTable[idx];
+ } else {
+ // Not found. Need to allocate it.
+
+ // Get an array with enough space to store 'count' values.
+ final ArrayList<long[]> list = mParent.mLongs;
+ int whichArray = list.size()-1;
+ long[] array = list.get(whichArray);
+ if (mParent.mNextIndex + count > array.length) {
+ // if it won't fit then make a new array.
+ array = new long[ARRAY_SIZE];
+ list.add(array);
+ whichArray++;
+ mParent.mNextIndex = 0;
+ }
+
+ // The key is a combination of whichArray, which index in that array, and
+ // the table value itself, which will be used for lookup
+ final int key = (whichArray << ARRAY_SHIFT)
+ | (mParent.mNextIndex << INDEX_SHIFT)
+ | (((int)id) << ID_SHIFT);
+
+ mParent.mNextIndex += count;
+
+ // Store the key in the sparse lookup table for this Table object.
+ mTable = GrowingArrayUtils.insert(mTable != null ? mTable : EmptyArray.INT,
+ mSize, ~idx, key);
+ mSize++;
+
+ return key;
+ }
+ }
+
+ /**
+ * Looks up a key in the table.
+ *
+ * @return The key from this table or INVALID_KEY if the id is not found.
+ */
+ public int getKey(byte id) {
+ assertConsistency();
+
+ final int idx = binarySearch(id);
+ if (idx >= 0) {
+ return mTable[idx];
+ } else {
+ return INVALID_KEY;
+ }
+ }
+
+ /**
+ * Get the value for the given key and offset from that key.
+ *
+ * @param key A key as obtained from getKey or getOrAddKey.
+ * @param value The value to set.
+ */
+ public long getValue(int key) {
+ return getValue(key, 0);
+ }
+
+ /**
+ * Get the value for the given key and offset from that key.
+ *
+ * @param key A key as obtained from getKey or getOrAddKey.
+ * @param index The offset from that key. Must be less than the count
+ * provided to getOrAddKey when the space was allocated.
+ * @param value The value to set.
+ *
+ * @return the value, or 0 in case of an error
+ */
+ public long getValue(int key, int index) {
+ assertConsistency();
+
+ try {
+ final long[] array = mParent.mLongs.get(getArrayFromKey(key));
+ return array[getIndexFromKey(key) + index];
+ } catch (IndexOutOfBoundsException ex) {
+ logOrThrow("key=0x" + Integer.toHexString(key)
+ + " index=" + index + " -- " + dumpInternalState(), ex);
+ return 0;
+ }
+ }
+
+ /**
+ * Set the value for the given id at offset 0 from that id.
+ * If the id is not found, return 0 instead.
+ *
+ * @param id The id of the item.
+ */
+ public long getValueForId(byte id) {
+ return getValueForId(id, 0);
+ }
+
+ /**
+ * Set the value for the given id and index offset from that id.
+ * If the id is not found, return 0 instead.
+ *
+ * @param id The id of the item.
+ * @param index The offset from that key. Must be less than the count
+ * provided to getOrAddKey when the space was allocated.
+ */
+ public long getValueForId(byte id, int index) {
+ assertConsistency();
+
+ final int idx = binarySearch(id);
+ if (idx >= 0) {
+ final int key = mTable[idx];
+ try {
+ final long[] array = mParent.mLongs.get(getArrayFromKey(key));
+ return array[getIndexFromKey(key) + index];
+ } catch (IndexOutOfBoundsException ex) {
+ logOrThrow("id=0x" + Integer.toHexString(id) + " idx=" + idx
+ + " key=0x" + Integer.toHexString(key) + " index=" + index
+ + " -- " + dumpInternalState(), ex);
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Return the raw storage long[] for the given key.
+ */
+ public long[] getArrayForKey(int key) {
+ assertConsistency();
+
+ return mParent.mLongs.get(getArrayFromKey(key));
+ }
+
+ /**
+ * Set the value for the given key and offset from that key.
+ *
+ * @param key A key as obtained from getKey or getOrAddKey.
+ * @param value The value to set.
+ */
+ public void setValue(int key, long value) {
+ setValue(key, 0, value);
+ }
+
+ /**
+ * Set the value for the given key and offset from that key.
+ *
+ * @param key A key as obtained from getKey or getOrAddKey.
+ * @param index The offset from that key. Must be less than the count
+ * provided to getOrAddKey when the space was allocated.
+ * @param value The value to set.
+ */
+ public void setValue(int key, int index, long value) {
+ assertConsistency();
+
+ if (value < 0) {
+ logOrThrow("can't store negative values"
+ + " key=0x" + Integer.toHexString(key)
+ + " index=" + index + " value=" + value
+ + " -- " + dumpInternalState());
+ return;
+ }
+
+ try {
+ final long[] array = mParent.mLongs.get(getArrayFromKey(key));
+ array[getIndexFromKey(key) + index] = value;
+ } catch (IndexOutOfBoundsException ex) {
+ logOrThrow("key=0x" + Integer.toHexString(key)
+ + " index=" + index + " value=" + value
+ + " -- " + dumpInternalState(), ex);
+ return;
+ }
+ }
+
+ /**
+ * Clear out the table, and reset the sequence numbers so future writes
+ * without allocations will assert.
+ */
+ public void resetTable() {
+ // Clear out our table.
+ mTable = null;
+ mSize = 0;
+
+ // Reset our sequence number. This will make all read/write calls
+ // start to fail, and then when we re-allocate it will be re-synced
+ // to that of mParent.
+ mSequence = UNINITIALIZED_SEQUENCE;
+ }
+
+ /**
+ * Write the keys stored in the table to the parcel. The parent must
+ * be separately written. Does not save the actual data.
+ */
+ public void writeToParcel(Parcel out) {
+ out.writeInt(mSequence);
+ out.writeInt(mSize);
+ for (int i=0; i<mSize; i++) {
+ out.writeInt(mTable[i]);
+ }
+ }
+
+ /**
+ * Read the keys from the parcel. The parent (with its long array) must
+ * have been previously initialized.
+ */
+ public boolean readFromParcel(Parcel in) {
+ // Read the state
+ mSequence = in.readInt();
+ mSize = in.readInt();
+ if (mSize != 0) {
+ mTable = new int[mSize];
+ for (int i=0; i<mSize; i++) {
+ mTable[i] = in.readInt();
+ }
+ } else {
+ mTable = null;
+ }
+
+ // Make sure we're all healthy
+ if (validateKeys(true)) {
+ return true;
+ } else {
+ // Clear it out
+ mSize = 0;
+ mTable = null;
+ return false;
+ }
+ }
+
+ /**
+ * Return the number of keys that have been added to this Table.
+ */
+ public int getKeyCount() {
+ return mSize;
+ }
+
+ /**
+ * Get the key at the given index in our table.
+ */
+ public int getKeyAt(int i) {
+ return mTable[i];
+ }
+
+ /**
+ * Throw an exception if one of a variety of internal consistency checks fails.
+ */
+ private void assertConsistency() {
+ // Assert that our sequewnce number has been initialized. If it hasn't
+ // that means someone tried to read or write data without allocating it
+ // since we were created or reset.
+ if (mSequence == UNINITIALIZED_SEQUENCE) {
+ logOrThrow("mSequence == UNINITIALIZED_SEQUENCE in"
+ + " SparseMappingTable.Table. mParent.mSequence=" + mParent.mSequence);
+ }
+
+ // Assert that our sequence number matches mParent's. If it isn't that means
+ // we have been reset and our
+ if (mSequence != mParent.mSequence) {
+ if (mSequence < mParent.mSequence) {
+ logOrThrow("Sequence mismatch. SparseMappingTable.resetTable()"
+ + " called but not Table.resetTable() -- "
+ + dumpInternalState());
+ } else if (mSequence > mParent.mSequence) {
+ logOrThrow("Sequence mismatch. Table.resetTable()"
+ + " called but not SparseMappingTable.resetTable() -- "
+ + dumpInternalState());
+ }
+ }
+ }
+
+ /**
+ * Finds the 'id' inside the array of length size (physical size of the array
+ * is not used).
+ *
+ * @return The index of the array, or the bitwise not (~index) of where it
+ * would go if you wanted to insert 'id' into the array.
+ */
+ private int binarySearch(byte id) {
+ int lo = 0;
+ int hi = mSize - 1;
+
+ while (lo <= hi) {
+ int mid = (lo + hi) >>> 1;
+ byte midId = (byte)((mTable[mid] >> ID_SHIFT) & ID_MASK);
+
+ if (midId < id) {
+ lo = mid + 1;
+ } else if (midId > id) {
+ hi = mid - 1;
+ } else {
+ return mid; // id found
+ }
+ }
+ return ~lo; // id not present
+ }
+
+ /**
+ * Check that all the keys are valid locations in the long arrays.
+ *
+ * If any aren't, log it and return false. Else return true.
+ */
+ private boolean validateKeys(boolean log) {
+ ArrayList<long[]> longs = mParent.mLongs;
+ final int longsSize = longs.size();
+
+ final int N = mSize;
+ for (int i=0; i<N; i++) {
+ final int key = mTable[i];
+ final int arrayIndex = getArrayFromKey(key);
+ final int index = getIndexFromKey(key);
+ if (arrayIndex >= longsSize || index >= longs.get(arrayIndex).length) {
+ if (log) {
+ Slog.w(TAG, "Invalid stats at index " + i + " -- " + dumpInternalState());
+ }
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public String dumpInternalState() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("SparseMappingTable.Table{mSequence=");
+ sb.append(mSequence);
+ sb.append(" mParent.mSequence=");
+ sb.append(mParent.mSequence);
+ sb.append(" mParent.mLongs.size()=");
+ sb.append(mParent.mLongs.size());
+ sb.append(" mSize=");
+ sb.append(mSize);
+ sb.append(" mTable=");
+ if (mTable == null) {
+ sb.append("null");
+ } else {
+ final int N = mTable.length;
+ sb.append('[');
+ for (int i=0; i<N; i++) {
+ final int key = mTable[i];
+ sb.append("0x");
+ sb.append(Integer.toHexString((key >> ID_SHIFT) & ID_MASK));
+ sb.append("/0x");
+ sb.append(Integer.toHexString((key >> ARRAY_SHIFT) & ARRAY_MASK));
+ sb.append("/0x");
+ sb.append(Integer.toHexString((key >> INDEX_SHIFT) & INDEX_MASK));
+ if (i != N-1) {
+ sb.append(", ");
+ }
+ }
+ sb.append(']');
+ }
+ sb.append(" clazz=");
+ sb.append(getClass().getName());
+ sb.append('}');
+
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Wipe out all the data.
+ */
+ public void reset() {
+ // Clear out mLongs, and prime it with a new array of data
+ mLongs.clear();
+ mLongs.add(new long[ARRAY_SIZE]);
+ mNextIndex = 0;
+
+ // Increment out sequence counter, because all of the tables will
+ // now be out of sync with the data.
+ mSequence++;
+ }
+
+ /**
+ * Write the data arrays to the parcel.
+ */
+ public void writeToParcel(Parcel out) {
+ out.writeInt(mSequence);
+ out.writeInt(mNextIndex);
+ final int N = mLongs.size();
+ out.writeInt(N);
+ for (int i=0; i<N-1; i++) {
+ final long[] array = mLongs.get(i);
+ out.writeInt(array.length);
+ writeCompactedLongArray(out, array, array.length);
+ }
+ // save less for the last one. upon re-loading they'll just start a new array.
+ final long[] lastLongs = mLongs.get(N-1);
+ out.writeInt(mNextIndex);
+ writeCompactedLongArray(out, lastLongs, mNextIndex);
+ }
+
+ /**
+ * Read the data arrays from the parcel.
+ */
+ public void readFromParcel(Parcel in) {
+ mSequence = in.readInt();
+ mNextIndex = in.readInt();
+
+ mLongs.clear();
+ final int N = in.readInt();
+ for (int i=0; i<N; i++) {
+ final int size = in.readInt();
+ final long[] array = new long[size];
+ readCompactedLongArray(in, array, size);
+ mLongs.add(array);
+ }
+ }
+
+ /**
+ * Write the long array to the parcel in a compacted form. Does not allow negative
+ * values in the array.
+ */
+ private static void writeCompactedLongArray(Parcel out, long[] array, int num) {
+ for (int i=0; i<num; i++) {
+ long val = array[i];
+ if (val < 0) {
+ Slog.w(TAG, "Time val negative: " + val);
+ val = 0;
+ }
+ if (val <= Integer.MAX_VALUE) {
+ out.writeInt((int)val);
+ } else {
+ int top = ~((int)((val>>32)&0x7fffffff));
+ int bottom = (int)(val&0xfffffff);
+ out.writeInt(top);
+ out.writeInt(bottom);
+ }
+ }
+ }
+
+ /**
+ * Read the compacted array into the long[].
+ */
+ private static void readCompactedLongArray(Parcel in, long[] array, int num) {
+ final int alen = array.length;
+ if (num > alen) {
+ logOrThrow("bad array lengths: got " + num + " array is " + alen);
+ return;
+ }
+ int i;
+ for (i=0; i<num; i++) {
+ int val = in.readInt();
+ if (val >= 0) {
+ array[i] = val;
+ } else {
+ int bottom = in.readInt();
+ array[i] = (((long)~val)<<32) | bottom;
+ }
+ }
+ while (i < alen) {
+ array[i] = 0;
+ i++;
+ }
+ }
+
+ /**
+ * Extract the id from a key.
+ */
+ public static byte getIdFromKey(int key) {
+ return (byte)((key >> ID_SHIFT) & ID_MASK);
+ }
+
+ /**
+ * Gets the index of the array in the list of arrays.
+ *
+ * Not to be confused with getIndexFromKey.
+ */
+ public static int getArrayFromKey(int key) {
+ return (key >> ARRAY_SHIFT) & ARRAY_MASK;
+ }
+
+ /**
+ * Gets the index of a value in a long[].
+ *
+ * Not to be confused with getArrayFromKey.
+ */
+ public static int getIndexFromKey(int key) {
+ return (key >> INDEX_SHIFT) & INDEX_MASK;
+ }
+
+ /**
+ * Do a Slog.wtf or throw an exception (thereby crashing the system process if
+ * this is a debug build.)
+ */
+ private static void logOrThrow(String message) {
+ logOrThrow(message, null);
+ }
+
+ /**
+ * Do a Slog.wtf or throw an exception (thereby crashing the system process if
+ * this is an eng build.)
+ */
+ private static void logOrThrow(String message, Throwable th) {
+ Slog.wtf(TAG, message, th);
+ if (Build.TYPE.equals("eng")) {
+ throw new RuntimeException(message, th);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/app/procstats/SysMemUsageTable.java b/core/java/com/android/internal/app/procstats/SysMemUsageTable.java
new file mode 100644
index 0000000..e71bc55
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/SysMemUsageTable.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app.procstats;
+
+import android.util.DebugUtils;
+
+import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;
+import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_SAMPLE_COUNT;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_CACHED_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_CACHED_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_CACHED_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_FREE_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_FREE_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_FREE_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_ZRAM_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_ZRAM_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_ZRAM_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_KERNEL_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_KERNEL_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_KERNEL_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_NATIVE_MINIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_NATIVE_AVERAGE;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_NATIVE_MAXIMUM;
+import static com.android.internal.app.procstats.ProcessStats.SYS_MEM_USAGE_COUNT;
+
+import java.io.PrintWriter;
+
+
+/**
+ * Class to accumulate system mem usage data.
+ */
+public class SysMemUsageTable extends SparseMappingTable.Table {
+ /**
+ * Construct the SysMemUsageTable with 'tableData' as backing store
+ * for the longs data.
+ */
+ public SysMemUsageTable(SparseMappingTable tableData) {
+ super(tableData);
+ }
+
+ /**
+ * Merge the stats given into our own values.
+ *
+ * @param that SysMemUsageTable to copy from.
+ */
+ public void mergeStats(SysMemUsageTable that) {
+ final int N = that.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = that.getKeyAt(i);
+
+ final int state = SparseMappingTable.getIdFromKey(key);
+ final long[] addData = that.getArrayForKey(key);
+ final int addOff = SparseMappingTable.getIndexFromKey(key);
+
+ mergeStats(state, addData, addOff);
+ }
+ }
+
+ /**
+ * Merge the stats given into our own values.
+ *
+ * @param state The state
+ * @param addData The data array to copy
+ * @param addOff The index in addOff to start copying from
+ */
+ public void mergeStats(int state, long[] addData, int addOff) {
+ final int key = getOrAddKey((byte)state, SYS_MEM_USAGE_COUNT);
+
+ final long[] dstData = getArrayForKey(key);
+ final int dstOff = SparseMappingTable.getIndexFromKey(key);
+
+ SysMemUsageTable.mergeSysMemUsage(dstData, dstOff, addData, addOff);
+ }
+
+ /**
+ * Return a long[] containing the merge of all of the usage in this table.
+ */
+ public long[] getTotalMemUsage() {
+ long[] total = new long[SYS_MEM_USAGE_COUNT];
+ final int N = getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = getKeyAt(i);
+
+ final long[] addData = getArrayForKey(key);
+ final int addOff = SparseMappingTable.getIndexFromKey(key);
+
+ SysMemUsageTable.mergeSysMemUsage(total, 0, addData, addOff);
+ }
+ return total;
+ }
+
+ /**
+ * Merge the stats from one raw long[] into another.
+ *
+ * @param dstData The destination array
+ * @param dstOff The index in the destination array to start from
+ * @param addData The source array
+ * @param addOff The index in the source array to start from
+ */
+ public static void mergeSysMemUsage(long[] dstData, int dstOff,
+ long[] addData, int addOff) {
+ final long dstCount = dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT];
+ final long addCount = addData[addOff+SYS_MEM_USAGE_SAMPLE_COUNT];
+ if (dstCount == 0) {
+ dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT] = addCount;
+ for (int i=SYS_MEM_USAGE_CACHED_MINIMUM; i<SYS_MEM_USAGE_COUNT; i++) {
+ dstData[dstOff+i] = addData[addOff+i];
+ }
+ } else if (addCount > 0) {
+ dstData[dstOff+SYS_MEM_USAGE_SAMPLE_COUNT] = dstCount + addCount;
+ for (int i=SYS_MEM_USAGE_CACHED_MINIMUM; i<SYS_MEM_USAGE_COUNT; i+=3) {
+ if (dstData[dstOff+i] > addData[addOff+i]) {
+ dstData[dstOff+i] = addData[addOff+i];
+ }
+ dstData[dstOff+i+1] = (long)(
+ ((dstData[dstOff+i+1]*(double)dstCount)
+ + (addData[addOff+i+1]*(double)addCount))
+ / (dstCount+addCount) );
+ if (dstData[dstOff+i+2] < addData[addOff+i+2]) {
+ dstData[dstOff+i+2] = addData[addOff+i+2];
+ }
+ }
+ }
+ }
+
+
+ public void dump(PrintWriter pw, String prefix, int[] screenStates, int[] memStates) {
+ int printedScreen = -1;
+ for (int is=0; is<screenStates.length; is++) {
+ int printedMem = -1;
+ for (int im=0; im<memStates.length; im++) {
+ final int iscreen = screenStates[is];
+ final int imem = memStates[im];
+ final int bucket = ((iscreen + imem) * STATE_COUNT);
+ long count = getValueForId((byte)bucket, SYS_MEM_USAGE_SAMPLE_COUNT);
+ if (count > 0) {
+ pw.print(prefix);
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw,
+ printedMem != imem ? imem : STATE_NOTHING, '\0');
+ printedMem = imem;
+ }
+ pw.print(": ");
+ pw.print(count);
+ pw.println(" samples:");
+ dumpCategory(pw, prefix, " Cached", bucket, SYS_MEM_USAGE_CACHED_MINIMUM);
+ dumpCategory(pw, prefix, " Free", bucket, SYS_MEM_USAGE_FREE_MINIMUM);
+ dumpCategory(pw, prefix, " ZRam", bucket, SYS_MEM_USAGE_ZRAM_MINIMUM);
+ dumpCategory(pw, prefix, " Kernel", bucket, SYS_MEM_USAGE_KERNEL_MINIMUM);
+ dumpCategory(pw, prefix, " Native", bucket, SYS_MEM_USAGE_NATIVE_MINIMUM);
+ }
+ }
+ }
+ }
+
+ private void dumpCategory(PrintWriter pw, String prefix, String label, int bucket, int index) {
+ pw.print(prefix); pw.print(label);
+ pw.print(": ");
+ DebugUtils.printSizeValue(pw, getValueForId((byte)bucket, index) * 1024);
+ pw.print(" min, ");
+ DebugUtils.printSizeValue(pw, getValueForId((byte)bucket, index + 1) * 1024);
+ pw.print(" avg, ");
+ DebugUtils.printSizeValue(pw, getValueForId((byte)bucket, index+2) * 1024);
+ pw.println(" max");
+ }
+
+}
+
+
diff --git a/core/java/com/android/internal/app/procstats/package.html b/core/java/com/android/internal/app/procstats/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/app/procstats/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 10027b6..5e8f4a2 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -27,7 +27,6 @@
import android.content.pm.PackageInfo;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
-import android.os.SELinux;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 9904893..4b695b9 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -183,6 +183,7 @@
private boolean mLastHasBottomStableInset = false;
private boolean mLastHasRightStableInset = false;
private int mLastWindowFlags = 0;
+ private boolean mLastShouldAlwaysConsumeNavBar = false;
private int mRootScrollY = 0;
@@ -996,6 +997,7 @@
boolean hasRightStableInset = insets.getStableInsetRight() != 0;
disallowAnimate |= (hasRightStableInset != mLastHasRightStableInset);
mLastHasRightStableInset = hasRightStableInset;
+ mLastShouldAlwaysConsumeNavBar = insets.shouldAlwaysConsumeNavBar();
}
boolean navBarToRightEdge = isNavBarToRightEdge(mLastBottomInset, mLastRightInset);
@@ -1016,12 +1018,11 @@
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
// to ensure that the rest of the view hierarchy doesn't notice it, unless they've
// explicitly asked for it.
-
boolean consumingNavBar =
(attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
&& (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
- || (insets != null && insets.shouldAlwaysConsumeNavBar());
+ || mLastShouldAlwaysConsumeNavBar;
// If we didn't request fullscreen layout, but we still got it because of the
// mForceWindowDrawsStatusBarBackground flag, also consume top inset.
diff --git a/core/java/com/android/internal/util/ProgressReporter.java b/core/java/com/android/internal/util/ProgressReporter.java
new file mode 100644
index 0000000..796f8ac
--- /dev/null
+++ b/core/java/com/android/internal/util/ProgressReporter.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IProgressListener;
+import android.os.RemoteException;
+import android.util.MathUtils;
+
+/**
+ * Tracks and reports progress of a single task to a {@link IProgressListener}.
+ * The reported progress of a task ranges from 0-100, but the task can be
+ * segmented into smaller pieces using {@link #startSegment(int)} and
+ * {@link #endSegment(int[])}, and segments can be nested.
+ * <p>
+ * Here's an example in action; when finished the overall task progress will be
+ * at 60.
+ *
+ * <pre>
+ * prog.setProgress(20);
+ * {
+ * final int restore = prog.startSegment(40);
+ * for (int i = 0; i < N; i++) {
+ * prog.setProgress(i, N);
+ * ...
+ * }
+ * prog.endSegment(restore);
+ * }
+ * </pre>
+ *
+ * This class is not thread safe.
+ *
+ * @hide
+ */
+public class ProgressReporter {
+ public static final ProgressReporter NO_OP = new ProgressReporter(0, null);
+
+ private final int mId;
+ private final IProgressListener mListener;
+
+ private Bundle mExtras = new Bundle();
+
+ private int mProgress = 0;
+
+ /**
+ * Current segment range: first element is starting progress of this
+ * segment, second element is length of segment.
+ */
+ private int[] mSegmentRange = new int[] { 0, 100 };
+
+ /**
+ * Create a new task with the given identifier whose progress will be
+ * reported to the given listener.
+ */
+ public ProgressReporter(int id, @Nullable IProgressListener listener) {
+ mId = id;
+ mListener = listener;
+ }
+
+ /**
+ * Set the progress of the currently active segment.
+ *
+ * @param progress Segment progress between 0-100.
+ */
+ public void setProgress(int progress) {
+ setProgress(progress, 100, null);
+ }
+
+ /**
+ * Set the progress of the currently active segment.
+ *
+ * @param progress Segment progress between 0-100.
+ */
+ public void setProgress(int progress, @Nullable CharSequence title) {
+ setProgress(progress, 100, title);
+ }
+
+ /**
+ * Set the fractional progress of the currently active segment.
+ */
+ public void setProgress(int n, int m) {
+ setProgress(n, m, null);
+ }
+
+ /**
+ * Set the fractional progress of the currently active segment.
+ */
+ public void setProgress(int n, int m, @Nullable CharSequence title) {
+ mProgress = mSegmentRange[0]
+ + MathUtils.constrain((n * mSegmentRange[1]) / m, 0, mSegmentRange[1]);
+ if (title != null) {
+ mExtras.putCharSequence(Intent.EXTRA_TITLE, title);
+ }
+ notifyProgress(mId, mProgress, mExtras);
+ }
+
+ /**
+ * Start a new inner segment that will contribute the given range towards
+ * the currently active segment. You must pass the returned value to
+ * {@link #endSegment(int[])} when finished.
+ */
+ public int[] startSegment(int size) {
+ final int[] lastRange = mSegmentRange;
+ mSegmentRange = new int[] { mProgress, (size * mSegmentRange[1] / 100) };
+ return lastRange;
+ }
+
+ /**
+ * End the current segment.
+ */
+ public void endSegment(int[] lastRange) {
+ mProgress = mSegmentRange[0] + mSegmentRange[1];
+ mSegmentRange = lastRange;
+ }
+
+ int getProgress() {
+ return mProgress;
+ }
+
+ int[] getSegmentRange() {
+ return mSegmentRange;
+ }
+
+ /**
+ * Report this entire task as being finished.
+ */
+ public void finish() {
+ notifyFinished(mId, null);
+ }
+
+ private void notifyProgress(int id, int progress, Bundle extras) {
+ if (mListener != null) {
+ try {
+ mListener.onProgress(id, progress, extras);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ public void notifyFinished(int id, Bundle extras) {
+ if (mListener != null) {
+ try {
+ mListener.onFinished(id, extras);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 3be15f3..6c1ebb4 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -16,6 +16,10 @@
package com.android.internal.view;
+import com.android.internal.annotations.GuardedBy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -23,6 +27,7 @@
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.ExtractedTextRequest;
@@ -56,11 +61,17 @@
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
private static final int DO_CLEAR_META_KEY_STATES = 130;
private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
+ private static final int DO_REPORT_FINISH = 150;
- private WeakReference<InputConnection> mInputConnection;
+ @GuardedBy("mLock")
+ @Nullable
+ private InputConnection mInputConnection;
private Looper mMainLooper;
private Handler mH;
+ private Object mLock = new Object();
+ @GuardedBy("mLock")
+ private boolean mFinished = false;
static class SomeArgs {
Object arg1;
@@ -80,12 +91,25 @@
}
}
- public IInputConnectionWrapper(Looper mainLooper, InputConnection conn) {
- mInputConnection = new WeakReference<>(conn);
+ public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
+ mInputConnection = inputConnection;
mMainLooper = mainLooper;
mH = new MyHandler(mMainLooper);
}
+ @Nullable
+ public InputConnection getInputConnection() {
+ synchronized (mLock) {
+ return mInputConnection;
+ }
+ }
+
+ protected boolean isFinished() {
+ synchronized (mLock) {
+ return mFinished;
+ }
+ }
+
abstract protected boolean isActive();
/**
@@ -198,6 +222,10 @@
seq, callback));
}
+ public void reportFinish() {
+ dispatchMessage(obtainMessage(DO_REPORT_FINISH));
+ }
+
void dispatchMessage(Message msg) {
// If we are calling this from the main thread, then we can call
// right through. Otherwise, we need to send the message to the
@@ -210,13 +238,13 @@
mH.sendMessage(msg);
}
-
+
void executeMessage(Message msg) {
switch (msg.what) {
case DO_GET_TEXT_AFTER_CURSOR: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
args.callback.setTextAfterCursor(null, args.seq);
@@ -232,7 +260,7 @@
case DO_GET_TEXT_BEFORE_CURSOR: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
args.callback.setTextBeforeCursor(null, args.seq);
@@ -248,7 +276,7 @@
case DO_GET_SELECTED_TEXT: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "getSelectedText on inactive InputConnection");
args.callback.setSelectedText(null, args.seq);
@@ -264,7 +292,7 @@
case DO_GET_CURSOR_CAPS_MODE: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
args.callback.setCursorCapsMode(0, args.seq);
@@ -280,7 +308,7 @@
case DO_GET_EXTRACTED_TEXT: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "getExtractedText on inactive InputConnection");
args.callback.setExtractedText(null, args.seq);
@@ -294,7 +322,7 @@
return;
}
case DO_COMMIT_TEXT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "commitText on inactive InputConnection");
return;
@@ -304,7 +332,7 @@
return;
}
case DO_SET_SELECTION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "setSelection on inactive InputConnection");
return;
@@ -313,7 +341,7 @@
return;
}
case DO_PERFORM_EDITOR_ACTION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "performEditorAction on inactive InputConnection");
return;
@@ -322,7 +350,7 @@
return;
}
case DO_PERFORM_CONTEXT_MENU_ACTION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "performContextMenuAction on inactive InputConnection");
return;
@@ -331,7 +359,7 @@
return;
}
case DO_COMMIT_COMPLETION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "commitCompletion on inactive InputConnection");
return;
@@ -340,7 +368,7 @@
return;
}
case DO_COMMIT_CORRECTION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "commitCorrection on inactive InputConnection");
return;
@@ -349,7 +377,7 @@
return;
}
case DO_SET_COMPOSING_TEXT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "setComposingText on inactive InputConnection");
return;
@@ -359,7 +387,7 @@
return;
}
case DO_SET_COMPOSING_REGION: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "setComposingRegion on inactive InputConnection");
return;
@@ -368,7 +396,7 @@
return;
}
case DO_FINISH_COMPOSING_TEXT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
// Note we do NOT check isActive() here, because this is safe
// for an IME to call at any time, and we need to allow it
// through to clean up our state after the IME has switched to
@@ -381,7 +409,7 @@
return;
}
case DO_SEND_KEY_EVENT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "sendKeyEvent on inactive InputConnection");
return;
@@ -391,7 +419,7 @@
return;
}
case DO_CLEAR_META_KEY_STATES: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
return;
@@ -400,7 +428,7 @@
return;
}
case DO_DELETE_SURROUNDING_TEXT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
return;
@@ -409,7 +437,7 @@
return;
}
case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
return;
@@ -418,7 +446,7 @@
return;
}
case DO_BEGIN_BATCH_EDIT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "beginBatchEdit on inactive InputConnection");
return;
@@ -427,7 +455,7 @@
return;
}
case DO_END_BATCH_EDIT: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "endBatchEdit on inactive InputConnection");
return;
@@ -436,7 +464,7 @@
return;
}
case DO_REPORT_FULLSCREEN_MODE: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null) {
Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
return;
@@ -447,7 +475,7 @@
return;
}
case DO_PERFORM_PRIVATE_COMMAND: {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "performPrivateCommand on inactive InputConnection");
return;
@@ -460,7 +488,7 @@
case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
SomeArgs args = (SomeArgs)msg.obj;
try {
- InputConnection ic = mInputConnection.get();
+ InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
args.callback.setRequestUpdateCursorAnchorInfoResult(false, args.seq);
@@ -473,6 +501,37 @@
}
return;
}
+ case DO_REPORT_FINISH: {
+ // Note that we do not need to worry about race condition here, because 1) mFinished
+ // is updated only inside this block, and 2) the code here is running on a Handler
+ // hence we assume multiple DO_REPORT_FINISH messages will not be handled at the
+ // same time.
+ if (isFinished()) {
+ return;
+ }
+ try {
+ InputConnection ic = getInputConnection();
+ // Note we do NOT check isActive() here, because this is safe
+ // for an IME to call at any time, and we need to allow it
+ // through to clean up our state after the IME has switched to
+ // another client.
+ if (ic == null) {
+ return;
+ }
+ ic.finishComposingText();
+ // TODO: Make reportFinish() public method of InputConnection to remove this
+ // check.
+ if (ic instanceof BaseInputConnection) {
+ ((BaseInputConnection) ic).reportFinish();
+ }
+ } finally {
+ synchronized (mLock) {
+ mInputConnection = null;
+ mFinished = true;
+ }
+ }
+ return;
+ }
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index bd97e5d..4738f5e 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -346,16 +346,6 @@
}
return false;
}
-
- @Override
- protected boolean onForwardingStopped() {
- final ShowableListMenu popup = getPopup();
- if (popup != null) {
- popup.dismiss();
- return true;
- }
- return false;
- }
}
public static abstract class PopupCallback {
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index f211ff2..a96b5a0 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -83,8 +83,11 @@
return false;
}
+ /**
+ * @hide
+ */
@Override
- protected void reportFinish() {
+ public void reportFinish() {
super.reportFinish();
synchronized(this) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c685b0c..c6112d9 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -193,9 +193,9 @@
$(TOP)/system/media/camera/include \
$(TOP)/system/netd/include \
external/pdfium/core/include/fpdfapi \
- external/pdfium/core/include/fpdfdoc \
external/pdfium/fpdfsdk/include \
external/pdfium/public \
+ external/pdfium \
external/skia/include/private \
external/skia/src/core \
external/skia/src/effects \
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index 0177635..2c840bd 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -196,7 +196,7 @@
return;
}
- CFX_AffineMatrix matrix;
+ CFX_Matrix matrix;
SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr);
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 6ddfacf..27f3493 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -205,11 +205,10 @@
clip.bottom = destBottom;
fxgeDevice->SetClip_Rect(&clip);
- CPDF_RenderContext* pageContext = new CPDF_RenderContext;
+ CPDF_RenderContext* pageContext = new CPDF_RenderContext(pPage);
pContext->m_pContext = pageContext;
- pageContext->Create(pPage);
- CFX_AffineMatrix matrix;
+ CFX_Matrix matrix;
if (!transform) {
pPage->GetDisplayMatrix(matrix, destLeft, destTop, destRight - destLeft,
destBottom - destTop, 0);
@@ -232,8 +231,8 @@
}
pageContext->AppendObjectList(pPage, &matrix);
- pContext->m_pRenderer = new CPDF_ProgressiveRenderer;
- pContext->m_pRenderer->Start(pageContext, fxgeDevice, renderOptions, NULL);
+ pContext->m_pRenderer = new CPDF_ProgressiveRenderer(pageContext, fxgeDevice, renderOptions);
+ pContext->m_pRenderer->Start(NULL);
fxgeDevice->RestoreState();
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 806fcc3..91f003d 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -567,6 +567,45 @@
// save context in opaque field
env->SetLongField(thiz, fields.context, (jlong)context.get());
+
+ // Update default display orientation in case the sensor is reverse-landscape
+ CameraInfo cameraInfo;
+ status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo);
+ if (rc != NO_ERROR) {
+ return rc;
+ }
+ int defaultOrientation = 0;
+ switch (cameraInfo.orientation) {
+ case 0:
+ break;
+ case 90:
+ if (cameraInfo.facing == CAMERA_FACING_FRONT) {
+ defaultOrientation = 180;
+ }
+ break;
+ case 180:
+ defaultOrientation = 180;
+ break;
+ case 270:
+ if (cameraInfo.facing != CAMERA_FACING_FRONT) {
+ defaultOrientation = 180;
+ }
+ break;
+ default:
+ ALOGE("Unexpected camera orientation %d!", cameraInfo.orientation);
+ break;
+ }
+ if (defaultOrientation != 0) {
+ ALOGV("Setting default display orientation to %d", defaultOrientation);
+ rc = camera->sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION,
+ defaultOrientation, 0);
+ if (rc != NO_ERROR) {
+ ALOGE("Unable to update default orientation: %s (%d)",
+ strerror(-rc), rc);
+ return rc;
+ }
+ }
+
return NO_ERROR;
}
diff --git a/core/res/res/layout-w600dp/preference_list_content_single.xml b/core/res/res/layout-sw600dp/preference_list_content_single.xml
similarity index 88%
rename from core/res/res/layout-w600dp/preference_list_content_single.xml
rename to core/res/res/layout-sw600dp/preference_list_content_single.xml
index d2fa5b9..88b1aa8 100644
--- a/core/res/res/layout-w600dp/preference_list_content_single.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content_single.xml
@@ -33,20 +33,22 @@
style="?attr/preferencePanelStyle"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingStart="32dip"
- android:paddingEnd="32dip"
- android:paddingTop="32dip"
- android:paddingBottom="32dip" >
+ android:layout_height="match_parent">
- <ListView android:id="@android:id/list"
+ <ListView
+ android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
- android:scrollbarAlwaysDrawVerticalTrack="true" />
+ android:scrollbarAlwaysDrawVerticalTrack="true"
+ android:paddingStart="32dip"
+ android:paddingEnd="32dip"
+ android:paddingTop="32dip"
+ android:paddingBottom="32dip"
+ android:clipToPadding="false"/>
<FrameLayout android:id="@+id/list_footer"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 41726fb..d12c8ba 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -25,63 +25,48 @@
android:maxCollapsedHeightSmall="56dp"
android:id="@id/contentPanel">
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
android:elevation="8dp"
android:paddingStart="16dp"
android:background="@color/white" >
+ <TextView android:id="@+id/profile_button"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginEnd="8dp"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
+ android:visibility="gone"
+ style="?attr/borderlessButtonStyle"
+ android:textAppearance="?attr/textAppearanceButton"
+ android:textColor="@color/material_deep_teal_500"
+ android:gravity="center_vertical"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:singleLine="true"/>
<ImageView android:id="@+id/title_icon"
android:layout_width="24dp"
android:layout_height="24dp"
- android:layout_gravity="start|center_vertical"
android:layout_marginEnd="16dp"
android:visibility="gone"
- android:scaleType="fitCenter" />
+ android:scaleType="fitCenter"
+ android:layout_below="@id/profile_button"
+ android:layout_alignParentLeft="true"
+ />
<TextView android:id="@+id/title"
- android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_weight="1"
+ android:layout_width="wrap_content"
android:textAppearance="?attr/textAppearanceMedium"
android:textSize="14sp"
android:gravity="start|center_vertical"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="12dp"
- android:paddingBottom="12dp" />
- <LinearLayout android:id="@+id/profile_button"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:layout_marginTop="4dp"
- android:layout_marginEnd="4dp"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
- android:focusable="true"
- android:visibility="gone"
- style="?attr/borderlessButtonStyle">
- <ImageView android:id="@+id/icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_gravity="start|center_vertical"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="16dp"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"
- android:scaleType="fitCenter" />
- <TextView android:id="@id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:layout_marginEnd="16dp"
- android:textAppearance="?attr/textAppearanceButton"
- android:textColor="?attr/textColorPrimary"
- android:minLines="1"
- android:maxLines="1"
- android:ellipsize="marquee" />
- </LinearLayout>
- </LinearLayout>
+ android:paddingBottom="12dp"
+ android:layout_below="@id/profile_button"
+ android:layout_toRightOf="@id/title_icon"/>
+ </RelativeLayout>
<ListView
android:layout_width="match_parent"
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 00c25e6..4b8640c 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -25,56 +25,39 @@
android:maxCollapsedHeightSmall="56dp"
android:id="@id/contentPanel">
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
android:elevation="8dp"
android:background="@color/white" >
+ <TextView android:id="@+id/profile_button"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginEnd="8dp"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
+ android:visibility="gone"
+ style="?attr/borderlessButtonStyle"
+ android:textAppearance="?attr/textAppearanceButton"
+ android:textColor="@color/material_deep_teal_500"
+ android:gravity="center_vertical"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:singleLine="true"/>
<TextView android:id="@+id/title"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
android:minHeight="56dp"
android:textAppearance="?attr/textAppearanceMedium"
android:gravity="start|center_vertical"
android:paddingStart="?attr/dialogPreferredPadding"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="8dp"
+ android:layout_below="@id/profile_button"
+ android:layout_alignParentLeft="true"
android:paddingBottom="8dp" />
- <LinearLayout android:id="@+id/profile_button"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:layout_marginTop="4dp"
- android:layout_marginEnd="4dp"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
- android:focusable="true"
- android:visibility="gone"
- style="?attr/borderlessButtonStyle">
- <ImageView android:id="@+id/icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_gravity="start|center_vertical"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="16dp"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"
- android:scaleType="fitCenter" />
- <TextView android:id="@id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:layout_marginEnd="16dp"
- android:textAppearance="?attr/textAppearanceButton"
- android:textColor="?attr/textColorPrimary"
- android:minLines="1"
- android:maxLines="1"
- android:ellipsize="marquee" />
- </LinearLayout>
- </LinearLayout>
+ </RelativeLayout>
<ListView
android:layout_width="match_parent"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index be140a5..1f958b4 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opsies"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s - %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s-%2$s%3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Interne gedeelde berging"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g>-SD-kaart"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-datastokkie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a87090a..2623053 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ተጨማሪ አማራጮች"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s፣ %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s፣ %2$s፣ %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"የውስጥ የተጋራ ማከማቻ"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD ካርድ"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ኤስዲ ካርድ"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"የዩኤስቢ አንጻፊ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 01d47cf..b828197 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1260,8 +1260,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"المزيد من الخيارات"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s، %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s، %2$s، %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"السعة التخزينية المشتركة الداخلية"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"بطاقة SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"بطاقة SD من <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"محرك أقراص USB"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 58d81b2..25a979b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Əlavə seçimlər"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Daxili paylaşılan yaddaş"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kart"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB drayv"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index b8c6fd3..3eff6f3 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1233,8 +1233,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Još opcija"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Unutrašnji deljeni memorijski prostor"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB disk"</string>
diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml
index 502e1e9..7b85628 100644
--- a/core/res/res/values-be-rBY/strings.xml
+++ b/core/res/res/values-be-rBY/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Больш налад"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Унутранае абагуленае сховішча"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-карта <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-дыск"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 62d0d372..4515e80 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Още опции"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"„%1$s“ – %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"„%1$s“, „%2$s“ – %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Вътрешно споделено хранилище"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD карта"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD карта от <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB устройство"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index cbe8eca..03faf2f 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -28,11 +28,11 @@
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> দিন"</string>
- <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
- <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
- <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা"</string>
- <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
- <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
+ <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
+ <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
+ <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা"</string>
+ <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
+ <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
<string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
<string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
<string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
@@ -829,8 +829,8 @@
<string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> এ"</string>
<string name="day" msgid="8144195776058119424">"দিন"</string>
<string name="days" msgid="4774547661021344602">"দিন"</string>
- <string name="hour" msgid="2126771916426189481">"ঘন্টা"</string>
- <string name="hours" msgid="894424005266852993">"ঘন্টা"</string>
+ <string name="hour" msgid="2126771916426189481">"ঘণ্টা"</string>
+ <string name="hours" msgid="894424005266852993">"ঘণ্টা"</string>
<string name="minute" msgid="9148878657703769868">"মি"</string>
<string name="minutes" msgid="5646001005827034509">"মিনিট"</string>
<string name="second" msgid="3184235808021478">"সেকেন্ড"</string>
@@ -848,8 +848,8 @@
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> মিনিট</item>
</plurals>
<plurals name="duration_hours" formatted="false" msgid="6826233369186668274">
- <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ঘন্টা</item>
- <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ঘন্টা</item>
+ <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ঘণ্টা</item>
+ <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ঘণ্টা</item>
</plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ভিডিও সমস্যা"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"এই ভিডিওটি এই ডিভাইসে স্ট্রিমিং করার জন্য বৈধ নয়৷"</string>
@@ -869,7 +869,7 @@
<string name="paste_as_plain_text" msgid="5427792741908010675">"প্লেইন টেক্সট হিসাবে আটকান"</string>
<string name="replace" msgid="5781686059063148930">"প্রতিস্থাপন করুন..."</string>
<string name="delete" msgid="6098684844021697789">"মুছুন"</string>
- <string name="copyUrl" msgid="2538211579596067402">"URL অনুলিপি করুন"</string>
+ <string name="copyUrl" msgid="2538211579596067402">"URL কপি করুন"</string>
<string name="selectTextMode" msgid="1018691815143165326">"পাঠ্য নির্বাচন করুন"</string>
<string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
<string name="redo" msgid="7759464876566803888">"পুনরায় করুন"</string>
@@ -1192,8 +1192,8 @@
<string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"বাড়ানোর জন্য উপরের দিকে এবং কমানোর জন্য নীচের দিকে স্লাইড করুন৷"</string>
<string name="time_picker_increment_minute_button" msgid="8865885114028614321">"মিনিট বাড়ান"</string>
<string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"মিনিট কমান"</string>
- <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ঘন্টা বাড়ান"</string>
- <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ঘন্টা কমান"</string>
+ <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ঘণ্টা বাড়ান"</string>
+ <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ঘণ্টা কমান"</string>
<string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM সেট করুন"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM সেট করুন"</string>
<string name="date_picker_increment_month_button" msgid="5369998479067934110">"মাস বাড়ান"</string>
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"আরো বিকল্প"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"অভ্যন্তরীণ শেয়ার করা সঞ্চয়স্থান"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD কার্ড"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD কার্ড"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ড্রাইভ"</string>
@@ -1453,9 +1452,9 @@
<string name="immersive_cling_description" msgid="3482371193207536040">"প্রস্থান করতে উপর থেকে নীচের দিকে সোয়াইপ করুন"</string>
<string name="immersive_cling_positive" msgid="5016839404568297683">"বুঝেছি"</string>
<string name="done_label" msgid="2093726099505892398">"সম্পন্ন হয়েছে"</string>
- <string name="hour_picker_description" msgid="6698199186859736512">"বৃত্তাকার ঘন্টা নির্বাচকের স্লাইডার"</string>
+ <string name="hour_picker_description" msgid="6698199186859736512">"বৃত্তাকার ঘণ্টা নির্বাচকের স্লাইডার"</string>
<string name="minute_picker_description" msgid="8606010966873791190">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string>
- <string name="select_hours" msgid="6043079511766008245">"ঘন্টা নির্বাচন করুন"</string>
+ <string name="select_hours" msgid="6043079511766008245">"ঘণ্টা নির্বাচন করুন"</string>
<string name="select_minutes" msgid="3974345615920336087">"মিনিট নির্বাচন করুন"</string>
<string name="select_day" msgid="7774759604701773332">"মাস এবং দিন নির্বাচন করুন"</string>
<string name="select_year" msgid="7952052866994196170">"বছর নির্বাচন করুন"</string>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index 6e7d8d2..7e9f44f 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -1233,8 +1233,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Interno dijeljena pohrana"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB disk"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 9044a1a..e59c936 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Emmagatzematge intern compartit"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Targeta SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Targeta SD de: <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unitat USB"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 8875ead..391b012 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere valgmuligheder"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Intern delt lagerplads"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort fra <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-drev"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a1183e9..d95bdda 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Weitere Optionen"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s. %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s. %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Interner gemeinsamer Speicher"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-Karte"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-Karte von <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-Speichergerät"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4e5f8fb..ce0805f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Εσωτερικός κοινόχρηστος αποθηκευτικός χώρος"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Κάρτα SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Κάρτα SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Μονάδα USB"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2484fe5..27cd9d2 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Almacenamiento interno compartido"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Tarjeta SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Tarjeta SD de <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unidad USB"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index ed5db6c..8b8f29f 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Aukera gehiago"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Barneko biltegiratze partekatua"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD txartela"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD txartela"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB unitatea"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b143038..e67e058 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینهها"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"حافظه داخلی مشترک"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"کارت SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"کارت SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"درایو USB"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8bb613e..b1ad7e7 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lisää asetuksia"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Sisäinen jaettu tallennustila"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kortti"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kortti: <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-asema"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3375e18..09993ac 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Stockage interne partagé"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Carte mémoire SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Clé USB"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 741d0e1..30ff9fb 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Espace de stockage interne partagé"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Carte SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Clé USB"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index be83dab..0d479a5 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Máis opcións"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Almacenamento compartido interno"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Tarxeta SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Tarxeta SD de <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unidade USB"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 2ce73f4..bc74c9d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1233,8 +1233,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Unutarnja dijeljena pohrana"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB pogon"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 8921e88..030975e 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Ավելի շատ ընտրանքներ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Համօգտագործվող ներքին հիշողություն"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD քարտ"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD քարտ <xliff:g id="MANUFACTURER">%s</xliff:g>-ից"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB սարքավար"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e7c706d..819ea80 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsi lainnya"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Penyimpanan bersama internal"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Kartu SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Kartu SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 5edb125..91624e7 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Fleiri valkostir"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Innbyggð samnýtt geymsla"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort frá <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-drif"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 73775a0..9937e0d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index b06434e..443c1be 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"אחסון משותף פנימי"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"כרטיס SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"כרטיס SD של <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"כונן USB"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 14d64b0..e81beb3 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"その他のオプション"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s、%2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s、%2$s、%3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"内部共有ストレージ"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SDカード"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g>製SDカード"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USBドライブ"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 92e57b7..3e463f1 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"მეტი ვარიანტები"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"შიდა გაზიარებული მეხსიერება"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD ბარათი"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ბარათი"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB დისკი"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 85621ed..342db02 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Басқа опциялар"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Ішкі ортақ қойма"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD картасы"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картасы"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB дискі"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index e9be6b6..fdee3aa 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1226,8 +1226,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ជម្រើសច្រើនទៀត"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"ឧបករណ៍ផ្ទុកដែលចែករំលែកខាងក្នុង"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"កាតអេសឌី"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"កាត SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"ឧបករណ៍ផ្ទុក USB"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 2e04419..b31b2bb 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"ಆಂತರಿಕವಾಗಿ ಹಂಚಲಾದ ಸಂಗ್ರಹಣೆ"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD ಕಾರ್ಡ್"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ಕಾರ್ಡ್"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ಡ್ರೈವ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b61df80..51418d9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"옵션 더보기"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"내부 공유 저장공간"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD 카드"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 카드"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB 드라이브"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 55b2b7c..32f3d9a 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -900,8 +900,8 @@
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s менен түзөтүү"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"Төмөнкү менен бөлүшүү"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s менен бөлүшүү"</string>
- <string name="whichSendToApplication" msgid="8272422260066642057">"Колдонуп жөнөтүү"</string>
- <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s колдонуп жөнөтүү"</string>
+ <string name="whichSendToApplication" msgid="8272422260066642057">"Колдонмо тандаңыз"</string>
+ <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s аркылуу жөнөтүү"</string>
<string name="whichHomeApplication" msgid="4307587691506919691">"Башкы бет колдонмосун тандаңыз"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Башкы бет колдонмосу катары %1$s пайдалануу"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Бул аракет үчүн демейки боюнча колдонулсун."</string>
@@ -1225,8 +1225,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Дагы параметрлер"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Бөлүшүлгөн ички сактагыч"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD карта"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB түзмөк"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 5d1c37e..94fb2db 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ໂຕເລືອກອື່ນ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນພາຍໃນ"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ແຜ່ນ SD"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ດຣ້າຍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1460b9b..c4c4fa2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Daugiau parinkčių"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Vidinė bendroji atmintis"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kortelė"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"„<xliff:g id="MANUFACTURER">%s</xliff:g>“ SD kortelė"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Atmintukas"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index c4ef82c..d9dae7a 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1226,8 +1226,7 @@
<!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
<skip />
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Внатрешно заедничко место за складирање"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"СД картичка"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> СД-картичка"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"УСБ-меморија"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 9b96501..16ededc 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"കൂടുതൽ ഓപ്ഷനുകള്"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"പങ്കിട്ട ആന്തരിക സ്റ്റോറേജ്"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD കാർഡ്"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD കാർഡ്"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ഡ്രൈവ്"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index ef34b46..0f31862 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Нэмэлт сонголтууд"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Дотоод хуваалцсан санах ой"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD карт"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD карт"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB диск"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 7baa543..9a35efd 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक पर्याय"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"अंतर्गत सामायिक केलेला संचय"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD कार्ड"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ड्राइव्ह"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index c2e3bfe..7c8ce0f 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Storan kongsi dalaman"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Kad SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Kad SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Pemacu USB"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 459eccd..b6f3c37 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1230,8 +1230,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"थप विकल्पहरू"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"साझेदारी गरिएको आन्तरिक भण्डारण"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD कार्ड"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ड्राइभ"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index f74b93c..8de9102 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ਹੋਰ ਚੋਣਾਂ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"ਅੰਦਰੂਨੀ ਸਾਂਝੀ ਕੀਤੀ ਗਈ ਸਟੋਰੇਜ"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD ਕਾਰਡ"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ਕਾਰਡ"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ਡ੍ਰਾਇਵ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6e4091a..f20e97d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Więcej opcji"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Wewnętrzna pamięć współdzielona"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Karta SD (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Dysk USB"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 62ee01c..2212f9f 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno compartilhado"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 331cd9d..6cb94c3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno partilhado"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unidade USB"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 62ee01c..2212f9f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno compartilhado"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index dd4faad..31ec3a0 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1233,8 +1233,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opțiuni"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Memorie internă comună"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Card SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Card SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Unitate USB"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4d618ac..5a79523 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Ещё"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Внутренний общий накопитель"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-карта <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-накопитель"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 5dbb922..4f34cd0 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1226,8 +1226,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"තවත් විකල්ප"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"අභ්යන්තර බෙදා ගත් ගබඩාව"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD පත"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD කාඩ්පත"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ධාවකය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 75a2129..4ba64b1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Viac možností"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Interné zdieľané úložisko"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD karta <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Disk USB"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 579880a..eb3d4e0 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1242,8 +1242,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Notranja shramba v skupni rabi"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Kartica SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Kartica SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Pogon USB"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index b39f297..94258e2 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsione të tjera"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Hapësira ruajtëse e brendshme e ndarë"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Karta SD nga <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-ja"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 74fc273..bfc22e4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1233,8 +1233,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Још опција"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Унутрашњи дељени меморијски простор"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD картица"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картица"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB диск"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 610fa07..3f2a4a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Delat internt lagringsutrymme"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-enhet"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3d4bc60d..2e1a7a4 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1226,8 +1226,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Chaguo zaidi"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Hifadhi ya ndani inayoshirikiwa"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Kadi ya SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Kadi ya SD iliyotengenezwa na <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Hifadhi ya USB"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 9411f5b..b34caed 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"மேலும் விருப்பங்கள்"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"பகிர்ந்த சேமிப்பகம் (அகம்)"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD கார்டு"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD கார்டு"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB டிரைவ்"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 353da8a..d0b6f43 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ตัวเลือกเพิ่มเติม"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"ที่จัดเก็บข้อมูลที่ใช้ร่วมกันภายใน"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"การ์ด SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"การ์ด SD ของ <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"ไดรฟ์ USB"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 41ada1c..698ae61 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Higit pang mga pagpipilian"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Internal na nakabahaging storage"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD card"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB drive"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3a04463..52c32e7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Dahili olarak paylaşılan depolama alanı"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartı"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB sürücü"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 565cdd9..41a1e82 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"مزید اختیارات"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"اندرونی اشتراک کردہ اسٹوریج"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD کارڈ"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD کارڈ"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ڈرائیو"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 1a81245..e3b9e9a 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -900,7 +900,7 @@
<string name="whichSendApplication" msgid="6902512414057341668">"Ulashish…"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"“%1$s” orqali ulashish"</string>
<string name="whichSendToApplication" msgid="8272422260066642057">"Ilovani tanlang"</string>
- <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s yordamida yuborish"</string>
+ <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s orqali yuborish"</string>
<string name="whichHomeApplication" msgid="4307587691506919691">"Bosh ilovani tanlash"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"%1$s: Bosh ilova sifatida foydalanish"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Ushbu amaldan standart sifatida foydalanish"</string>
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Ko‘proq sozlamalar"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Ichki umumiy xotira"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartasi"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB xotira"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7302f7a..76743f2 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Tùy chọn khác"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Bộ nhớ trong dùng chung"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Thẻ SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"Thẻ SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Ổ USB"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4c90e1c..3b0c075 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -899,7 +899,7 @@
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"使用%1$s编辑"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"分享方式"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"使用%1$s分享"</string>
- <string name="whichSendToApplication" msgid="8272422260066642057">"通过以下应用发送:"</string>
+ <string name="whichSendToApplication" msgid="8272422260066642057">"通过以下应用发送"</string>
<string name="whichSendToApplicationNamed" msgid="7768387871529295325">"通过1$s发送"</string>
<string name="whichHomeApplication" msgid="4307587691506919691">"选择主屏幕应用"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"将“%1$s”设为主屏幕应用"</string>
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s:%2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s - %2$s:%3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"内部共享的存储空间"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD卡"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"U 盘"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a782d40..6e62d1c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多選項"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s:%2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s - %2$s:%3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"內部共用儲存空間"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB 隨身碟"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 23d72dc..ddd486b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1224,8 +1224,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Izinketho ezingaphezulu"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <!-- no translation found for storage_internal (3570990907910199483) -->
- <skip />
+ <string name="storage_internal" msgid="3570990907910199483">"Isitoreji esabiwe sangaphakathi"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Ikhadi le-SD"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ikhadi le-SD"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"Idrayivu ye-USB"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a52c4e5..00eb81a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2846,6 +2846,11 @@
<!-- Pointer icon of a hand sign while grabbing something. -->
<enum name="grabbing" value="1021" />
</attr>
+
+ <!-- Whether this view has elements that may overlap when drawn. See
+ {@link android.view.View#forceHasOverlappingRendering(boolean)}. -->
+ <attr name="forceHasOverlappingRendering" format="boolean" />
+
</declare-styleable>
<!-- Attributes that can be assigned to a tag for a particular View. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 5716823..d1c0895 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2262,13 +2262,20 @@
<!-- Where to initially position the activity inside the available space. Uses constants
defined in {@link android.view.Gravity}. -->
<attr name="gravity" />
+ <!-- Minimal width of the activity.
+
+ <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+ activities launched in the task. That is if the root activity of a task set minimal width,
+ then the system will set the same minimal width on all other activities in the task. It
+ will also ignore any other minimal width attributes of non-root activities. -->
+ <attr name="minimalWidth" format="dimension" />
<!-- Minimal height of the activity.
<p><strong>NOTE:</strong> A task's root activity value is applied to all additional
- activities launched in the task. That is if the root activity of a task set minimal size,
- then the system will set the same minimal size on all other activities in the task. It will
- also ignore any other minimal size attributes of non-root activities. -->
- <attr name="minimalSize" format="dimension" />
+ activities launched in the task. That is if the root activity of a task set minimal height,
+ then the system will set the same minimal height on all other activities in the task. It
+ will also ignore any other minimal height attributes of non-root activities. -->
+ <attr name="minimalHeight" format="dimension" />
</declare-styleable>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7b85c7e..ac29f92 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2664,7 +2664,7 @@
<public type="attr" name="subMenuArrow" />
<public type="attr" name="defaultWidth" />
<public type="attr" name="defaultHeight" />
- <public type="attr" name="minimalSize" />
+ <public type="attr" name="minimalWidth" />
<public type="attr" name="resizeableActivity" />
<public type="attr" name="supportsPictureInPicture" />
<public type="attr" name="titleMargin" />
@@ -2709,6 +2709,8 @@
<public type="attr" name="fillType" />
<public type="attr" name="popupEnterTransition" />
<public type="attr" name="popupExitTransition" />
+ <public type="attr" name="minimalHeight" />
+ <public type="attr" name="forceHasOverlappingRendering" />
<public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
<public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 74ce753..6041f637c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -563,11 +563,11 @@
<!-- Label for the Android system components when they are shown to the user. -->
<string name="android_system_label">Android System</string>
- <!-- Label for the user owner in the intent forwarding app. [CHAR LIMIT=15] -->
- <string name="user_owner_label">Personal</string>
+ <!-- Label for the user owner in the intent forwarding app. -->
+ <string name="user_owner_label">Switch to Personal</string>
- <!-- Label for a corporate profile in the intent forwarding app. [CHAR LIMIT=15] -->
- <string name="managed_profile_label">Work</string>
+ <!-- Label for a corporate profile in the intent forwarding app. -->
+ <string name="managed_profile_label">Switch to Work</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_contacts">Contacts</string>
@@ -2904,7 +2904,9 @@
<string name="dlg_ok">OK</string>
<!-- USB_PREFERENCES: Notification for when the user connected to the charger only. This is the title -->
- <string name="usb_charging_notification_title">USB for charging</string>
+ <string name="usb_charging_notification_title">USB charging this device</string>
+ <!-- USB_PREFERENCES: Notification for when the user connects the phone to supply power to attached device. This is the title -->
+ <string name="usb_supplying_notification_title">USB supplying power to attached device</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MTP mode. This is the title -->
<string name="usb_mtp_notification_title">USB for file transfer</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in PTP mode. This is the title -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index e636bc0..6d4936c 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -311,7 +311,7 @@
<style name="TextAppearance.Material.Widget.PopupMenu.Header">
<item name="fontFamily">@string/font_family_title_material</item>
<item name="textSize">@dimen/text_size_menu_header_material</item>
- <item name="textColor">?attr/textColorSecondary</item>
+ <item name="textColor">?attr/colorAccent</item>
</style>
<style name="TextAppearance.Material.Widget.DropDownHint" parent="TextAppearance.Material.Menu" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3f46768..6526571 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1863,6 +1863,7 @@
<java-symbol type="string" name="usb_notification_message" />
<java-symbol type="string" name="usb_ptp_notification_title" />
<java-symbol type="string" name="usb_midi_notification_title" />
+ <java-symbol type="string" name="usb_supplying_notification_title" />
<java-symbol type="string" name="vpn_text" />
<java-symbol type="string" name="vpn_text_long" />
<java-symbol type="string" name="vpn_title" />
diff --git a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
index a37abf1..59ffd56 100644
--- a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
+++ b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
@@ -20,6 +20,7 @@
import android.content.res.TypedArray;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -42,6 +43,7 @@
}
@SmallTest
+ @Suppress
public void testTextAppearanceInSuggestionsPopup() {
final Activity activity = getActivity();
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index 3fbc16a..923b829 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -44,7 +44,6 @@
import android.support.test.espresso.Espresso;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.view.MotionEvent;
import android.widget.espresso.ContextMenuUtils;
@@ -98,7 +97,6 @@
}
@SmallTest
- @Suppress
public void testContextMenu() throws Exception {
final String text = "abc def ghi.";
onView(withId(R.id.textview)).perform(click());
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 91d57e7..f779d6c 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -385,6 +385,51 @@
}
@SmallTest
+ public void testSelectionHandles_bidi() throws Exception {
+ final String text = "abc \u0621\u0622\u0623 def";
+ onView(withId(R.id.textview)).perform(click());
+ onView(withId(R.id.textview)).perform(replaceText(text));
+
+ assertNoSelectionHandles();
+
+ onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0622')));
+
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .check(matches(isDisplayed()));
+ onHandleView(com.android.internal.R.id.selection_end_handle)
+ .check(matches(isDisplayed()));
+
+ onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+ final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
+ onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+ onHandleView(com.android.internal.R.id.selection_end_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
+ onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0623') + 1,
+ false));
+ onView(withId(R.id.textview)).check(hasSelection("\u0623"));
+
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0621'),
+ false));
+ onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
+ onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623"));
+
+ onHandleView(com.android.internal.R.id.selection_end_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
+ onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
+ }
+
+ @SmallTest
public void testSelectionHandles_multiLine() throws Exception {
final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
onView(withId(R.id.textview)).perform(click());
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 1dd6e17..4cecb65 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -17,6 +17,10 @@
package android.widget.espresso;
import static android.support.test.espresso.action.ViewActions.actionWithAssertions;
+
+import org.hamcrest.core.Is;
+import org.hamcrest.core.IsInstanceOf;
+
import android.graphics.Rect;
import android.support.test.espresso.PerformException;
import android.support.test.espresso.ViewAction;
@@ -29,6 +33,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.widget.Editor;
+import android.widget.Editor.HandleView;
import android.widget.TextView;
/**
@@ -311,18 +316,87 @@
* @param endIndex The index of the TextView's text to end the drag at
*/
public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex) {
- final int currentOffset = handleType == Handle.SELECTION_START ?
- textView.getSelectionStart() : textView.getSelectionEnd();
+ return dragHandle(textView, handleType, endIndex, 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.
+ */
+ public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex,
+ boolean primary) {
return actionWithAssertions(
new DragAction(
DragAction.Drag.TAP,
- new HandleCoordinates(textView, handleType, currentOffset),
- new HandleCoordinates(textView, handleType, endIndex),
+ new CurrentHandleCoordinates(textView),
+ new HandleCoordinates(textView, handleType, endIndex, primary),
Press.FINGER,
Editor.HandleView.class));
}
/**
+ * A provider of the x, y coordinates of the handle dragging point.
+ */
+ private static final class CurrentHandleCoordinates implements CoordinatesProvider {
+ // Must be larger than Editor#LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS.
+ private final TextView mTextView;
+ private final String mActionDescription;
+
+
+ public CurrentHandleCoordinates(TextView textView) {
+ mTextView = textView;
+ mActionDescription = "Could not locate handle.";
+ }
+
+ @Override
+ public float[] calculateCoordinates(View view) {
+ try {
+ return locateHandle(view);
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new PerformException.Builder()
+ .withActionDescription(mActionDescription)
+ .withViewDescription(HumanReadables.describe(view))
+ .withCause(e)
+ .build();
+ }
+ }
+
+ private float[] locateHandle(View view) {
+ final Rect bounds = new Rect();
+ view.getBoundsOnScreen(bounds);
+ final Rect visibleDisplayBounds = new Rect();
+ mTextView.getWindowVisibleDisplayFrame(visibleDisplayBounds);
+ visibleDisplayBounds.right -= 1;
+ visibleDisplayBounds.bottom -= 1;
+ if (!visibleDisplayBounds.intersect(bounds)) {
+ throw new PerformException.Builder()
+ .withActionDescription(mActionDescription
+ + " The handle is entirely out of the visible display frame of"
+ + "the TextView's window.")
+ .withViewDescription(HumanReadables.describe(view))
+ .build();
+ }
+ final float dragPointX = Math.max(Math.min(bounds.centerX(),
+ visibleDisplayBounds.right), visibleDisplayBounds.left);
+ final float verticalOffset = bounds.height() * 0.7f;
+ final float dragPointY = Math.max(Math.min(bounds.top + verticalOffset,
+ visibleDisplayBounds.bottom), visibleDisplayBounds.top);
+ return new float[] {dragPointX, dragPointY};
+ }
+ }
+
+ /**
* A provider of the x, y coordinates of the handle that points the specified text index in a
* text view.
*/
@@ -332,14 +406,17 @@
private final TextView mTextView;
private final Handle mHandleType;
private final int mIndex;
+ private final boolean mPrimary;
private final String mActionDescription;
- public HandleCoordinates(TextView textView, Handle handleType, int index) {
+ public HandleCoordinates(TextView textView, Handle handleType, int index, boolean primary) {
mTextView = textView;
mHandleType = handleType;
mIndex = index;
+ mPrimary = primary;
mActionDescription = "Could not locate " + handleType.toString()
- + " handle that points text index: " + index;
+ + " handle that points text index: " + index
+ + " (" + (primary ? "primary" : "secondary" ) + ")";
}
@Override
@@ -356,17 +433,26 @@
}
private float[] locateHandlePointsTextIndex(View view) {
+ if (!(view instanceof HandleView)) {
+ throw new PerformException.Builder()
+ .withActionDescription(mActionDescription + " The view is not a HandleView")
+ .withViewDescription(HumanReadables.describe(view))
+ .build();
+ }
+ final HandleView handleView = (HandleView) view;
final int currentOffset = mHandleType == Handle.SELECTION_START ?
mTextView.getSelectionStart() : mTextView.getSelectionEnd();
final Layout layout = mTextView.getLayout();
+
final int currentLine = layout.getLineForOffset(currentOffset);
final int targetLine = layout.getLineForOffset(mIndex);
-
+ final float currentX = handleView.getHorizontal(layout, currentOffset);
+ final float currentY = layout.getLineTop(currentLine);
final float[] currentCoordinates =
- (new TextCoordinates(currentOffset)).calculateCoordinates(mTextView);
+ TextCoordinates.convertToScreenCoordinates(mTextView, currentX, currentY);
final float[] targetCoordinates =
- (new TextCoordinates(mIndex)).calculateCoordinates(mTextView);
+ (new TextCoordinates(mIndex, mPrimary)).calculateCoordinates(mTextView);
final Rect bounds = new Rect();
view.getBoundsOnScreen(bounds);
final Rect visibleDisplayBounds = new Rect();
@@ -403,17 +489,24 @@
private static final class TextCoordinates implements CoordinatesProvider {
private final int mIndex;
+ private final boolean mPrimary;
private final String mActionDescription;
public TextCoordinates(int index) {
+ this(index, true);
+ }
+
+ public TextCoordinates(int index, boolean primary) {
mIndex = index;
- mActionDescription = "Could not locate text at index: " + mIndex;
+ mPrimary = primary;
+ mActionDescription = "Could not locate text at index: " + mIndex
+ + " (" + (primary ? "primary" : "secondary" ) + ")";
}
@Override
public float[] calculateCoordinates(View view) {
try {
- return locateTextAtIndex((TextView) view, mIndex);
+ return locateTextAtIndex((TextView) view, mIndex, mPrimary);
} catch (ClassCastException e) {
throw new PerformException.Builder()
.withActionDescription(mActionDescription)
@@ -432,19 +525,30 @@
/**
* @throws StringIndexOutOfBoundsException
*/
- private float[] locateTextAtIndex(TextView textView, int index) {
+ private float[] locateTextAtIndex(TextView textView, int index, boolean primary) {
if (index < 0 || index > textView.getText().length()) {
throw new StringIndexOutOfBoundsException(index);
}
- final int[] xy = new int[2];
- textView.getLocationOnScreen(xy);
final Layout layout = textView.getLayout();
final int line = layout.getLineForOffset(index);
- final float x = textView.getTotalPaddingLeft() - textView.getScrollX()
- + layout.getPrimaryHorizontal(index);
- final float y = textView.getTotalPaddingTop() - textView.getScrollY()
- + layout.getLineTop(line);
- return new float[]{x + xy[0], y + xy[1]};
+ return convertToScreenCoordinates(textView,
+ (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] };
}
}
}
diff --git a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
new file mode 100644
index 0000000..fbf5523
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import junit.framework.TestCase;
+
+public class ProgressReporterTest extends TestCase {
+ private ProgressReporter r;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ r = new ProgressReporter(0, null);
+ }
+
+ private void assertProgress(int expected) {
+ assertEquals(expected, r.getProgress());
+ }
+
+ private void assertRange(int start, int len) {
+ final int[] range = r.getSegmentRange();
+ assertEquals("start", start, range[0]);
+ assertEquals("len", len, range[1]);
+ }
+
+ public void testBasic() throws Exception {
+ assertProgress(0);
+
+ r.setProgress(20);
+ assertProgress(20);
+
+ r.setProgress(-20);
+ assertProgress(0);
+
+ r.setProgress(1024);
+ assertProgress(100);
+ }
+
+ public void testSegment() throws Exception {
+ r.setProgress(20);
+ assertProgress(20);
+
+ final int[] lastRange = r.startSegment(40);
+ {
+ assertProgress(20);
+
+ r.setProgress(50);
+ assertProgress(40);
+ }
+ r.endSegment(lastRange);
+ assertProgress(60);
+
+ r.setProgress(80);
+ assertProgress(80);
+ }
+
+ public void testSegmentOvershoot() throws Exception {
+ r.setProgress(20);
+ assertProgress(20);
+
+ final int[] lastRange = r.startSegment(40);
+ {
+ r.setProgress(-100, 2);
+ assertProgress(20);
+
+ r.setProgress(1, 2);
+ assertProgress(40);
+
+ r.setProgress(100, 2);
+ assertProgress(60);
+ }
+ r.endSegment(lastRange);
+ assertProgress(60);
+ }
+
+ public void testSegmentNested() throws Exception {
+ r.setProgress(20);
+ assertProgress(20);
+ assertRange(0, 100);
+
+ final int[] lastRange = r.startSegment(40);
+ assertRange(20, 40);
+ {
+ r.setProgress(50);
+ assertProgress(40);
+
+ final int[] lastRange2 = r.startSegment(25);
+ assertRange(40, 10);
+ {
+ r.setProgress(0);
+ assertProgress(40);
+
+ r.setProgress(50);
+ assertProgress(45);
+
+ r.setProgress(100);
+ assertProgress(50);
+ }
+ r.endSegment(lastRange2);
+ assertProgress(50);
+ }
+ r.endSegment(lastRange);
+ assertProgress(60);
+ }
+}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 291fdc4..0dae796 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1494,9 +1494,14 @@
}
/**
- * Get font feature settings. Default is null.
+ * Returns the font feature settings. The format is the same as the CSS
+ * font-feature-settings attribute:
+ * <a href="http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings">
+ * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings</a>
*
- * @return the paint's currently set font feature settings.
+ * @return the paint's currently set font feature settings. Default is null.
+ *
+ * @see #setFontFeatureSettings(String)
*/
public String getFontFeatureSettings() {
return mFontFeatureSettings;
@@ -1506,7 +1511,10 @@
* Set font feature settings.
*
* The format is the same as the CSS font-feature-settings attribute:
- * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings
+ * <a href="http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings">
+ * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings</a>
+ *
+ * @see #getFontFeatureSettings()
*
* @param settings the font feature settings string to use, may be null.
*/
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 3915984..4f600b4 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1198,6 +1198,8 @@
/**
* Inflate this Drawable from an XML resource optionally styled by a theme.
+ * This can't be called more than once for each Drawable. Note that framework may have called
+ * this once to create the Drawable instance from XML resource.
*
* @param r Resources used to resolve attribute values
* @param parser XML parser from which to inflate this Drawable
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 516591b..1f17851 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -266,7 +266,8 @@
tests/unit/FrameBuilderTests.cpp \
tests/unit/LeakCheckTests.cpp \
tests/unit/OpDumperTests.cpp \
- tests/unit/RecordingCanvasTests.cpp
+ tests/unit/RecordingCanvasTests.cpp \
+ tests/unit/SkiaCanvasTests.cpp
endif
include $(LOCAL_PATH)/hwui_static_deps.mk
@@ -321,6 +322,7 @@
$(hwui_test_common_src_files) \
tests/microbench/main.cpp \
tests/microbench/DisplayListCanvasBench.cpp \
+ tests/microbench/FontBench.cpp \
tests/microbench/LinearAllocatorBench.cpp \
tests/microbench/PathParserBench.cpp \
tests/microbench/ShadowBench.cpp \
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 06b712e..ea4f4eb 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -506,6 +506,22 @@
renderer.renderGlop(state, glop);
}
+void BakedOpDispatcher::onColorOp(BakedOpRenderer& renderer, const ColorOp& op, const BakedOpState& state) {
+ SkPaint paint;
+ paint.setColor(op.color);
+ paint.setXfermodeMode(op.mode);
+
+ Glop glop;
+ GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+ .setRoundRectClipState(state.roundRectClipState)
+ .setMeshUnitQuad()
+ .setFillPaint(paint, state.alpha)
+ .setTransform(Matrix4::identity(), TransformFlags::None)
+ .setModelViewMapUnitToRect(state.computedState.clipState->rect)
+ .build();
+ renderer.renderGlop(state, glop);
+}
+
void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op, const BakedOpState& state) {
renderer.renderFunctor(op, state);
}
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index fae8e48..b1314fe 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -572,6 +572,12 @@
deferOvalOp(*resolvedOp);
}
+void FrameBuilder::deferColorOp(const ColorOp& op) {
+ BakedOpState* bakedState = tryBakeUnboundedOpState(op);
+ if (!bakedState) return; // quick rejected
+ currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
+}
+
void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
BakedOpState* bakedState = tryBakeUnboundedOpState(op);
if (!bakedState) return; // quick rejected
@@ -693,7 +699,17 @@
void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) {
if (CC_UNLIKELY(!op.layer->isRenderable())) return;
- BakedOpState* bakedState = tryBakeOpState(op);
+
+ const TextureLayerOp* textureLayerOp = &op;
+ // Now safe to access transform (which was potentially unready at record time)
+ if (!op.layer->getTransform().isIdentity()) {
+ // non-identity transform present, so 'inject it' into op by copying + replacing matrix
+ Matrix4 combinedMatrix(op.localMatrix);
+ combinedMatrix.multiply(op.layer->getTransform());
+ textureLayerOp = mAllocator.create<TextureLayerOp>(op, combinedMatrix);
+ }
+ BakedOpState* bakedState = tryBakeOpState(*textureLayerOp);
+
if (!bakedState) return; // quick rejected
currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::TextureLayer);
}
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 2246cf9c..76e587e 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -244,7 +244,7 @@
int64_t totalDuration =
frame[FrameInfoIndex::FrameCompleted] - frame[FrameInfoIndex::IntendedVsync];
uint32_t framebucket = frameCountIndexForFrameTime(
- totalDuration, mData->frameCounts.size());
+ totalDuration, mData->frameCounts.size() - 1);
// Keep the fast path as fast as possible.
if (CC_LIKELY(totalDuration < mFrameInterval)) {
mData->frameCounts[framebucket]++;
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 96a57b6..0271a80 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -90,6 +90,7 @@
UNMERGEABLE_OP_FN(ArcOp) \
UNMERGEABLE_OP_FN(BitmapMeshOp) \
UNMERGEABLE_OP_FN(BitmapRectOp) \
+ UNMERGEABLE_OP_FN(ColorOp) \
UNMERGEABLE_OP_FN(FunctorOp) \
UNMERGEABLE_OP_FN(LinesOp) \
UNMERGEABLE_OP_FN(OvalOp) \
@@ -256,6 +257,16 @@
const float* radius;
};
+struct ColorOp : RecordedOp {
+ // Note: unbounded op that will fillclip, so no bounds/matrix needed
+ ColorOp(const ClipBase* localClip, int color, SkXfermode::Mode mode)
+ : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
+ , color(color)
+ , mode(mode) {}
+ const int color;
+ const SkXfermode::Mode mode;
+};
+
struct FunctorOp : RecordedOp {
// Note: undefined record-time bounds, since this op fills the clip
// TODO: explicitly define bounds
@@ -408,6 +419,14 @@
TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer)
: SUPER_PAINTLESS(TextureLayerOp)
, layer(layer) {}
+
+ // Copy an existing TextureLayerOp, replacing the underlying matrix
+ TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix)
+ : RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix,
+ op.localClip, op.paint)
+ , layer(op.layer) {
+
+ }
Layer* layer;
};
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 4eeadb7..4f9cd68 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -234,10 +234,10 @@
// android/graphics/Canvas draw operations
// ----------------------------------------------------------------------------
void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) {
- SkPaint paint;
- paint.setColor(color);
- paint.setXfermodeMode(mode);
- drawPaint(paint);
+ addOp(alloc().create_trivial<ColorOp>(
+ getRecordedClip(),
+ color,
+ mode));
}
void RecordingCanvas::drawPaint(const SkPaint& paint) {
@@ -576,15 +576,9 @@
// Note that the backing layer has *not* yet been updated, so don't trust
// its width, height, transform, etc...!
- Matrix4 totalTransform(*(mState.currentSnapshot()->transform));
- if (layerHandle->getTransform()) {
- Matrix4 layerTransform(*layerHandle->getTransform());
- totalTransform.multiply(layerTransform);
- }
-
addOp(alloc().create_trivial<TextureLayerOp>(
Rect(layerHandle->getWidth(), layerHandle->getHeight()),
- totalTransform,
+ *(mState.currentSnapshot()->transform),
getRecordedClip(),
layerHandle->backingLayer()));
}
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index c612480..9df32b28 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -318,12 +318,17 @@
posArray = pointStorage.get();
}
- // compute conservative bounds
- // NOTE: We could call the faster paint.getFontBounds for a less accurate,
- // but even more conservative bounds if this is too slow.
+ // Compute conservative bounds. If the content has already been processed
+ // by Minikin then it had already computed these bounds. Unfortunately,
+ // there is no way to capture those bounds as part of the Skia drawPosText
+ // API so we need to do that computation again here.
SkRect bounds;
- glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
- bounds.offset(x, y);
+ for (int i = 0; i < glyphs.count; i++) {
+ SkRect glyphBounds;
+ glyphs.paint.measureText(&glyphs.glyphIDs[i], sizeof(uint16_t), &glyphBounds);
+ glyphBounds.offset(pos[i].fX, pos[i].fY);
+ bounds.join(glyphBounds);
+ }
static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 9a825fd..8e04c87 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -356,8 +356,6 @@
}
void Font::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs) {
- ATRACE_NAME("Precache Glyphs");
-
if (numGlyphs == 0 || glyphs == nullptr) {
return;
}
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 059e9ae..c762eed 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -44,6 +44,7 @@
renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
const SkMatrix& transform) {
Layer* layer = LayerRenderer::createTextureLayer(renderThread.renderState());
+ layer->getTransform().load(transform);
sp<DeferredLayerUpdater> layerUpdater = new DeferredLayerUpdater(layer);
layerUpdater->setSize(width, height);
diff --git a/libs/hwui/tests/microbench/FontBench.cpp b/libs/hwui/tests/microbench/FontBench.cpp
new file mode 100644
index 0000000..df3d041
--- /dev/null
+++ b/libs/hwui/tests/microbench/FontBench.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <benchmark/benchmark.h>
+
+#include "GammaFontRenderer.h"
+#include "tests/common/TestUtils.h"
+
+#include <SkPaint.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+void BM_FontRenderer_precache_cachehits(benchmark::State& state) {
+ TestUtils::runOnRenderThread([&state](renderthread::RenderThread& thread) {
+ SkPaint paint;
+ paint.setTextSize(20);
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ GammaFontRenderer gammaFontRenderer;
+ FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer();
+ fontRenderer.setFont(&paint, SkMatrix::I());
+
+ std::vector<glyph_t> glyphs;
+ std::vector<float> positions;
+ float totalAdvance;
+ uirenderer::Rect bounds;
+ TestUtils::layoutTextUnscaled(paint, "This is a test",
+ &glyphs, &positions, &totalAdvance, &bounds);
+
+ fontRenderer.precache(&paint, glyphs.data(), glyphs.size(), SkMatrix::I());
+
+ while (state.KeepRunning()) {
+ fontRenderer.precache(&paint, glyphs.data(), glyphs.size(), SkMatrix::I());
+ }
+ });
+}
+BENCHMARK(BM_FontRenderer_precache_cachehits);
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index 9daf633..0aef620 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -113,15 +113,17 @@
};
void BM_FrameBuilder_defer_scene(benchmark::State& state) {
- const char* sceneName = *(SCENES.begin() + state.range_x());
- state.SetLabel(sceneName);
- auto nodes = getSyncedSceneNodes(sceneName);
- while (state.KeepRunning()) {
- FrameBuilder frameBuilder(sEmptyLayerUpdateQueue,
- SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
- nodes, sLightGeometry, Caches::getInstance());
- benchmark::DoNotOptimize(&frameBuilder);
- }
+ TestUtils::runOnRenderThread([&state](RenderThread& thread) {
+ const char* sceneName = *(SCENES.begin() + state.range_x());
+ state.SetLabel(sceneName);
+ auto nodes = getSyncedSceneNodes(sceneName);
+ while (state.KeepRunning()) {
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue,
+ SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
+ nodes, sLightGeometry, Caches::getInstance());
+ benchmark::DoNotOptimize(&frameBuilder);
+ }
+ });
}
BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1);
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index ba22d91..e97aaa6 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -372,8 +372,8 @@
EXPECT_EQ(3, renderer.getIndex()) << "Expect 3 ops";
}
-RENDERTHREAD_TEST(FrameBuilder, textureLayer) {
- class TextureLayerTestRenderer : public TestRendererBase {
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_clipLocalMatrix) {
+ class TextureLayerClipLocalMatrixTestRenderer : public TestRendererBase {
public:
void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
EXPECT_EQ(0, mIndex++);
@@ -398,11 +398,56 @@
});
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
- TextureLayerTestRenderer renderer;
+ TextureLayerClipLocalMatrixTestRenderer renderer;
frameBuilder.replayBakedOps<TestDispatcher>(renderer);
EXPECT_EQ(1, renderer.getIndex());
}
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_combineMatrices) {
+ class TextureLayerCombineMatricesTestRenderer : public TestRendererBase {
+ public:
+ void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(0, mIndex++);
+
+ Matrix4 expected;
+ expected.loadTranslate(35, 45, 0);
+ EXPECT_MATRIX_APPROX_EQ(expected, state.computedState.transform);
+ }
+ };
+
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+
+ auto node = TestUtils::createNode(0, 0, 200, 200,
+ [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.translate(30, 40);
+ canvas.drawLayer(layerUpdater.get());
+ canvas.restore();
+ });
+
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+ TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+ TextureLayerCombineMatricesTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(1, renderer.getIndex());
+}
+
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_reject) {
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+ layerUpdater->backingLayer()->setRenderTarget(GL_NONE); // Should be rejected
+
+ auto node = TestUtils::createNode(0, 0, 200, 200,
+ [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.drawLayer(layerUpdater.get());
+ });
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+ TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+ FailRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+}
+
RENDERTHREAD_TEST(FrameBuilder, functor_reject) {
class FunctorTestRenderer : public TestRendererBase {
public:
@@ -427,7 +472,31 @@
EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected";
}
-RENDERTHREAD_TEST(FrameBuilder, renderNode) {
+RENDERTHREAD_TEST(FrameBuilder, deferColorOp_unbounded) {
+ class ColorTestRenderer : public TestRendererBase {
+ public:
+ void onColorOp(const ColorOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(0, mIndex++);
+ EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds)
+ << "Color op should be expanded to bounds of surrounding";
+ }
+ };
+
+ auto unclippedColorView = TestUtils::createNode(0, 0, 10, 10,
+ [](RenderProperties& props, RecordingCanvas& canvas) {
+ props.setClipToBounds(false);
+ canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+ });
+
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+ TestUtils::createSyncedNodeList(unclippedColorView),
+ sLightGeometry, Caches::getInstance());
+ ColorTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(1, renderer.getIndex()) << "ColorOp should not be rejected";
+}
+
+TEST(FrameBuilder, renderNode) {
class RenderNodeTestRenderer : public TestRendererBase {
public:
void onRectOp(const RectOp& op, const BakedOpState& state) override {
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 42dabd3..58376c6 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include <DeferredLayerUpdater.h>
#include <RecordedOp.h>
#include <RecordingCanvas.h>
#include <hwui/Paint.h>
@@ -39,6 +40,12 @@
}
}
+static void validateSingleOp(std::unique_ptr<DisplayList>& dl,
+ std::function<void(const RecordedOp& op)> opValidator) {
+ ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
+ opValidator(*(dl->getOps()[0]));
+}
+
TEST(RecordingCanvas, emptyPlayback) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
canvas.save(SaveFlags::MatrixClip);
@@ -226,9 +233,9 @@
ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
auto op = *(dl->getOps()[0]);
- EXPECT_EQ(RecordedOpId::RectOp, op.opId);
+ EXPECT_EQ(RecordedOpId::ColorOp, op.opId);
EXPECT_EQ(nullptr, op.localClip);
- EXPECT_TRUE(op.unmappedBounds.contains(Rect(200, 200))) << "Expect recording/clip bounds";
+ EXPECT_TRUE(op.unmappedBounds.isEmpty()) << "Expect undefined recorded bounds";
}
TEST(RecordingCanvas, backgroundAndImage) {
@@ -284,6 +291,21 @@
ASSERT_EQ(2, count);
}
+RENDERTHREAD_TEST(RecordingCanvas, textureLayer) {
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200,
+ [&layerUpdater](RecordingCanvas& canvas) {
+ canvas.drawLayer(layerUpdater.get());
+ });
+
+ validateSingleOp(dl, [] (const RecordedOp& op) {
+ ASSERT_EQ(RecordedOpId::TextureLayerOp, op.opId);
+ ASSERT_TRUE(op.localMatrix.isIdentity()) << "Op must not apply matrix at record time.";
+ });
+}
+
TEST(RecordingCanvas, saveLayer_simple) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
canvas.saveLayerAlpha(10, 20, 190, 180, 128, SaveFlags::ClipToLayer);
@@ -596,6 +618,15 @@
EXPECT_NE(&paint, ops[2]->paint);
}
+TEST(RecordingCanvas, refBitmap) {
+ SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
+ canvas.drawBitmap(bitmap, 0, 0, nullptr);
+ });
+ auto& bitmaps = dl->getBitmapResources();
+ EXPECT_EQ(1u, bitmaps.size());
+}
+
TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index 586625b..875e260 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -41,3 +41,10 @@
EXPECT_EQ(SkShader::kRepeat_TileMode, xy[1]);
EXPECT_EQ(origBitmap.pixelRef(), bitmap.pixelRef());
}
+
+TEST(SkiaBehavior, genIds) {
+ SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+ uint32_t genId = bitmap.getGenerationID();
+ bitmap.notifyPixelsChanged();
+ EXPECT_NE(genId, bitmap.getGenerationID());
+}
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
new file mode 100644
index 0000000..5a01193
--- /dev/null
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tests/common/TestUtils.h"
+
+#include <gtest/gtest.h>
+#include <RecordingCanvas.h>
+#include <SkPicture.h>
+#include <SkPictureRecorder.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+/**
+ * Verify that we get the same culling bounds for text for (1) drawing glyphs
+ * directly to a Canvas or (2) going through a SkPicture as an intermediate step.
+ */
+TEST(SkiaCanvasProxy, drawGlyphsViaPicture) {
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+ // setup test variables
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(20);
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ static const char* text = "testing text bounds";
+
+ // draw text directly into Recording canvas
+ TestUtils::drawUtf8ToCanvas(&canvas, text, paint, 25, 25);
+
+ // record the same text draw into a SkPicture and replay it into a Recording canvas
+ SkPictureRecorder recorder;
+ SkCanvas* skCanvas = recorder.beginRecording(200, 200, NULL, 0);
+ std::unique_ptr<Canvas> pictCanvas(Canvas::create_canvas(skCanvas));
+ TestUtils::drawUtf8ToCanvas(pictCanvas.get(), text, paint, 25, 25);
+ SkAutoTUnref<const SkPicture> picture(recorder.endRecording());
+
+ canvas.asSkCanvas()->drawPicture(picture);
+ });
+
+ // verify that the text bounds and matrices match
+ ASSERT_EQ(2U, dl->getOps().size());
+ auto directOp = dl->getOps()[0];
+ auto pictureOp = dl->getOps()[1];
+ ASSERT_EQ(RecordedOpId::TextOp, directOp->opId);
+ EXPECT_EQ(directOp->opId, pictureOp->opId);
+ EXPECT_EQ(directOp->unmappedBounds, pictureOp->unmappedBounds);
+ EXPECT_EQ(directOp->localMatrix, pictureOp->localMatrix);
+}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 17ce533..d78ccee 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -81,41 +81,42 @@
*/
public static final int MULTIPATH_INDICATOR_NOT_USED = 2;
- /**
- * The state of GNSS receiver the measurement is invalid or unknown.
- */
+ /** This GNSS measurement's tracking state is invalid or unknown. */
public static final int STATE_UNKNOWN = 0;
-
- /**
- * The state of the GNSS receiver is ranging code lock.
- */
+ /** This GNSS measurement's tracking state has code lock. */
public static final int STATE_CODE_LOCK = (1<<0);
-
- /**
- * The state of the GNSS receiver is in bit sync.
- */
+ /** This GNSS measurement's tracking state has bit sync. */
public static final int STATE_BIT_SYNC = (1<<1);
-
- /**
- *The state of the GNSS receiver is in sub-frame sync.
- */
+ /** This GNSS measurement's tracking state has sub-frame sync. */
public static final int STATE_SUBFRAME_SYNC = (1<<2);
-
- /**
- * The state of the GNSS receiver has TOW decoded.
- */
+ /** This GNSS measurement's tracking state has time-of-week decoded. */
public static final int STATE_TOW_DECODED = (1<<3);
-
- /**
- * The state of the GNSS receiver contains millisecond ambiguity.
- */
+ /** This GNSS measurement's tracking state contains millisecond ambiguity. */
public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
+ /** This GNSS measurement's tracking state has symbol sync. */
+ public static final int STATE_SYMBOL_SYNC = (1<<5);
+ /** This Glonass measurement's tracking state has string sync. */
+ public static final int STATE_GLO_STRING_SYNC = (1<<6);
+ /** This Glonass measurement's tracking state has time-of-day decoded. */
+ public static final int STATE_GLO_TOD_DECODED = (1<<7);
+ /** This Beidou measurement's tracking state has D2 bit sync. */
+ public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
+ /** This Beidou measurement's tracking state has D2 sub-frame sync. */
+ public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
+ /** This Galileo measurement's tracking state has E1B/C code lock. */
+ public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
+ /** This Galileo measurement's tracking state has E1C secondary code lock. */
+ public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
+ /** This Galileo measurement's tracking state has E1B page sync. */
+ public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
+ /** This SBAS measurement's tracking state has whole second level sync. */
+ public static final int STATE_SBAS_SYNC = (1<<13);
/**
- * All the GNSS receiver state flags.
+ * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
+ * individual measurement.)
*/
- private static final int STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
- | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
+ private static final int STATE_ALL = 0x3fff; // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
/**
* The state of the 'Accumulated Delta Range' is invalid or unknown.
@@ -276,29 +277,58 @@
if (mState == STATE_UNKNOWN) {
return "Unknown";
}
+
StringBuilder builder = new StringBuilder();
- if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
+ if ((mState & STATE_CODE_LOCK) != 0) {
builder.append("CodeLock|");
}
- if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
+ if ((mState & STATE_BIT_SYNC) != 0) {
builder.append("BitSync|");
}
- if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
+ if ((mState & STATE_SUBFRAME_SYNC) != 0) {
builder.append("SubframeSync|");
}
- if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
+ if ((mState & STATE_TOW_DECODED) != 0) {
builder.append("TowDecoded|");
}
- if ((mState & STATE_MSEC_AMBIGUOUS) == STATE_MSEC_AMBIGUOUS) {
- builder.append("MsecAmbiguous");
+ if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
+ builder.append("MsecAmbiguous|");
}
+ if ((mState & STATE_SYMBOL_SYNC) != 0) {
+ builder.append("SymbolSync|");
+ }
+ if ((mState & STATE_GLO_STRING_SYNC) != 0) {
+ builder.append("GloStringSync|");
+ }
+ if ((mState & STATE_GLO_TOD_DECODED) != 0) {
+ builder.append("GloTodDecoded|");
+ }
+ if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
+ builder.append("BdsD2BitSync|");
+ }
+ if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
+ builder.append("BdsD2SubframeSync|");
+ }
+ if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
+ builder.append("GalE1bcCodeLock|");
+ }
+ if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
+ builder.append("E1c2ndCodeLock|");
+ }
+ if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
+ builder.append("GalE1bPageSync|");
+ }
+ if ((mState & STATE_SBAS_SYNC) != 0) {
+ builder.append("SbasSync|");
+ }
+
int remainingStates = mState & ~STATE_ALL;
if (remainingStates > 0) {
builder.append("Other(");
builder.append(Integer.toBinaryString(remainingStates));
builder.append(")|");
}
- builder.deleteCharAt(builder.length() - 1);
+ builder.setLength(builder.length() - 1);
return builder.toString();
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d9caf03..b6ff41e 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1120,7 +1120,7 @@
* <p> See also {@link AudioManager#getProperty(String)} for key
* {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
* @return current size in frames of the <code>AudioTrack</code> buffer.
- * @throws IllegalStateException
+ * @throws IllegalStateException if track is not initialized.
*/
public int getBufferSizeInFrames() {
return native_get_buffer_size_frames();
@@ -1147,7 +1147,7 @@
* @param bufferSizeInFrames requested buffer size
* @return the actual buffer size in frames or an error code,
* {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
- * @throws IllegalStateException
+ * @throws IllegalStateException if track is not initialized.
*/
public int setBufferSizeInFrames(int bufferSizeInFrames) {
if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
@@ -1176,7 +1176,7 @@
* <p> See also {@link AudioManager#getProperty(String)} for key
* {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
* @return maximum size in frames of the <code>AudioTrack</code> buffer.
- * @throws IllegalStateException
+ * @throws IllegalStateException if track is not initialized.
*/
public int getBufferCapacityInFrames() {
return native_get_buffer_capacity_frames();
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index aa99248..d0ef37c 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -358,9 +358,10 @@
/**
* Returns object size in 64-bit integer.
*
- * The object size stored in MtpObjectInfo is unsigned 32-bit integer.
- * The methods reads 64-bit object size from the object property so that it can fetch 4GB+
- * object size correctly.
+ * Though MtpObjectInfo#getCompressedSize returns the object size in 32-bit unsigned integer,
+ * this method returns the object size in 64-bit integer from the object property. Thus it can
+ * fetch 4GB+ object size correctly. If the device does not support objectSize property, it
+ * throws IOException.
* @hide
*/
public long getObjectSizeLong(int handle, int format) throws IOException {
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index f7c6770..6e434b2 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -701,6 +701,8 @@
device->discardEventRequest(seq);
}
+// Returns object size in 64-bit integer. If the MTP device does not support the property, it
+// throws IOException.
static jlong android_mtp_MtpDevice_get_object_size_long(
JNIEnv *env, jobject thiz, jint handle, jint format) {
MtpDevice* const device = get_device_from_object(env, thiz);
diff --git a/packages/DocumentsUI/perf-tests/Android.mk b/packages/DocumentsUI/perf-tests/Android.mk
index 11c163b..919fc56 100644
--- a/packages/DocumentsUI/perf-tests/Android.mk
+++ b/packages/DocumentsUI/perf-tests/Android.mk
@@ -11,7 +11,7 @@
../tests/src/com/android/documentsui/StubProvider.java
LOCAL_JAVA_LIBRARIES := android-support-v4 android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator ub-janktesthelper
LOCAL_PACKAGE_NAME := DocumentsUIPerfTests
LOCAL_INSTRUMENTATION_FOR := DocumentsUI
diff --git a/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesJankPerfTest.java b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesJankPerfTest.java
new file mode 100644
index 0000000..cb2d904
--- /dev/null
+++ b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesJankPerfTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StressProvider.DEFAULT_AUTHORITY;
+import static com.android.documentsui.StressProvider.STRESS_ROOT_0_ID;
+import static com.android.documentsui.StressProvider.STRESS_ROOT_2_ID;
+
+import android.app.Activity;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import android.content.Intent;
+import android.content.Context;
+import android.support.test.jank.JankTest;
+import android.support.test.jank.JankTestBase;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.jank.GfxMonitor;
+import android.support.test.uiautomator.UiScrollable;
+import android.util.Log;
+
+import com.android.documentsui.FilesActivity;
+import com.android.documentsui.bots.RootsListBot;
+import com.android.documentsui.bots.DirectoryListBot;
+
+@LargeTest
+public class FilesJankPerfTest extends JankTestBase {
+ private static final String DOCUMENTSUI_PACKAGE = "com.android.documentsui";
+ private static final int MAX_FLINGS = 10;
+ private static final int BOT_TIMEOUT = 5000;
+
+ private RootsListBot mRootsListBot;
+ private DirectoryListBot mDirListBot;
+ private Activity mActivity = null;
+
+ public void setUpInLoop() {
+ final UiDevice device = UiDevice.getInstance(getInstrumentation());
+ final Context context = getInstrumentation().getTargetContext();
+ mRootsListBot = new RootsListBot(device, context, BOT_TIMEOUT);
+ mDirListBot = new DirectoryListBot(device, context, BOT_TIMEOUT);
+
+ final Intent intent = new Intent(context, FilesActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mActivity = getInstrumentation().startActivitySync(intent);
+ }
+
+ public void tearDownInLoop() {
+ if (mActivity != null) {
+ mActivity.finish();
+ mActivity = null;
+ }
+ }
+
+ public void setupAndOpenInLoop() throws Exception {
+ setUpInLoop();
+ openRoot();
+ }
+
+ public void openRoot() throws Exception {
+ mRootsListBot.openRoot(STRESS_ROOT_2_ID);
+ }
+
+ @JankTest(expectedFrames=0, beforeLoop="setUpInLoop", afterLoop="tearDownInLoop")
+ @GfxMonitor(processName=DOCUMENTSUI_PACKAGE)
+ public void testOpenRootJankPerformance() throws Exception {
+ openRoot();
+ getInstrumentation().waitForIdleSync();
+ }
+
+ @JankTest(expectedFrames=0, beforeLoop="setupAndOpenInLoop", afterLoop="tearDownInLoop")
+ @GfxMonitor(processName=DOCUMENTSUI_PACKAGE)
+ public void testFlingJankPerformance() throws Exception {
+ new UiScrollable(mDirListBot.findDocumentsList().getSelector()).flingToEnd(MAX_FLINGS);
+ getInstrumentation().waitForIdleSync();
+ }
+}
diff --git a/packages/DocumentsUI/perf-tests/src/com/android/documentsui/StressProvider.java b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/StressProvider.java
index 1bc802a..6147a71 100644
--- a/packages/DocumentsUI/perf-tests/src/com/android/documentsui/StressProvider.java
+++ b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/StressProvider.java
@@ -32,7 +32,9 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
/**
@@ -46,11 +48,21 @@
// Empty root.
public static final String STRESS_ROOT_0_ID = "STRESS_ROOT_0";
- // Root with thousands of items.
+ // Root with thousands of directories.
public static final String STRESS_ROOT_1_ID = "STRESS_ROOT_1";
+ // Root with hundreds of files.
+ public static final String STRESS_ROOT_2_ID = "STRESS_ROOT_2";
+
private static final String STRESS_ROOT_0_DOC_ID = "STRESS_ROOT_0_DOC";
private static final String STRESS_ROOT_1_DOC_ID = "STRESS_ROOT_1_DOC";
+ private static final String STRESS_ROOT_2_DOC_ID = "STRESS_ROOT_2_DOC";
+
+ private static final int STRESS_ROOT_1_ITEMS = 10000;
+ private static final int STRESS_ROOT_2_ITEMS = 300;
+
+ private static final String MIME_TYPE_IMAGE = "image/jpeg";
+ private static final long REFERENCE_TIMESTAMP = 1459159369359L;
private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID,
@@ -62,7 +74,12 @@
};
private String mAuthority = DEFAULT_AUTHORITY;
- private ArrayList<String> mIds = new ArrayList<>();
+
+ // Map from a root document id to children document ids.
+ private Map<String, ArrayList<StubDocument>> mChildDocuments = new HashMap<>();
+
+ private Map<String, StubDocument> mDocuments = new HashMap<>();
+ private Map<String, StubRoot> mRoots = new HashMap<>();
@Override
public void attachInfo(Context context, ProviderInfo info) {
@@ -72,20 +89,41 @@
@Override
public boolean onCreate() {
- mIds = new ArrayList();
- for (int i = 0; i < 10000; i++) {
- mIds.add(createRandomId(i));
+ StubDocument document;
+
+ ArrayList<StubDocument> children = new ArrayList<StubDocument>();
+ mChildDocuments.put(STRESS_ROOT_1_DOC_ID, children);
+ for (int i = 0; i < STRESS_ROOT_1_ITEMS; i++) {
+ document = StubDocument.createDirectory(i);
+ mDocuments.put(document.id, document);
+ children.add(document);
}
- mIds.add(STRESS_ROOT_0_DOC_ID);
- mIds.add(STRESS_ROOT_1_DOC_ID);
+
+ children = new ArrayList<StubDocument>();
+ mChildDocuments.put(STRESS_ROOT_2_DOC_ID, children);
+ for (int i = 0; i < STRESS_ROOT_2_ITEMS; i++) {
+ document = StubDocument.createFile(STRESS_ROOT_1_ITEMS + i);
+ mDocuments.put(document.id, document);
+ children.add(document);
+ }
+
+ mRoots.put(STRESS_ROOT_0_ID, new StubRoot(STRESS_ROOT_0_ID, STRESS_ROOT_0_DOC_ID));
+ mRoots.put(STRESS_ROOT_1_ID, new StubRoot(STRESS_ROOT_1_ID, STRESS_ROOT_1_DOC_ID));
+ mRoots.put(STRESS_ROOT_2_ID, new StubRoot(STRESS_ROOT_2_ID, STRESS_ROOT_2_DOC_ID));
+
+ mDocuments.put(STRESS_ROOT_0_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_0_DOC_ID));
+ mDocuments.put(STRESS_ROOT_1_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_1_DOC_ID));
+ mDocuments.put(STRESS_ROOT_2_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_2_DOC_ID));
+
return true;
}
@Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(DEFAULT_ROOT_PROJECTION);
- includeRoot(result, STRESS_ROOT_0_ID, STRESS_ROOT_0_DOC_ID);
- includeRoot(result, STRESS_ROOT_1_ID, STRESS_ROOT_1_DOC_ID);
+ for (StubRoot root : mRoots.values()) {
+ includeRoot(result, root);
+ }
return result;
}
@@ -93,57 +131,112 @@
public Cursor queryDocument(String documentId, String[] projection)
throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
- includeDocument(result, documentId);
+ final StubDocument document = mDocuments.get(documentId);
+ includeDocument(result, document);
return result;
}
@Override
- public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
+ public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
+ String sortOrder)
throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
- if (STRESS_ROOT_1_DOC_ID.equals(parentDocumentId)) {
- for (String id : mIds) {
- includeDocument(result, id);
+ final ArrayList<StubDocument> childDocuments = mChildDocuments.get(parentDocumentId);
+ if (childDocuments != null) {
+ for (StubDocument document : childDocuments) {
+ includeDocument(result, document);
}
}
return result;
}
@Override
- public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
+ public ParcelFileDescriptor openDocument(String docId, String mode,
+ CancellationSignal signal)
throws FileNotFoundException {
throw new UnsupportedOperationException();
}
- private void includeRoot(MatrixCursor result, String rootId, String docId) {
+ private void includeRoot(MatrixCursor result, StubRoot root) {
final RowBuilder row = result.newRow();
- row.add(Root.COLUMN_ROOT_ID, rootId);
+ row.add(Root.COLUMN_ROOT_ID, root.id);
row.add(Root.COLUMN_FLAGS, 0);
- row.add(Root.COLUMN_TITLE, rootId);
- row.add(Root.COLUMN_DOCUMENT_ID, docId);
+ row.add(Root.COLUMN_TITLE, root.id);
+ row.add(Root.COLUMN_DOCUMENT_ID, root.documentId);
}
- private void includeDocument(MatrixCursor result, String id) {
+ private void includeDocument(MatrixCursor result, StubDocument document) {
final RowBuilder row = result.newRow();
- row.add(Document.COLUMN_DOCUMENT_ID, id);
- row.add(Document.COLUMN_DISPLAY_NAME, id);
- row.add(Document.COLUMN_SIZE, 0);
- row.add(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
+ row.add(Document.COLUMN_DOCUMENT_ID, document.id);
+ row.add(Document.COLUMN_DISPLAY_NAME, document.id);
+ row.add(Document.COLUMN_SIZE, document.size);
+ row.add(Document.COLUMN_MIME_TYPE, document.mimeType);
row.add(Document.COLUMN_FLAGS, 0);
- row.add(Document.COLUMN_LAST_MODIFIED, null);
+ row.add(Document.COLUMN_LAST_MODIFIED, document.lastModified);
}
- private static String getDocumentIdForFile(File file) {
+ private static String getStubDocumentIdForFile(File file) {
return file.getAbsolutePath();
}
- private String createRandomId(int index) {
- final Random random = new Random(index);
- final StringBuilder builder = new StringBuilder();
- for (int i = 0; i < 20; i++) {
- builder.append((char) (random.nextInt(96) + 32));
+ private static class StubDocument {
+ final String mimeType;
+ final String id;
+ final int size;
+ final long lastModified;
+
+ private StubDocument(String mimeType, String id, int size, long lastModified) {
+ this.mimeType = mimeType;
+ this.id = id;
+ this.size = size;
+ this.lastModified = lastModified;
}
- builder.append(index); // Append a number to guarantee uniqueness.
- return builder.toString();
+
+ public static StubDocument createDirectory(int index) {
+ return new StubDocument(
+ DocumentsContract.Document.MIME_TYPE_DIR, createRandomId(index), 0,
+ createRandomTime(index));
+ }
+
+ public static StubDocument createDirectory(String id) {
+ return new StubDocument(DocumentsContract.Document.MIME_TYPE_DIR, id, 0, 0);
+ }
+
+ public static StubDocument createFile(int index) {
+ return new StubDocument(
+ MIME_TYPE_IMAGE, createRandomId(index), createRandomSize(index),
+ createRandomTime(index));
+ }
+
+ private static String createRandomId(int index) {
+ final Random random = new Random(index);
+ final StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 20; i++) {
+ builder.append((char) (random.nextInt(96) + 32));
+ }
+ builder.append(index); // Append a number to guarantee uniqueness.
+ return builder.toString();
+ }
+
+ private static int createRandomSize(int index) {
+ final Random random = new Random(index);
+ return random.nextInt(1024 * 1024 * 100); // Up to 100 MB.
+ }
+
+ private static long createRandomTime(int index) {
+ final Random random = new Random(index);
+ // Up to 30 days backwards from REFERENCE_TIMESTAMP.
+ return REFERENCE_TIMESTAMP - random.nextLong() % 1000L * 60 * 60 * 24 * 30;
+ }
+ }
+
+ private static class StubRoot {
+ final String id;
+ final String documentId;
+
+ public StubRoot(String id, String documentId) {
+ this.id = id;
+ this.documentId = documentId;
+ }
}
}
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index 2aee569..95c6f1f 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -31,61 +31,64 @@
android:actionViewClass="android.widget.SearchView"
android:imeOptions="actionSearch"
android:visible="false" />
- <item
- android:id="@+id/menu_grid"
- android:title="@string/menu_grid"
- android:icon="@drawable/ic_menu_view_grid"
- android:showAsAction="always" />
- <item
- android:id="@+id/menu_list"
- android:title="@string/menu_list"
- android:icon="@drawable/ic_menu_view_list"
- android:showAsAction="always" />
+<!-- This group is being hidden when searching is in full bar mode-->
+ <group android:id="@+id/group_hide_when_searching">
+ <item
+ android:id="@+id/menu_grid"
+ android:title="@string/menu_grid"
+ android:icon="@drawable/ic_menu_view_grid"
+ android:showAsAction="always" />
+ <item
+ android:id="@+id/menu_list"
+ android:title="@string/menu_list"
+ android:icon="@drawable/ic_menu_view_list"
+ android:showAsAction="always" />
- <item
- android:id="@+id/menu_new_window"
- android:title="@string/menu_new_window"
- android:alphabeticShortcut="n"
- android:showAsAction="never"
- android:visible="false" />
- <item
- android:id="@+id/menu_create_dir"
- android:title="@string/menu_create_dir"
- android:icon="@drawable/ic_menu_new_folder"
- android:alphabeticShortcut="e"
- android:showAsAction="never"
- android:visible="false" />
- <item
- android:id="@+id/menu_paste_from_clipboard"
- android:title="@string/menu_paste_from_clipboard"
- android:alphabeticShortcut="v"
- android:showAsAction="never"
- android:visible="false" />
- <!-- Copy action is defined in mode_directory.xml -->
- <item
- android:id="@+id/menu_sort"
- android:title="@string/menu_sort"
- android:icon="@drawable/ic_menu_sortby"
- android:showAsAction="ifRoom">
- <menu>
- <item
- android:id="@+id/menu_sort_name"
- android:title="@string/sort_name" />
- <item
- android:id="@+id/menu_sort_date"
- android:title="@string/sort_date" />
- <item
- android:id="@+id/menu_sort_size"
- android:title="@string/sort_size" />
- </menu>
- </item>
- <item
- android:id="@+id/menu_file_size"
- android:showAsAction="never"
- android:visible="false" />
- <item
- android:id="@+id/menu_settings"
- android:title="@string/menu_settings"
- android:showAsAction="never"
- android:visible="false" />
+ <item
+ android:id="@+id/menu_new_window"
+ android:title="@string/menu_new_window"
+ android:alphabeticShortcut="n"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_create_dir"
+ android:title="@string/menu_create_dir"
+ android:icon="@drawable/ic_menu_new_folder"
+ android:alphabeticShortcut="e"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_paste_from_clipboard"
+ android:title="@string/menu_paste_from_clipboard"
+ android:alphabeticShortcut="v"
+ android:showAsAction="never"
+ android:visible="false" />
+ <!-- Copy action is defined in mode_directory.xml -->
+ <item
+ android:id="@+id/menu_sort"
+ android:title="@string/menu_sort"
+ android:icon="@drawable/ic_menu_sortby"
+ android:showAsAction="ifRoom">
+ <menu>
+ <item
+ android:id="@+id/menu_sort_name"
+ android:title="@string/sort_name" />
+ <item
+ android:id="@+id/menu_sort_date"
+ android:title="@string/sort_date" />
+ <item
+ android:id="@+id/menu_sort_size"
+ android:title="@string/sort_size" />
+ </menu>
+ </item>
+ <item
+ android:id="@+id/menu_file_size"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:showAsAction="never"
+ android:visible="false" />
+ </group>
</menu>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 5abb9d7..a3fdd78 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Kon nie dokument hernoem nie"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige lêers is omgeskakel"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot jou data, insluitend foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Moenie weer vra nie"</string>
<string name="allow" msgid="7225948811296386551">"Laat toe"</string>
<string name="deny" msgid="2081879885755434506">"Weier"</string>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index b77b82cc..df73bed 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ሰነዱን ዳግም መሰየም አልተሳካም"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"አንዳንድ ፋይሎች ተለውጠዋል"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> በ<xliff:g id="STORAGE"><i>^3</i></xliff:g> ላይ የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መደረሻ ይሰጠው?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"በ<xliff:g id="STORAGE"><i>^2</i></xliff:g> ላይ ያሉትን ፎቶዎች እና ቪዲዮዎች ጨምሮ የውሂብዎ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጥ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ዳግም አትጠይቅ"</string>
<string name="allow" msgid="7225948811296386551">"ይፍቀዱ"</string>
<string name="deny" msgid="2081879885755434506">"ያስተባብሉ"</string>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 1625043..d92eb5f 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -139,6 +139,7 @@
<string name="rename_error" msgid="4203041674883412606">"أخفقت إعادة تسمية المستند."</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"تم تحويل بعض الملفات"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور ومقاطع الفيديو على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
<string name="never_ask_again" msgid="4295278542972859268">"عدم السؤال مرة أخرى"</string>
<string name="allow" msgid="7225948811296386551">"السماح"</string>
<string name="deny" msgid="2081879885755434506">"رفض"</string>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 0f0eda4..632fa6b 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Sənəd adını dəyişmək uğursuz oldu"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bəzi fayllar konvertasiya edilib"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> yaddaşında <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> yaddaşında foto və videolar daxil olmaqla datanıza <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təmin edilsin?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Bir daha soruşmayın"</string>
<string name="allow" msgid="7225948811296386551">"İcazə verin"</string>
<string name="deny" msgid="2081879885755434506">"Rədd et"</string>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index 7bbf942..2d679ea 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Preimenovanje dokumenta nije uspelo"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke datoteke su konvertovane"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li da aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobrite pristup direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na memorijskom prostoru <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite da li da dozvolite da aplikacija <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa podacima, uključujući slike i video snimke, na lokaciji <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
<string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
<string name="deny" msgid="2081879885755434506">"Odbij"</string>
diff --git a/packages/DocumentsUI/res/values-be-rBY/strings.xml b/packages/DocumentsUI/res/values-be-rBY/strings.xml
index 4621d9b..abd4679 100644
--- a/packages/DocumentsUI/res/values-be-rBY/strings.xml
+++ b/packages/DocumentsUI/res/values-be-rBY/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Не атрымалася перайменаваць дакумент"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некаторыя файлы былі сканвертаваныя"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> у <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Даць <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да вашых даных, у тым ліку фатаграфій і відэа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Больш не пытацца"</string>
<string name="allow" msgid="7225948811296386551">"Дазволіць"</string>
<string name="deny" msgid="2081879885755434506">"Забараніць"</string>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index 329f92f..4822adb 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Преименуването на документа не бе успешно"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Някои файлове бяха преобразувани"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ в/ъв <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до данните ви в хранилището (<xliff:g id="STORAGE"><i>^2</i></xliff:g>), включително снимки и видеоклипове?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Без повторно питане"</string>
<string name="allow" msgid="7225948811296386551">"Разрешаване"</string>
<string name="deny" msgid="2081879885755434506">"Отказване"</string>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index 936e2dd..5709692 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -32,7 +32,7 @@
<string name="menu_share" msgid="3075149983979628146">"শেয়ার করুন"</string>
<string name="menu_delete" msgid="8138799623850614177">"মুছুন"</string>
<string name="menu_select_all" msgid="8323579667348729928">"সবগুলি নির্বাচন করুন"</string>
- <string name="menu_copy" msgid="3612326052677229148">"এতে অনুলিপি করুন…"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"এতে কপি করুন…"</string>
<string name="menu_move" msgid="1828090633118079817">"এতে সরান..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"নতুন উইন্ডো"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"প্রতিলিপি করুন"</string>
@@ -42,7 +42,7 @@
<string name="menu_file_size_show" msgid="3240323619260823076">"ফাইলের আকার দেখান"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ফাইলের আকার লুকান"</string>
<string name="button_select" msgid="527196987259139214">"নির্বাচন করুন"</string>
- <string name="button_copy" msgid="8706475544635021302">"অনুলিপি করুন"</string>
+ <string name="button_copy" msgid="8706475544635021302">"কপি করুন"</string>
<string name="button_move" msgid="2202666023104202232">"সরান"</string>
<string name="button_dismiss" msgid="3714065566893946085">"খারিজ করুন"</string>
<string name="button_retry" msgid="4392027584153752797">"আবার চেষ্টা করুন"</string>
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"দস্তাবেজের পুনঃনামকরণ ব্যর্থ হয়েছে৷"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"কিছু ফাইল রূপান্তরিত হয়েছে"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="STORAGE"><i>^3</i></xliff:g> এ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার মঞ্জুরি দিতে চান?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> এ থাকা ফটো ও ভিডিওগুলি সমেত <xliff:g id="APPNAME"><b>^1</b></xliff:g> কে আপনার ডেটা অ্যাক্সেস করার অনুমতি দেবেন?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"আর জিজ্ঞাসা করবেন না"</string>
<string name="allow" msgid="7225948811296386551">"অনুমতি দিন"</string>
<string name="deny" msgid="2081879885755434506">"আস্বীকার করুন"</string>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
index d23c884..9c94a05 100644
--- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke od datoteka su pretvorene"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Omogućiti <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup svojim podacima, uključujući fotografije i video zapise, na <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
<string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
<string name="deny" msgid="2081879885755434506">"Odbijte"</string>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 044350a..4ecec9f 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"No s\'ha pogut canviar el nom del document"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"S\'han convertit alguns fitxers"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de l\'emmagatzematge <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés a les dades de l\'emmagatzematge <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incloses les fotos i els vídeos?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"No m\'ho demanis més"</string>
<string name="allow" msgid="7225948811296386551">"Permet"</string>
<string name="deny" msgid="2081879885755434506">"Denega"</string>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index ca6f3f1..3c6e81d 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokument se nepodařilo přejmenovat."</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Některé soubory byly převedeny"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložišti <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup ke svým datům v úložišti <xliff:g id="STORAGE"><i>^2</i></xliff:g>, včetně fotek a videí?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Příště se neptat"</string>
<string name="allow" msgid="7225948811296386551">"Povolit"</string>
<string name="deny" msgid="2081879885755434506">"Odepřít"</string>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index c4e7770..679506b 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokumentet kunne ikke omdøbes"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nogle filer er konverteret"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til mappen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til dine data, herunder billeder og videoer på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Spørg ikke igen"</string>
<string name="allow" msgid="7225948811296386551">"Tillad"</string>
<string name="deny" msgid="2081879885755434506">"Afvis"</string>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 766222c..b48afb0 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokument konnte nicht umbenannt werden"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Einige Dateien wurden konvertiert"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> auf <xliff:g id="STORAGE"><i>^3</i></xliff:g> geben?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf deine Daten auf <xliff:g id="STORAGE"><i>^2</i></xliff:g> geben, einschließlich Fotos und Videos?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Nicht mehr fragen"</string>
<string name="allow" msgid="7225948811296386551">"Zulassen"</string>
<string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 3bbcf776..3872c40 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Αποτυχία μετονομασίας εγγράφου"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Ορισμένα αρχεία μετατράπηκαν"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^3</i></xliff:g>;"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Θέλετε να εκχωρήσετε πρόσβαση στα δεδομένα σας στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g>, συμπεριλαμβανομένων των φωτογραφιών και των βίντεό σας, στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^2</i></xliff:g>;"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Να μην ερωτηθώ ξανά"</string>
<string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string>
<string name="deny" msgid="2081879885755434506">"Άρνηση"</string>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 6d847b5..3f36f41 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"No se pudo cambiar el nombre del documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se convirtieron algunos archivos"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"¿Otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> en <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> a tus datos, incluidas tus fotos y videos en <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Denegar"</string>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 15b5694..a0da06c 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Error al cambiar el nombre del documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se han convertido algunos archivos"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda a tus datos, incluidos los vídeos y las fotos de <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Denegar"</string>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index ed60aa9..d49b320 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokumendi ümbernimetamine ebaõnnestus"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Mõned failid teisendati"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> salvestusruumis <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs teie andmetele (sh fotod ja videod) salvestusruumis <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ära enam küsi"</string>
<string name="allow" msgid="7225948811296386551">"Luba"</string>
<string name="deny" msgid="2081879885755434506">"Keela"</string>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index f3d68b0d..085f148 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Ezin izan zaio aldatu izena dokumentuari"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Artxibo batzuk bihurtu dira"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktorioa atzitzeko baimena eman nahi diozu?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzea baimendu nahi diozu, besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ez galdetu berriro"</string>
<string name="allow" msgid="7225948811296386551">"Onartu"</string>
<string name="deny" msgid="2081879885755434506">"Ukatu"</string>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 80e1aa8..114c7d0 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"نام سند تغییر نکرد"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"بعضی از فایلها تبدیل شدند"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> در <xliff:g id="STORAGE"><i>^3</i></xliff:g> دسترسی داشته باشد؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه میدهید به دادههایتان دسترسی پیدا کند، از جمله عکسها و ویدیوهایتان در <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
<string name="never_ask_again" msgid="4295278542972859268">"دوباره سؤال نشود"</string>
<string name="allow" msgid="7225948811296386551">"ارزیابیشده"</string>
<string name="deny" msgid="2081879885755434506">"اجازه ندارد"</string>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index 279aad7..46f863f 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokumentin nimen muuttaminen epäonnistui."</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Joitakin tiedostoja muunnettiin."</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^3</i></xliff:g> olevan hakemiston <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> käyttöoikeus?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^2</i></xliff:g> olevien tietojesi, mukaan lukien valokuviesi ja videoidesi, käyttöoikeus?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Älä kysy uudestaan"</string>
<string name="allow" msgid="7225948811296386551">"Salli"</string>
<string name="deny" msgid="2081879885755434506">"Kiellä"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index 347a3f2..b78b10e 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Impossible de renommer le document"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sur <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Voulez-vous accorder l\'accès à vos données à <xliff:g id="APPNAME"><b>^1</b></xliff:g>, y compris vos photos et vos vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne plus me demander"</string>
<string name="allow" msgid="7225948811296386551">"Autoriser"</string>
<string name="deny" msgid="2081879885755434506">"Refuser"</string>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 6030bde..63e28bf 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Échec du changement de nom du document."</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" sur <xliff:g id="STORAGE"><i>^3</i></xliff:g> ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à vos données, y compris les photos et les vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne plus demander"</string>
<string name="allow" msgid="7225948811296386551">"Autoriser"</string>
<string name="deny" msgid="2081879885755434506">"Refuser"</string>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index 58181f8..9ce9ebd 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Non se puido cambiar o nome do documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Convertéronse algúns ficheiros"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no almacenamento de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos almacenados en <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluídos vídeos e fotos?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Non preguntar de novo"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Rexeitar"</string>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 2cce5a3..6c2bb3e 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"દસ્તાવેજનું નામ બદલવામાં નિષ્ફળ થયાં"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"કેટલીક ફાઇલો રૂપાંતરિત કરી હતી"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટા અને વિડિઓઝ સહિત તમારા ડેટાની અૅક્સેસ આપીએ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ફરીથી પૂછશો નહીં"</string>
<string name="allow" msgid="7225948811296386551">"મંજૂરી આપો"</string>
<string name="deny" msgid="2081879885755434506">"નકારો"</string>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index 9f57f0b..9c27556 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"दस्तावेज़ का नाम बदलना विफल रहा"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"कुछ फ़ाइलें रूपांतरित हो गई थीं"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस दें?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो सहित, अपने डेटा का एक्सेस प्रदान करें?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"फिर से ना पूछें"</string>
<string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
<string name="deny" msgid="2081879885755434506">"अस्वीकारें"</string>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 0d42d5d..58e709b 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Naziv dokumenta nije promijenjen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke su datoteke konvertirane"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dopustiti pristup podacima, uključujući fotografije i videozapise na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^2</i></xliff:g>)?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Više me ne pitaj"</string>
<string name="allow" msgid="7225948811296386551">"Dopusti"</string>
<string name="deny" msgid="2081879885755434506">"Odbij"</string>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 37bfcfa..1936214 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Nem sikerült átnevezni a dokumentumot"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Egyes fájlokat konvertált a rendszer"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz itt: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára az Ön adataihoz, beleértve a következő tárhelyen található képekhez és videókhoz: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne jelenjen meg többé"</string>
<string name="allow" msgid="7225948811296386551">"Engedélyezés"</string>
<string name="deny" msgid="2081879885755434506">"Elutasítás"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 22e44b0..57af718 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Չհաջողվեց վերանվանել փաստաթուղթը"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Որոշ ֆայլեր փոխարկվել են"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ի <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ում պահվող ձեր տվյալները, այդ թվում նաև լուսանկարները և տեսանյութերը, օգտագործելու թույլտվություն:"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Այլևս չհարցնել"</string>
<string name="allow" msgid="7225948811296386551">"Թույլատրել"</string>
<string name="deny" msgid="2081879885755434506">"Մերժել"</string>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index f9aae9d..6621c9171 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Gagal mengganti nama dokumen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Beberapa file dikonversi"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke data Anda, termasuk foto dan video, di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
<string name="allow" msgid="7225948811296386551">"Izinkan"</string>
<string name="deny" msgid="2081879885755434506">"Tolak"</string>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index a2a0d9b..4265606 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Ekki tókst að endurnefna skjalið"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sumum skrám var umbreytt"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> á <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að gögnunum þínum, þar á meðal myndum og myndskeiðum, á <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ekki spyrja aftur"</string>
<string name="allow" msgid="7225948811296386551">"Leyfa"</string>
<string name="deny" msgid="2081879885755434506">"Hafna"</string>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index ddede45..7599180 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Ridenominazione documento non riuscita"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alcuni file sono stati convertiti"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> su <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso ai tuoi dati, inclusi video e foto, sull\'unità <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Non chiedermelo più"</string>
<string name="allow" msgid="7225948811296386551">"Consenti"</string>
<string name="deny" msgid="2081879885755434506">"Nega"</string>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index e2658c3..2e2020c 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"ניסיון שינוי שם המסמך נכשל"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"קבצים מסוימים הומרו"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לספריה <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> באחסון <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לנתונים שלך, כולל תמונות וסרטונים, השמורים ב<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"אל תשאל שוב"</string>
<string name="allow" msgid="7225948811296386551">"אפשר"</string>
<string name="deny" msgid="2081879885755434506">"דחה"</string>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 3cad318..1ba405f 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ドキュメントの名前を変更できませんでした"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"一部のファイルが変換されました"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"「<xliff:g id="STORAGE"><i>^3</i></xliff:g>」の「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリに「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」へのアクセスを許可しますか?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>の写真や動画などのデータへのアクセスを「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」に許可しますか?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"今後表示しない"</string>
<string name="allow" msgid="7225948811296386551">"許可"</string>
<string name="deny" msgid="2081879885755434506">"拒否"</string>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index afd4198..c1624e3 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"დოკუმენტის გადარქმევა ვერ მოხერხდა"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ზოგიერთი ფაილი გარდაქმნილია"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ის დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ზე არსებულ მონაცემებზე, მათ შორის, ფოტოებსა და ვიდეოებზე, წვდომის უფლებით?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"აღარ მკითხოთ"</string>
<string name="allow" msgid="7225948811296386551">"უფლების მიცემა"</string>
<string name="deny" msgid="2081879885755434506">"აკრძალვა"</string>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 21a8260..904ca5d 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Құжат қайта аталмады"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Кейбір файлдар түрлендірілді"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^3</i></xliff:g> қоймасындағы <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына өтуге рұқсат беру керек пе?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> <xliff:g id="STORAGE"><i>^2</i></xliff:g> қоймасындағы деректерге, соның ішінде, фотосуреттерге және бейнелерге қатынас беру керек пе?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Қайта сұралмасын"</string>
<string name="allow" msgid="7225948811296386551">"Рұқсат беру"</string>
<string name="deny" msgid="2081879885755434506">"Бас тарту"</string>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 5a049add..ca0fa4c 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"បានបរាជ័យក្នុងការប្តូរឈ្មោះឯកសារ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ឯកសារមួយចំនួនត្រូវបានបម្លែង"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> នៅលើ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ផ្តល់សិទ្ធិអនុញ្ញាតដល់ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការទិន្នន័យរបស់អ្នក រាប់បញ្ចូលទាំងរូបថត និងវីដេអូ នៅលើ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ឬទេ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"កុំសួរទៀត"</string>
<string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
<string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 924b14a..6287274 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ಕೆಲವು ಫೈಲ್ಗಳನ್ನು ಪರಿವರ್ತಿಸಲಾಗಿದೆ"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ಸಂಗ್ರಹಣೆಯಲ್ಲಿನ ಪೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
<string name="allow" msgid="7225948811296386551">"ಅನುಮತಿಸು"</string>
<string name="deny" msgid="2081879885755434506">"ನಿರಾಕರಿಸು"</string>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index df0cbf2..1b553b5 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"문서 이름을 변경하지 못했습니다."</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"일부 파일이 변환되었습니다."</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="STORAGE"><i>^3</i></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 사진, 동영상 등 <xliff:g id="STORAGE"><i>^2</i></xliff:g>의 내 데이터에 액세스하도록 허용하시겠습니까?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"다시 묻지 않음"</string>
<string name="allow" msgid="7225948811296386551">"허용"</string>
<string name="deny" msgid="2081879885755434506">"거부"</string>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 84bc37f..f4981b9 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Документтин аталышы өзгөртүлбөй калды"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Айрым файлдардын форматы өзгөртүлдү"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^3</i></xliff:g> түзмөгүндөгү <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> папканы пайдалануу мүмкүнчүлүгү берилсинби?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^2</i></xliff:g> түзмөгүндөгү дайындарыңыз, сүрөттөрүңүз жана видеолоруңузду пайдалануу мүмкүнчүлүгү берилсинби?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Экинчи суралбасын"</string>
<string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string>
<string name="deny" msgid="2081879885755434506">"Жок"</string>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 4c891aa..4203241 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ປ່ຽນຊື່ເອກະສານບໍ່ສຳເລັດ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ປ່ຽນແປງບາງໄຟລ໌ແລ້ວ"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"ອະນຸຍາດສິດເຂົ້າເຖິງໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເພື່ອເຂົ້າໄດເຣກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ຢູ່ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ບໍ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ອະນຸມັດໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເຂົ້າເຖິງຂໍ້ມູນຂອງທ່ານ ເຊິ່ງຮວມເຖິງຮູບພາບ ແລະ ວິດີໂອໃນ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ໄດ້ບໍ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ບໍ່ຕ້ອງຖາມຄືນ"</string>
<string name="allow" msgid="7225948811296386551">"ອະນຸຍາດ"</string>
<string name="deny" msgid="2081879885755434506">"ປະຕິເສດ"</string>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 8aec2d4..5114854 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Nepavyko pervardyti dokumento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Kai kurie failai buvo konvertuoti"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Suteikti programai „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie duomenų, įskaitant nuotraukas ir vaizdo įrašus, <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Daugiau neklausti"</string>
<string name="allow" msgid="7225948811296386551">"Leisti"</string>
<string name="deny" msgid="2081879885755434506">"Atmesti"</string>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index be2f0b7..8ee161d 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Neizdevās pārdēvēt dokumentu"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Daži faili tika pārveidoti."</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> šajā krātuvē: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt jūsu datiem, tostarp fotoattēliem un videoklipiem, šajā krātuvē: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Turpmāk vairs nejautāt"</string>
<string name="allow" msgid="7225948811296386551">"Atļaut"</string>
<string name="deny" msgid="2081879885755434506">"Noraidīt"</string>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index e9c7f3f..5fb64f1 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Не успеа да се преименува документот"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некои датотеки беа конвертирани"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до вашите податоци, вклучувајќи фотографии и видеа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Не прашувај повторно"</string>
<string name="allow" msgid="7225948811296386551">"Дозволи"</string>
<string name="deny" msgid="2081879885755434506">"Одбиј"</string>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index e71e62a..afb26a0 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ഡോക്യുമെന്റിന്റെ പേരുമാറ്റുന്നത് പരാജയപ്പെട്ടു"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ചില ഫയലുകൾ പരിവർത്തനം ചെയ്യപ്പെട്ടു"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> സ്റ്റോറേജിലെ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്റ്ററിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> സ്റ്റോറേജിലെ ഫോട്ടോകളും വീഡിയോകളും ഉൾപ്പെടെ, നിങ്ങളുടെ ഡാറ്റയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ്സ് അനുവദിക്കണോ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
<string name="allow" msgid="7225948811296386551">"അനുവദിക്കുക"</string>
<string name="deny" msgid="2081879885755434506">"നിരസിക്കുക"</string>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 64cc2a8..2890908 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Баримт бичгийн нэрийн өөрчилж чадсангүй"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Зарим файлыг хөрвүүлсэн"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>-д байгаа <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандахыг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д зөвшөөрөх үү?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>-д байгаа зураг, видео гэх мэт таны өгөгдөлд <xliff:g id="APPNAME"><b>^1</b></xliff:g> хандахыг зөвшөөрөх үү?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Дахин бүү асуу"</string>
<string name="allow" msgid="7225948811296386551">"Зөвшөөрөх"</string>
<string name="deny" msgid="2081879885755434506">"Татгалзах"</string>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 415eda8..e850b26 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"दस्तऐवज पुनर्नामित करण्यात अयशस्वी झाले"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"काही फायली रूपांतरित केल्या होत्या"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> वर <xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेवर प्रवेशाची मंजूरी द्यायची?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="STORAGE"><i>^2</i></xliff:g> वर फोटो आणि व्हिडिओंसह, आपल्या डेटामध्ये प्रवेश करण्याची मंजूरी द्यायची?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"पुन्हा विचारू नका"</string>
<string name="allow" msgid="7225948811296386551">"अनुमती द्या"</string>
<string name="deny" msgid="2081879885755434506">"नकार द्या"</string>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index c5f4771..374cbb0 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Gagal menamakan semula dokumen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sesetengah fail telah ditukarkan"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada data anda, termasuk foto dan video pada <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
<string name="allow" msgid="7225948811296386551">"Benarkan"</string>
<string name="deny" msgid="2081879885755434506">"Nafi"</string>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index bdfd1a2..80afcfb 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"စာရွက်စာတမ်းကို အမည်ပြောင်းခြင်း မအောင်မြင်ပါ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"အချို့ဖိုင်များကို ပြောင်းလဲထားသည်"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ကို <xliff:g id="STORAGE"><i>^3</i></xliff:g> ရှိ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> လမ်းညွှန်အား အသုံးပြုခွင့်ပေးမလား။"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ရှိဓာတ်ပုံများနှင့် ဗီဒီယိုများအပါအဝင် သင့်ဒေတာများကို <xliff:g id="APPNAME"><b>^1</b></xliff:g> အားအသုံးပြုခွင့်ပေးမလား။"</string>
<string name="never_ask_again" msgid="4295278542972859268">"နောက်ထပ်မမေးပါနှင့်"</string>
<string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
<string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 5922d1c..8349a13 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Kunne ikke gi dokumentet nytt navn"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Noen filer er konvertert"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til dataene dine – inkludert bilder og videoer – på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ikke spør igjen"</string>
<string name="allow" msgid="7225948811296386551">"Tillat"</string>
<string name="deny" msgid="2081879885755434506">"Avslå"</string>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 4bc814b..a110742 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"कागजात पुन: नामाकरण गर्न असफल भयो"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"केही फाइलहरू परिवर्तन गरिएका थिए"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^3</i></xliff:g> मा भएको <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामा पहुँच गर्न अनुमति दिने हो?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^2</i></xliff:g> मा भएका तस्बिर र भिडियोहरू लगायत तपाईँको डेटामा पहुँच गर्नका लागि अनुमति दिने हो?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"फेरि नसोध्नुहोस्"</string>
<string name="allow" msgid="7225948811296386551">"अनुमति दिनुहोस्"</string>
<string name="deny" msgid="2081879885755434506">"अस्वीकार गर्नुहोस्"</string>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index f1b3ed7..27796cf 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Kan naam van document niet wijzigen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige bestanden zijn geconverteerd"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot je gegevens, waaronder foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Niet meer vragen"</string>
<string name="allow" msgid="7225948811296386551">"Toestaan"</string>
<string name="deny" msgid="2081879885755434506">"Weigeren"</string>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index f9f9412..503bc0d 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ਦਸਤਾਵੇਜ਼ ਦਾ ਮੁੜ-ਨਾਮਕਰਨ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ਕੁਝ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> \'ਤੇ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ, ਤੁਹਾਡੇ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
<string name="allow" msgid="7225948811296386551">"ਆਗਿਆ ਦਿਓ"</string>
<string name="deny" msgid="2081879885755434506">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 7a35bc2..7f0b274 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Nie udało się zmienić nazwy dokumentu"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektóre pliki zostały przekonwertowane"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> w pamięci masowej <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do Twoich danych, w tym zdjęć i filmów, zapisanych w pamięci <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Nie pytaj ponownie"</string>
<string name="allow" msgid="7225948811296386551">"Zezwól"</string>
<string name="deny" msgid="2081879885755434506">"Odmów"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index b765cd0..d34b7b6 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Negar"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 1edd1c0..7c82410 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Falha ao mudar o nome do documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns ficheiros foram convertidos"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no(a) <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no(a) <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Recusar"</string>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index b765cd0..d34b7b6 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Negar"</string>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 10f6aee..54458f1 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Documentul nu a putut fi redenumit"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Unele fișiere au fost convertite"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> accesul la directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de pe <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să vă acceseze datele, inclusiv fotografiile și videoclipurile, de pe <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Nu mai întreba"</string>
<string name="allow" msgid="7225948811296386551">"Permiteți"</string>
<string name="deny" msgid="2081879885755434506">"Refuzați"</string>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index d9f40097..2eda9ec 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Не удалось переименовать документ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Формат некоторых файлов изменен"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" на устройстве \"<xliff:g id="STORAGE"><i>^3</i></xliff:g>\"?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к вашим данным, включая фото и видео, на носителе: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Больше не спрашивать"</string>
<string name="allow" msgid="7225948811296386551">"Разрешить"</string>
<string name="deny" msgid="2081879885755434506">"Отклонить"</string>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 41ee2260..1dc9a2b 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ලේඛනය යළි නම් කිරීම අසාර්ථක විය"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"සමහර ගොනු පරිවර්තනය කරන ලදී"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> හට <xliff:g id="STORAGE"><i>^3</i></xliff:g> මත <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ප්රවේශය දෙන්නද?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> හි, ඡායාරූප සහ වීඩියෝ ඇතුළුව, ඔබේ දත්තවලට <xliff:g id="APPNAME"><b>^1</b></xliff:g> හට ප්රවේශය ලබා දෙන්නද?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"නැවත අසන්න එපා"</string>
<string name="allow" msgid="7225948811296386551">"අවසර දෙන්න"</string>
<string name="deny" msgid="2081879885755434506">"ප්රතික්ෂේප කරන්න"</string>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 518093c..da91574 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Premenovanie dokumentu zlyhalo"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektoré súbory boli konvertované"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložisku <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> udeliť prístup k dátam (vrátane fotiek a videí) v úložisku <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Nabudúce sa nepýtať"</string>
<string name="allow" msgid="7225948811296386551">"Povoliť"</string>
<string name="deny" msgid="2081879885755434506">"Zamietnuť"</string>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 39cfed7..9a7b477 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokumenta ni bilo mogoče preimenovati"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nekatere datoteke so bile pretvorjene"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v shrambi <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Odobrite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostop do podatkov, vključno s fotografijami in videoposnetki, v shrambi <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ne sprašuj več"</string>
<string name="allow" msgid="7225948811296386551">"Dovoli"</string>
<string name="deny" msgid="2081879885755434506">"Zavrni"</string>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index f5ebbbc..6b41c60 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Riemërtimi i dokumentit dështoi"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Disa skedarë u konvertuan"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Jepi aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> në <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te të dhënat, duke përfshirë fotografitë dhe videot, në <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Mos pyet përsëri"</string>
<string name="allow" msgid="7225948811296386551">"Lejo"</string>
<string name="deny" msgid="2081879885755434506">"Moho"</string>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 6a6488e..b6ccf45 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -118,6 +118,7 @@
<string name="rename_error" msgid="4203041674883412606">"Преименовање документа није успело"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Неке датотеке су конвертоване"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Желите ли да апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> одобрите приступ директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на меморијском простору <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Желите да ли да дозволите да апликација <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа подацима, укључујући слике и видео снимке, на локацији <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Не питај поново"</string>
<string name="allow" msgid="7225948811296386551">"Дозволи"</string>
<string name="deny" msgid="2081879885755434506">"Одбиј"</string>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 8b55b22..67bbfdf 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Det gick inte att byta namn på dokumentet"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Vissa filer konverterades"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till din data (inklusive foton och videor) på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Fråga inte igen"</string>
<string name="allow" msgid="7225948811296386551">"Tillåt"</string>
<string name="deny" msgid="2081879885755434506">"Neka"</string>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 482c7ec..168b63a 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Imeshindwa kubadilisha jina la hati"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Baadhi ya faili zimebadilishwa muundo"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kwenye <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie data yako, ikiwa ni pamoja na picha na video kwenye <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Usiniulize tena"</string>
<string name="allow" msgid="7225948811296386551">"Ruhusu"</string>
<string name="deny" msgid="2081879885755434506">"Kataza"</string>
diff --git a/packages/DocumentsUI/res/values-sw720dp/colors.xml b/packages/DocumentsUI/res/values-sw720dp/colors.xml
new file mode 100644
index 0000000..3ecafe2
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <color name="menu_search_background">#ff676f74</color>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/config.xml b/packages/DocumentsUI/res/values-sw720dp/config.xml
new file mode 100644
index 0000000..4898e74
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Indicates if search view is taking the whole toolbar space -->
+ <bool name="full_bar_search_view">false</bool>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index b32c324..43543c6 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ஆவணத்திற்கு மறுபெயரிடுவதில் தோல்வி"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"சில கோப்புகள் மாற்றப்பட்டன"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> இல் உள்ள <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> இல் உள்ள படங்கள், வீடியோக்கள் உட்பட எல்லா தரவையும் அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"மீண்டும் கேட்காதே"</string>
<string name="allow" msgid="7225948811296386551">"அனுமதி"</string>
<string name="deny" msgid="2081879885755434506">"நிராகரி"</string>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index e77fd66..47d2c48 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"పత్రం పేరు మార్చడంలో విఫలమైంది"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"కొన్ని పైల్లు మార్చబడ్డాయి"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="STORAGE"><i>^3</i></xliff:g>లో <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>లో ఫోటోలు మరియు వీడియోలతో సహా మీ డేటా ప్రాప్యతను <xliff:g id="APPNAME"><b>^1</b></xliff:g>కి మంజూరు చేయాలా?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"మళ్లీ అడగవద్దు"</string>
<string name="allow" msgid="7225948811296386551">"అనుమతించండి"</string>
<string name="deny" msgid="2081879885755434506">"తిరస్కరించండి"</string>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 4d94795..99009b4 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"ไม่สามารถเปลี่ยนชื่อเอกสาร"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"แปลงบางไฟล์แล้ว"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ในการเข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ใน <xliff:g id="STORAGE"><i>^3</i></xliff:g> ไหม"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงข้อมูลของคุณ รวมถึงรูปภาพและวิดีโอใน <xliff:g id="STORAGE"><i>^2</i></xliff:g> ไหม"</string>
<string name="never_ask_again" msgid="4295278542972859268">"ไม่ต้องถามอีก"</string>
<string name="allow" msgid="7225948811296386551">"อนุญาต"</string>
<string name="deny" msgid="2081879885755434506">"ปฏิเสธ"</string>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index f395a5b..dd08e13 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Hindi napalitan ang pangalan ng dokumento"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Na-convert ang ilang file"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa iyong data, kabilang ang mga larawan at video, sa <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Huwag nang tatanunging muli"</string>
<string name="allow" msgid="7225948811296386551">"Payagan"</string>
<string name="deny" msgid="2081879885755434506">"Tanggihan"</string>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index bc4db0d..3cc53e1 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Dokümanın adı değiştirilemedi"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bazı dosyalar dönüştürüldü"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına <xliff:g id="STORAGE"><i>^3</i></xliff:g> depolama alanındaki <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişim izni verilsin mi?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasının, fotoğraflar ve videolar dahil olmak üzere <xliff:g id="STORAGE"><i>^2</i></xliff:g> üzerindeki verilerinize erişmesine izin verilsin mi?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Tekrar sorma"</string>
<string name="allow" msgid="7225948811296386551">"İzin Ver"</string>
<string name="deny" msgid="2081879885755434506">"Reddet"</string>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index 79b6fbf..f9620a0 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -125,6 +125,7 @@
<string name="rename_error" msgid="4203041674883412606">"Не вдалося перейменувати документ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Деякі файли конвертовано"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на пристрої пам’яті <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до ваших даних, зокрема до фотографій і відео, які містить <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Не запитувати знову"</string>
<string name="allow" msgid="7225948811296386551">"Дозвол."</string>
<string name="deny" msgid="2081879885755434506">"Забор."</string>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 4498f87..76d4cee 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"دستاویز کا نام تبدیل کرنے میں ناکام"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"کچھ فائلوں کو تبدیل کیا گیا تھا"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="STORAGE"><i>^3</i></xliff:g> پر <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی عطا کریں؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو اپنے ڈیٹا بشمول <xliff:g id="STORAGE"><i>^2</i></xliff:g> پر موجود تصاویر اور ویڈیوز تک رسائی عطا کریں؟"</string>
<string name="never_ask_again" msgid="4295278542972859268">"دوبارہ نہ پوچھیں"</string>
<string name="allow" msgid="7225948811296386551">"اجازت دیں"</string>
<string name="deny" msgid="2081879885755434506">"مسترد کریں"</string>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index b4f435b..47f1ac1 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Hujjatni qayta nomlab bo‘lmadi"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bir nechta fayllar o‘girildi"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildiga kirishiga ruxsat berilsinmi?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^2</i></xliff:g> xotirasidagi ma’lumotlardan, jumladan, rasmlar va videolardan foydalanishiga ruxsat berilsinmi?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Boshqa so‘ralmasin"</string>
<string name="allow" msgid="7225948811296386551">"Ruxsat berish"</string>
<string name="deny" msgid="2081879885755434506">"Rad qilish"</string>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index b64026a..613f271 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Không đổi được tên tài liệu"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Đã chuyển đổi một số tệp"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> trong <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào dữ liệu của bạn, kể cả ảnh và video trên <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Không hỏi lại"</string>
<string name="allow" msgid="7225948811296386551">"Cho phép"</string>
<string name="deny" msgid="2081879885755434506">"Từ chối"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 90d1619..3bfeaaf 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"无法重命名文档"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分文件已转换成其他格式"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问您 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的数据(包括照片和视频)吗?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"不再询问"</string>
<string name="allow" msgid="7225948811296386551">"允许"</string>
<string name="deny" msgid="2081879885755434506">"拒绝"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index aeda260..7587086 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄存取權嗎?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要向「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的相片和影片等資料的存取權嗎?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
<string name="allow" msgid="7225948811296386551">"允許"</string>
<string name="deny" msgid="2081879885755434506">"拒絕"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index dc76411..7f13098 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要允許「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」存取 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的資料 (包括相片和影片) 嗎?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
<string name="allow" msgid="7225948811296386551">"允許"</string>
<string name="deny" msgid="2081879885755434506">"拒絕"</string>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index c53031b..6453059 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -111,6 +111,7 @@
<string name="rename_error" msgid="4203041674883412606">"Yehlulekile ukuqamba kabusha idokhumenti"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Amanye amafayela aguqulelwe"</string>
<string name="open_external_dialog_request" msgid="5789329484285817629">"Nika i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela ekuqondiseni kwe-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ku-<xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Nikeza i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela kudatha yakho, okufaka izithombe namavidiyo, ku-<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
<string name="never_ask_again" msgid="4295278542972859268">"Ungaphindi ubuze"</string>
<string name="allow" msgid="7225948811296386551">"Vumela"</string>
<string name="deny" msgid="2081879885755434506">"Yala"</string>
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index 51e04b6..1660e26 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -24,7 +24,7 @@
<color name="window_background">#fff1f1f1</color>
<color name="drawer_background">#fff1f1f1</color>
<color name="directory_background">#fff7f7f7</color>
- <color name="menu_search_background">#ff676f74</color>
+ <color name="menu_search_background">@android:color/transparent</color>
<color name="primary_dark">@*android:color/primary_dark_material_dark</color>
<color name="primary">@*android:color/material_blue_grey_900</color>
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index 408603e..765211d 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -26,4 +26,6 @@
<bool name="home_root_hidden">true</bool>
<!-- Indicates if the advanced roots like internal storage should be hidden in the roots list) -->
<bool name="advanced_roots_hidden">true</bool>
+ <!-- Indicates if search view is taking the whole toolbar space -->
+ <bool name="full_bar_search_view">true</bool>
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 54202d4..69315f7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -146,7 +146,8 @@
getMenuInflater().inflate(R.menu.activity, menu);
mNavigator.update();
- mSearchManager.install((DocumentsToolbar) findViewById(R.id.toolbar));
+ boolean fullBarSearch = getResources().getBoolean(R.bool.full_bar_search_view);
+ mSearchManager.install((DocumentsToolbar) findViewById(R.id.toolbar), fullBarSearch);
return showMenu;
}
@@ -378,8 +379,12 @@
public void onSearchChanged(@Nullable String query) {
// We should not get here if root is not searchable
assert(canSearchRoot());
-
reloadSearch(query);
+ }
+
+ @Override
+ public void onSearchFinished() {
+ // Restores menu icons state
invalidateOptionsMenu();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index bed8b29..3e04e2a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -201,6 +201,8 @@
newWindow.setVisible(true);
Menus.disableHiddenItems(menu, pasteFromCb);
+ // It hides icon if searching in progress
+ mSearchManager.updateMenu();
return true;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index e6b22e6..7ad4a09 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -30,6 +30,7 @@
import android.provider.DocumentsContract;
import android.util.Log;
+import com.android.documentsui.State.ActionType;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService;
@@ -502,7 +503,7 @@
* @param name The name of the histogram.
* @param bucket The bucket to increment.
*/
- private static void logHistogram(Context context, String name, int bucket) {
+ private static void logHistogram(Context context, String name, @ActionType int bucket) {
if (DEBUG) Log.d(TAG, name + ": " + bucket);
MetricsLogger.histogram(context, name, bucket);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index 35da8cc..8b4f40e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -17,6 +17,7 @@
package com.android.documentsui;
import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -117,7 +118,7 @@
Intent handlerAppIntent = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
- mAdapter = new RootsAdapter(context, result, handlerAppIntent);
+ mAdapter = new RootsAdapter(context, result, handlerAppIntent, state);
mList.setAdapter(mAdapter);
onCurrentRootChanged();
@@ -308,8 +309,8 @@
* @param handlerAppIntent When not null, apps capable of handling the original
* intent will be included in list of roots (in special section at bottom).
*/
- public RootsAdapter(
- Context context, Collection<RootInfo> roots, @Nullable Intent handlerAppIntent) {
+ public RootsAdapter(Context context, Collection<RootInfo> roots,
+ @Nullable Intent handlerAppIntent, State state) {
super(context, 0);
final List<RootItem> libraries = new ArrayList<>();
@@ -320,7 +321,8 @@
if (root.isHome() && Shared.isHomeRootHidden(context)) {
continue;
- } else if (root.isAdvanced() && Shared.areAdvancedRootsHidden(context)) {
+ } else if (root.isAdvanced()
+ && Shared.areAdvancedRootsHidden(context, state)) {
continue;
} else if (root.isLibrary()) {
if (DEBUG) Log.d(TAG, "Adding " + root + " as library.");
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
index 4d0ba4b..11b8891 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
@@ -23,7 +23,9 @@
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;
import android.util.Log;
+import android.view.Menu;
import android.view.MenuItem;
+import android.view.MenuItem.OnActionExpandListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
@@ -36,10 +38,12 @@
* Manages searching UI behavior.
*/
final class SearchViewManager implements
- SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener {
+ SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
+ OnActionExpandListener {
public interface SearchManagerListener {
void onSearchChanged(@Nullable String query);
+ void onSearchFinished();
}
public static final String TAG = "SearchManger";
@@ -48,10 +52,11 @@
private boolean mSearchExpanded;
private String mCurrentSearch;
private boolean mIgnoreNextClose;
+ private boolean mFullBar;
private DocumentsToolbar mActionBar;
- private MenuItem mMenu;
- private SearchView mView;
+ private MenuItem mMenuItem;
+ private SearchView mSearchView;
public SearchViewManager(SearchManagerListener listener, @Nullable Bundle savedState) {
mListener = listener;
@@ -62,45 +67,61 @@
mListener = listener;
}
- public void install(DocumentsToolbar actionBar) {
- // assert(mActionBar == null);
-
+ public void install(DocumentsToolbar actionBar, boolean isFullBarSearch) {
mActionBar = actionBar;
- mMenu = actionBar.getSearchMenu();
- mView = (SearchView) mMenu.getActionView();
+ mMenuItem = actionBar.getSearchMenu();
+ mSearchView = (SearchView) mMenuItem.getActionView();
- mView.setOnQueryTextListener(this);
- mView.setOnCloseListener(this);
- mView.setOnSearchClickListener(this);
- mView.setOnQueryTextFocusChangeListener(this);
+ mSearchView.setOnQueryTextListener(this);
+ mSearchView.setOnCloseListener(this);
+ mSearchView.setOnSearchClickListener(this);
+ mSearchView.setOnQueryTextFocusChangeListener(this);
+
+ mFullBar = isFullBarSearch;
+ if (mFullBar) {
+ mMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
+ | MenuItem.SHOW_AS_ACTION_ALWAYS);
+ mMenuItem.setOnActionExpandListener(this);
+ }
restoreSearch();
}
/**
+ * Used to hide menu icons, when the search is being restored. Needed because search restoration
+ * is done before onPrepareOptionsMenu(Menu menu) that is overriding the icons visibility.
+ */
+ public void updateMenu() {
+ if (isSearching() && mFullBar) {
+ Menu menu = mActionBar.getMenu();
+ menu.setGroupVisible(R.id.group_hide_when_searching, false);
+ }
+ }
+
+ /**
* @param root Info about the current directory.
*/
void update(RootInfo root) {
- if (mMenu == null) {
+ if (mMenuItem == null) {
if (DEBUG) Log.d(TAG, "update called before Search MenuItem installed.");
return;
}
if (mCurrentSearch != null) {
- mMenu.expandActionView();
+ mMenuItem.expandActionView();
- mView.setIconified(false);
- mView.clearFocus();
- mView.setQuery(mCurrentSearch, false);
+ mSearchView.setIconified(false);
+ mSearchView.clearFocus();
+ mSearchView.setQuery(mCurrentSearch, false);
} else {
- mView.clearFocus();
- if (!mView.isIconified()) {
+ mSearchView.clearFocus();
+ if (!mSearchView.isIconified()) {
mIgnoreNextClose = true;
- mView.setIconified(true);
+ mSearchView.setIconified(true);
}
- if (mMenu.isActionViewExpanded()) {
- mMenu.collapseActionView();
+ if (mMenuItem.isActionViewExpanded()) {
+ mMenuItem.collapseActionView();
}
}
@@ -109,7 +130,7 @@
}
void showMenu(boolean visible) {
- if (mMenu == null) {
+ if (mMenuItem == null) {
if (DEBUG) Log.d(TAG, "showMenu called before Search MenuItem installed.");
return;
}
@@ -118,7 +139,7 @@
mCurrentSearch = null;
}
- mMenu.setVisible(visible);
+ mMenuItem.setVisible(visible);
}
/**
@@ -129,46 +150,46 @@
boolean cancelSearch() {
if (isExpanded() || isSearching()) {
// If the query string is not empty search view won't get iconified
- mView.setQuery("", false);
- // Causes calling onClose(). onClose() is triggering directory content update.
- mView.setIconified(true);
+ mSearchView.setQuery("", false);
+
+ if (mFullBar) {
+ onClose();
+ } else {
+ // Causes calling onClose(). onClose() is triggering directory content update.
+ mSearchView.setIconified(true);
+ }
return true;
}
return false;
}
+ /**
+ * Sets search view into the searching state. Used to restore state after device orientation
+ * change.
+ */
private void restoreSearch() {
if (isSearching()) {
+ if(mFullBar) {
+ mMenuItem.expandActionView();
+ } else {
+ mSearchView.setIconified(false);
+ }
onSearchExpanded();
- mView.setIconified(false);
- mView.setQuery(mCurrentSearch, false);
- mView.clearFocus();
+ mSearchView.setQuery(mCurrentSearch, false);
+ mSearchView.clearFocus();
}
}
private void onSearchExpanded() {
mSearchExpanded = true;
- }
-
- boolean isSearching() {
- return mCurrentSearch != null;
- }
-
- boolean isExpanded() {
- return mSearchExpanded;
+ if(mFullBar) {
+ Menu menu = mActionBar.getMenu();
+ menu.setGroupVisible(R.id.group_hide_when_searching, false);
+ }
}
/**
- * Called when owning activity is saving state to be used to restore state during creation.
- * @param state Bundle to save state too
- */
- public void onSaveInstanceState(Bundle state) {
- state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
- }
-
- /**
- * Clears the search. Clears the SearchView background color. Triggers refreshing of the
- * directory content.
+ * Clears the search. Triggers refreshing of the directory content.
* @return True if the default behavior of clearing/dismissing SearchView should be overridden.
* False otherwise.
*/
@@ -187,13 +208,26 @@
mListener.onSearchChanged(mCurrentSearch);
}
}
+
+ if(mFullBar) {
+ mMenuItem.collapseActionView();
+ }
+ mListener.onSearchFinished();
+
return false;
}
/**
- * Sets mSearchExpanded. Called when search icon is clicked to start search. Used to detect when
- * the view expanded instead of onMenuItemActionExpand, because SearchView has showAsAction set
- * to always and onMenuItemAction* methods are not called.
+ * Called when owning activity is saving state to be used to restore state during creation.
+ * @param state Bundle to save state too
+ */
+ public void onSaveInstanceState(Bundle state) {
+ state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
+ }
+
+ /**
+ * Sets mSearchExpanded. Called when search icon is clicked to start search for both search view
+ * modes.
*/
@Override
public void onClick(View v) {
@@ -203,19 +237,22 @@
@Override
public boolean onQueryTextSubmit(String query) {
mCurrentSearch = query;
- mView.clearFocus();
+ mSearchView.clearFocus();
if (mListener != null) {
mListener.onSearchChanged(mCurrentSearch);
}
return true;
}
+ /**
+ * Used to detect and handle back button pressed event when search is expanded.
+ */
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if (mCurrentSearch == null) {
- mView.setIconified(true);
- } else if (TextUtils.isEmpty(mView.getQuery())) {
+ mSearchView.setIconified(true);
+ } else if (TextUtils.isEmpty(mSearchView.getQuery())) {
cancelSearch();
}
}
@@ -226,8 +263,34 @@
return false;
}
+ @Override
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ Menu menu = mActionBar.getMenu();
+ menu.setGroupVisible(R.id.group_hide_when_searching, true);
+
+ // Handles case when search view is collapsed by using the arrow on the left of the bar
+ if (isExpanded() || isSearching()) {
+ cancelSearch();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemActionExpand(MenuItem item) {
+ return true;
+ }
+
String getCurrentSearch() {
return mCurrentSearch;
}
+ boolean isSearching() {
+ return mCurrentSearch != null;
+ }
+
+ boolean isExpanded() {
+ return mSearchExpanded;
+ }
+
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index d21afee..655359a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -22,6 +22,11 @@
import android.text.format.DateUtils;
import android.text.format.Time;
import android.view.WindowManager;
+
+import com.android.documentsui.State.ActionType;
+
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
+
import android.app.AlertDialog;
import java.text.Collator;
@@ -179,8 +184,9 @@
/*
* Indicates if the advanced roots should be hidden.
*/
- public static boolean areAdvancedRootsHidden(Context context) {
- return context.getResources().getBoolean(R.bool.advanced_roots_hidden);
+ public static boolean areAdvancedRootsHidden(Context context, State state) {
+ return context.getResources().getBoolean(R.bool.advanced_roots_hidden)
+ && state.action != ACTION_OPEN_TREE;
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index 16b7660..534a483 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -43,10 +43,19 @@
private static final String TAG = "State";
+ @IntDef(flag = true, value = {
+ ACTION_BROWSE,
+ ACTION_PICK_COPY_DESTINATION,
+ ACTION_OPEN,
+ ACTION_CREATE,
+ ACTION_GET_CONTENT,
+ ACTION_OPEN_TREE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ActionType {}
// File manager and related private picking activity.
public static final int ACTION_BROWSE = 1;
public static final int ACTION_PICK_COPY_DESTINATION = 2;
-
// All public picking activities
public static final int ACTION_OPEN = 3;
public static final int ACTION_CREATE = 4;
@@ -69,7 +78,7 @@
public static final int SORT_ORDER_LAST_MODIFIED = 2;
public static final int SORT_ORDER_SIZE = 3;
- public int action;
+ public @ActionType int action;
public String[] acceptMimes;
/** Derived from local preferences */
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
index da9f9c3..7c1e2196 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
@@ -167,7 +167,7 @@
return true;
}
- private UiObject findDocumentsList() {
+ public UiObject findDocumentsList() {
return findObject(
"com.android.documentsui:id/container_directory",
DIR_LIST_ID);
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 5089512..098d5a2 100644
--- a/packages/Keyguard/res/values-ky-rKG/strings.xml
+++ b/packages/Keyguard/res/values-ky-rKG/strings.xml
@@ -108,7 +108,7 @@
<string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM-картанын PUK-кодун ачуу кыйрады!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"Код кабыл алынды!"</string>
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Байланыш жок."</string>
- <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"Киргизүү ыкмасын которуу"</string>
+ <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"Киргизүү ыкмасын өзгөртүү"</string>
<string name="airplane_mode" msgid="3122107900897202805">"Учак режими"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкыч талап кылынат"</string>
<string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Түзмөк кайра күйгүзүлгөндөн кийин PIN код талап кылынат"</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 81666fe..a73dcb6 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -108,7 +108,7 @@
<string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM卡PUK码操作失败!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"代码正确!"</string>
<string name="keyguard_carrier_default" msgid="8700650403054042153">"无服务。"</string>
- <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"输入法切换按钮。"</string>
+ <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"切换输入法"</string>
<string name="airplane_mode" msgid="3122107900897202805">"飞行模式"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"重启设备后需要绘制解锁图案"</string>
<string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"重启设备后需要输入 PIN 码"</string>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
index 1fd471c..777dc60 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
@@ -144,6 +144,8 @@
return mCallback.getFileSize(inode);
} catch (FileNotFoundException e) {
return -OsConstants.ENOENT;
+ } catch (UnsupportedOperationException e) {
+ return -OsConstants.ENOTSUP;
}
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 68f426f..246b95de 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -20,6 +20,7 @@
import android.annotation.WorkerThread;
import android.content.ContentResolver;
import android.database.Cursor;
+import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.os.Bundle;
@@ -340,13 +341,46 @@
Log.e(MtpDocumentsProvider.TAG, "Failed to load object info", error);
}
}
+ final long[] objectSizeList = new long[infoList.size()];
+ for (int i = 0; i < infoList.size(); i++) {
+ final MtpObjectInfo info = infoList.get(i);
+ // Compressed size is 32-bit unsigned integer but getCompressedSize returns the
+ // value in Java int (signed 32-bit integer). Use getCompressedSizeLong instead
+ // to get the value in Java long.
+ if (info.getCompressedSizeLong() != 0xffffffffl) {
+ objectSizeList[i] = info.getCompressedSizeLong();
+ continue;
+ }
+
+ if (!MtpDeviceRecord.isSupported(
+ mOperationsSupported,
+ MtpConstants.OPERATION_GET_OBJECT_PROP_DESC) ||
+ !MtpDeviceRecord.isSupported(
+ mOperationsSupported,
+ MtpConstants.OPERATION_GET_OBJECT_PROP_VALUE)) {
+ objectSizeList[i] = -1;
+ continue;
+ }
+
+ // Object size is more than 4GB.
+ try {
+ objectSizeList[i] = mManager.getObjectSizeLong(
+ mIdentifier.mDeviceId,
+ info.getObjectHandle(),
+ info.getFormat());
+ } catch (IOException error) {
+ Log.e(MtpDocumentsProvider.TAG, "Failed to get object size property.", error);
+ objectSizeList[i] = -1;
+ }
+ }
synchronized (this) {
try {
mDatabase.getMapper().putChildDocuments(
mIdentifier.mDeviceId,
mIdentifier.mDocumentId,
mOperationsSupported,
- infoList.toArray(new MtpObjectInfo[infoList.size()]));
+ infoList.toArray(new MtpObjectInfo[infoList.size()]),
+ objectSizeList);
} catch (FileNotFoundException error) {
// Looks like the parent document information is removed.
// Adding documents has already cancelled in Mapper so we don't need to invoke
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
index 8058183..adc71ae 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
@@ -128,16 +128,27 @@
* @param deviceId Device ID
* @param parentId Parent document ID.
* @param documents List of document information.
+ * @param documentSizes 64-bit size of documents. MtpObjectInfo#getComporessedSize will be
+ * ignored because it does not contain 4GB> object size. Can be -1 if the size is unknown.
* @throws FileNotFoundException
*/
synchronized void putChildDocuments(
- int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo[] documents)
+ int deviceId, String parentId,
+ int[] operationsSupported,
+ MtpObjectInfo[] documents,
+ long[] documentSizes)
throws FileNotFoundException {
+ assert documents.length == documentSizes.length;
final ContentValues[] valuesList = new ContentValues[documents.length];
for (int i = 0; i < documents.length; i++) {
valuesList[i] = new ContentValues();
MtpDatabase.getObjectDocumentValues(
- valuesList[i], deviceId, parentId, operationsSupported, documents[i]);
+ valuesList[i],
+ deviceId,
+ parentId,
+ operationsSupported,
+ documents[i],
+ documentSizes[i]);
}
putDocuments(
parentId,
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 4564018..cce619e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -372,12 +372,16 @@
* newly added and never mapped with existing ones.
* @param parentDocumentId
* @param info
+ * @param size Object size. info#getCompressedSize() will be ignored because it does not contain
+ * object size more than 4GB.
* @return Document ID of added document.
*/
String putNewDocument(
- int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info) {
+ int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info,
+ long size) {
final ContentValues values = new ContentValues();
- getObjectDocumentValues(values, deviceId, parentDocumentId, operationsSupported, info);
+ getObjectDocumentValues(
+ values, deviceId, parentDocumentId, operationsSupported, info, size);
mDatabase.beginTransaction();
try {
final long id = mDatabase.insert(TABLE_DOCUMENTS, null, values);
@@ -586,9 +590,9 @@
}
void updateObject(String documentId, int deviceId, String parentId, int[] operationsSupported,
- MtpObjectInfo info) {
+ MtpObjectInfo info, Long size) {
final ContentValues values = new ContentValues();
- getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info);
+ getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info, size);
mDatabase.beginTransaction();
try {
@@ -811,11 +815,12 @@
* @param values {@link ContentValues} that receives values.
* @param deviceId Device ID of the object.
* @param parentId Parent document ID of the object.
- * @param info MTP object info.
+ * @param info MTP object info. getCompressedSize will be ignored.
+ * @param size 64-bit size of documents. Negative value is regarded as unknown size.
*/
static void getObjectDocumentValues(
ContentValues values, int deviceId, String parentId,
- int[] operationsSupported, MtpObjectInfo info) {
+ int[] operationsSupported, MtpObjectInfo info, long size) {
values.clear();
final String mimeType = getMimeType(info);
values.put(COLUMN_DEVICE_ID, deviceId);
@@ -834,7 +839,11 @@
values.put(Document.COLUMN_FLAGS, getDocumentFlags(
operationsSupported, mimeType, info.getThumbCompressedSizeLong(),
info.getProtectionStatus(), DOCUMENT_TYPE_OBJECT));
- values.put(Document.COLUMN_SIZE, info.getCompressedSizeLong());
+ if (size >= 0) {
+ values.put(Document.COLUMN_SIZE, size);
+ } else {
+ values.putNull(Document.COLUMN_SIZE);
+ }
}
private static String getMimeType(MtpObjectInfo info) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
index 393c4de..c52b81d 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
@@ -56,8 +56,15 @@
}
static boolean isPartialReadSupported(@Nullable int[] supportedList, long fileSize) {
- return fileSize <= 0xffffffffl &&
- isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT);
+ if (isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) {
+ return true;
+ }
+ if (0 <= fileSize &&
+ fileSize <= 0xffffffffL &&
+ isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) {
+ return true;
+ }
+ return false;
}
static boolean isWritingSupported(@Nullable int[] supportedList) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 4152d1e..9f64046ce 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -30,7 +30,6 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
-import android.os.FileUriExposedException;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
@@ -235,11 +234,14 @@
final MtpDeviceRecord device = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord;
switch (mode) {
case "r":
- final long fileSize = getFileSize(documentId);
+ long fileSize;
+ try {
+ fileSize = getFileSize(documentId);
+ } catch (UnsupportedOperationException exception) {
+ fileSize = -1;
+ }
// MTP getPartialObject operation does not support files that are larger than
// 4GB. Fallback to non-seekable file descriptor.
- // TODO: Use getPartialObject64 for MTP devices that support Android vendor
- // extension.
if (MtpDeviceRecord.isPartialReadSupported(
device.operationsSupported, fileSize)) {
return mAppFuse.openFile(
@@ -389,7 +391,7 @@
new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
final String documentId = mDatabase.putNewDocument(
parentId.mDeviceId, parentDocumentId, record.operationsSupported,
- infoWithHandle);
+ infoWithHandle, 0l);
getDocumentLoader(parentId).clearTask(parentId);
notifyChildDocumentsChange(parentDocumentId);
return documentId;
@@ -544,6 +546,9 @@
MtpDatabase.strings(Document.COLUMN_SIZE, Document.COLUMN_DISPLAY_NAME));
try {
if (cursor.moveToNext()) {
+ if (cursor.isNull(0)) {
+ throw new UnsupportedOperationException();
+ }
return cursor.getLong(0);
} else {
throw new FileNotFoundException();
@@ -595,12 +600,20 @@
int inode, long offset, long size, byte[] buffer) throws IOException {
final Identifier identifier = mDatabase.createIdentifier(Integer.toString(inode));
final MtpDeviceRecord record = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord;
- if (MtpDeviceRecord.isPartialReadSupported(record.operationsSupported, offset)) {
+
+ if (MtpDeviceRecord.isSupported(
+ record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) {
+ return mMtpManager.getPartialObject64(
+ identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer);
+ }
+
+ if (0 <= offset && offset <= 0xffffffffL && MtpDeviceRecord.isSupported(
+ record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) {
return mMtpManager.getPartialObject(
identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer);
- } else {
- throw new UnsupportedOperationException();
}
+
+ throw new UnsupportedOperationException();
}
@Override
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 0599b70..00d31a7 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -170,6 +170,14 @@
}
}
+ long getPartialObject64(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
+ throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ synchronized (device) {
+ return device.getPartialObject64(objectHandle, offset, size, buffer);
+ }
+ }
+
byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
@@ -229,6 +237,11 @@
return device.readEvent(signal);
}
+ long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ return device.getObjectSizeLong(objectHandle, format);
+ }
+
private synchronized MtpDevice getDevice(int deviceId) throws IOException {
final MtpDevice device = mDevices.get(deviceId);
if (device == null) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
index c10a65e..1520f3b 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -174,7 +174,8 @@
mIdentifier.mDeviceId,
parentIdentifier.mDocumentId,
mOperationsSupported,
- newObjectInfo);
+ newObjectInfo,
+ tempFile.length());
} catch (IOException error) {
Log.w(MtpDocumentsProvider.TAG,
"Failed to send a file because of: " + error.getMessage());
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index 284223b..404047b 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -200,7 +200,7 @@
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
- });
+ }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});
final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2");
assertEquals(3, cursor.getCount());
@@ -273,7 +273,7 @@
mDatabase.getMapper().startAddingDocuments("2");
mDatabase.getMapper().putChildDocuments(0, "2", new int[0], new MtpObjectInfo[] {
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
try (final Cursor cursor =
@@ -290,7 +290,7 @@
MtpConstants.OPERATION_SEND_OBJECT_INFO,
}, new MtpObjectInfo[] {
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
try (final Cursor cursor =
@@ -306,7 +306,7 @@
MtpConstants.OPERATION_DELETE_OBJECT
}, new MtpObjectInfo[] {
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
try (final Cursor cursor =
@@ -395,7 +395,7 @@
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
- });
+ }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});
mDatabase.getMapper().clearMapping();
addTestDevice();
@@ -412,7 +412,7 @@
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
- });
+ }, new long[] { 1024L, 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
{
@@ -545,7 +545,7 @@
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
- });
+ }, new long[] { 0L, 0L });
mDatabase.getMapper().stopAddingDocuments("2");
// Put note.txt in each directory.
@@ -553,10 +553,10 @@
mDatabase.getMapper().startAddingDocuments("4");
mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
// Clear mapping.
mDatabase.getMapper().clearMapping();
@@ -568,7 +568,7 @@
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
- });
+ }, new long[] { 0L, 0L });
mDatabase.getMapper().stopAddingDocuments("2");
// Add note.txt in each directory again.
@@ -576,10 +576,10 @@
mDatabase.getMapper().startAddingDocuments("4");
mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("3");
mDatabase.getMapper().stopAddingDocuments("4");
@@ -860,7 +860,7 @@
mDatabase.getMapper().startAddingDocuments("2");
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId);
@@ -873,13 +873,13 @@
mDatabase.getMapper().startAddingDocuments("2");
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
mDatabase.getMapper().startAddingDocuments("3");
mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L });
mDatabase.getMapper().stopAddingDocuments("3");
mDatabase.deleteDocument("3");
@@ -909,7 +909,8 @@
"3",
mDatabase.putNewDocument(
0, "2", OPERATIONS_SUPPORTED,
- createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
+ createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+ 1024L));
{
final Cursor cursor =
@@ -928,7 +929,8 @@
mDatabase.getMapper().startAddingDocuments("2");
mDatabase.putNewDocument(
0, "2", OPERATIONS_SUPPORTED,
- createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
+ createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+ 1024L);
mDatabase.getMapper().stopAddingDocuments("2");
{
@@ -1045,7 +1047,7 @@
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L, 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
// Disconnect the device.
@@ -1064,7 +1066,7 @@
mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
- });
+ }, new long[] { 1024L, 1024L });
mDatabase.getMapper().stopAddingDocuments("2");
try (final Cursor cursor = mDatabase.queryChildDocuments(
@@ -1093,7 +1095,7 @@
createDocument(102, "unknown.mp4", MtpConstants.FORMAT_MPEG, 1000),
createDocument(103, "inconsistent.txt", MtpConstants.FORMAT_MPEG, 1000),
createDocument(104, "noext", MtpConstants.FORMAT_UNDEFINED, 1000),
- });
+ }, new long[] { 1000L, 1000L, 1000L, 1000L, 1000L });
mDatabase.getMapper().stopAddingDocuments("2");
try (final Cursor cursor = mDatabase.queryChildDocuments(
strings(COLUMN_DISPLAY_NAME, COLUMN_MIME_TYPE),
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index da6af37..0de761c 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -708,6 +708,33 @@
} catch (UnsupportedOperationException exception) {}
}
+ public void testObjectSizeLong() throws Exception {
+ setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+ setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
+ mMtpManager.setObjectSizeLong(0, 100, MtpConstants.FORMAT_EXIF_JPEG, 0x400000000L);
+ setupDocuments(
+ 0,
+ 0,
+ MtpManager.OBJECT_HANDLE_ROOT_CHILDREN,
+ "1",
+ new MtpObjectInfo[] {
+ new MtpObjectInfo.Builder()
+ .setObjectHandle(100)
+ .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
+ .setName("image.jpg")
+ .setCompressedSize(0xffffffffl)
+ .build()
+ });
+
+ final Cursor cursor = mProvider.queryDocument("3", new String[] {
+ DocumentsContract.Document.COLUMN_SIZE
+ });
+ assertEquals(1, cursor.getCount());
+
+ cursor.moveToNext();
+ assertEquals(0x400000000L, cursor.getLong(0));
+ }
+
private void setupProvider(int flag) {
mDatabase = new MtpDatabase(getContext(), flag);
mProvider = new MtpDocumentsProvider();
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index a08d9ee..8611797 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -75,7 +75,8 @@
mDatabase.getMapper().startAddingDocuments("2");
mDatabase.getMapper().putChildDocuments(
0, "2", TestUtil.OPERATIONS_SUPPORTED,
- new MtpObjectInfo[] { info });
+ new MtpObjectInfo[] { info },
+ new long[] { 0L });
mDatabase.getMapper().stopAddingDocuments("2");
// Create a placeholder file which should be replaced by a real file later.
mtpManager.setObjectInfo(0, info);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 5171bd2..9a81489 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -39,6 +39,7 @@
private final Map<String, int[]> mObjectHandles = new HashMap<>();
private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
+ private final Map<String, Long> mObjectSizeLongs = new HashMap<>();
TestMtpManager(Context context) {
super(context);
@@ -68,6 +69,10 @@
mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
}
+ void setObjectSizeLong(int deviceId, int objectHandle, int format, long value) {
+ mObjectSizeLongs.put(pack(deviceId, objectHandle, format), value);
+ }
+
@Override
MtpDeviceRecord[] getDevices() {
final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
@@ -214,4 +219,14 @@
}
return i;
}
+
+ @Override
+ long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
+ final String key = pack(deviceId, objectHandle, format);
+ if (mObjectSizeLongs.containsKey(key)) {
+ return mObjectSizeLongs.get(key);
+ } else {
+ throw new IOException();
+ }
+ }
}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
index 5ceab01..8805d19 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
@@ -38,6 +38,8 @@
MtpConstants.OPERATION_SEND_OBJECT,
MtpConstants.OPERATION_SEND_OBJECT_INFO,
MtpConstants.OPERATION_DELETE_OBJECT,
+ MtpConstants.OPERATION_GET_OBJECT_PROP_DESC,
+ MtpConstants.OPERATION_GET_OBJECT_PROP_VALUE
};
/**
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 2bcd851..ed6fdb7 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -57,7 +57,7 @@
<activity
android:name=".ui.PrintActivity"
- android:configChanges="screenSize|smallestScreenSize|orientation"
+ android:configChanges="screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection"
android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
android:theme="@style/Theme.PrintActivity">
<intent-filter>
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
index c8478f2..0224c6c 100644
--- a/packages/PrintSpooler/res/values-af/strings.xml
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Herbegin"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met drukker nie"</string>
<string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie beskikbaar nie"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Gebruik <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Jou dokument kan dalk deur een of meer bedieners op pad na die drukker gaan."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Jammer, dit het nie gewerk nie. Probeer weer."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Herprobeer"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Hierdie drukker is nie op die oomblik beskikbaar nie."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan nie voorskou wys nie"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Berei tans voorskou voor …"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index d4426cc..98255d4 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"እንደገና ጀምር"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ከአታሚ ጋር ምንም ግንኙነት የለም"</string>
<string name="reason_unknown" msgid="5507940196503246139">"አይታወቅም"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – አይገኝም"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ይጠቀሙ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ሰነድዎ ወደ አታሚው በሚሄድበት ወቅት በአንድ ወይም ከዚያ በላይ አገልጋዮች ውስጥ ሊያልፍ ይችላል።"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ይቅርታ፣ ያ አልሰራም። እንደገና ይሞክሩ።"</string>
<string name="print_error_retry" msgid="1426421728784259538">"እንደገና ይሞክሩ"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"አታሚው አሁን አይገኝም።"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"ቅድመ ዕይታን ማሳየት አይቻልም"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"ቅድመ እይታን በማዘጋጀት ላይ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index 2e1b6d0..5f0255c 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -84,7 +84,6 @@
<string name="restart" msgid="2472034227037808749">"إعادة تشغيل"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"لا يوجد اتصال بالطابعة"</string>
<string name="reason_unknown" msgid="5507940196503246139">"غير معروف"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – غير متاحة"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"هل تريد استخدام <xliff:g id="SERVICE">%1$s</xliff:g>؟"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"من الممكن أن يمر المستند عبر خادم أو أكثر أثناء إرساله إلى الطابعة."</string>
<string-array name="color_mode_labels">
@@ -104,5 +103,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"عذرًا، هذا لا يعمل. أعد المحاولة."</string>
<string name="print_error_retry" msgid="1426421728784259538">"إعادة المحاولة"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"الطابعة ليست متوفرة في الوقت الحالي."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"يتعذر عرض المعاينة."</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"جارٍ تحضير المعاينة…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
index 5490b84..b5dfaf8 100644
--- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml
+++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Yenidən başlat"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Printerə heç bir bağlantı yoxdur"</string>
<string name="reason_unknown" msgid="5507940196503246139">"naməlum"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>– əlçatmaz"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətindən istifadə edilsin?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Sənədiniz printerə qədər bir və ya daha çox server vasitəsilə keçə bilər."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Üzr istəyirik, alınmadı. Yenidən cəhd edin."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Yenidən yoxla"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Bu printer hazırda əlçatan deyil."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Önizləmə göstərilə bilmir"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Önizləməyə hazırlıq gedir..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 0574dae..2ac8002 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze sa štampačem"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nedostupan"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li da koristite <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument može da prođe kroz jedan ili više servera na putu do štampača."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Žao nam je, ovo nije uspelo. Pokušajte ponovo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Pokušajte ponovo"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ovaj štampač trenutno nije dostupan."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nije uspeo prikaz pregleda"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-be-rBY/strings.xml b/packages/PrintSpooler/res/values-be-rBY/strings.xml
index b581045..13d573e 100644
--- a/packages/PrintSpooler/res/values-be-rBY/strings.xml
+++ b/packages/PrintSpooler/res/values-be-rBY/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Перазапусціць"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Няма падлучэння да прынтара"</string>
<string name="reason_unknown" msgid="5507940196503246139">"невядома"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недаступна"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Выкарыстоўваць службу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Ваш дакумент можа прайсці праз адзін ці больш сервераў перад тым, як будзе надрукаваны."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"На жаль, не атрымалася. Паспрабуйце яшчэ раз."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Паўтарыць спробу"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Гэты прынтар зараз недаступны."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Папярэдні прагляд немагчымы"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Падрыхтоўка папярэдняга прагляду..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
index 88af8e4..73c51e9 100644
--- a/packages/PrintSpooler/res/values-bg/strings.xml
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Рестартиране"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Няма връзка с принтера"</string>
<string name="reason_unknown" msgid="5507940196503246139">"няма данни"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – не е налице"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Да се използва ли „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"По пътя към принтера документът ви може да премине през един или повече сървъри."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"За съжаление това не проработи. Опитайте отново."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Нов опит"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"В момента този принтер не е налице."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Визуализацията не може да се покаже"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Визуализацията се подготвя…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index c61ef74..25b4660 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"পুনর্সূচনা"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"মুদ্রকে কোনো সংযোগ নেই"</string>
<string name="reason_unknown" msgid="5507940196503246139">"অজানা"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – অনুপলব্ধ"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ব্যবহার করবেন?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"আপনার দস্তাবেজ মুদ্রকে যাওয়ার সময় এক বা একাধিক সার্ভারের মাধ্যমে পাস হতে পারে।"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"দুঃখিত, এটি কাজ করেনি৷ আবার চেষ্টা করুন৷"</string>
<string name="print_error_retry" msgid="1426421728784259538">"পুনরায় চেষ্টা করুন"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"এই মূহুর্তে প্রিন্টার উপলব্ধ নয়।"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"পূর্বরূপ প্রদর্শন করা যাবে না"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"পূর্বরূপ প্রস্তুত করছে..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-bs-rBA/strings.xml b/packages/PrintSpooler/res/values-bs-rBA/strings.xml
index 7465c3c..9a17707 100644
--- a/packages/PrintSpooler/res/values-bs-rBA/strings.xml
+++ b/packages/PrintSpooler/res/values-bs-rBA/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nema konekcije sa štampačem"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nepoznat"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nedostupan"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Zaista želite koristiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Moguće je da dokument prije štampanja prođe kroz jedan ili više servera."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Nažalost, nije uspjelo. Pokušajte ponovo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Ponovi"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Štampač trenutno nije dostupan."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Pregled se ne može prikazati"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index 482100a..a1df406 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reinicia"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No hi ha connexió amb la impressora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconegut"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Vols fer servir <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"És possible que el document passi com a mínim per un servidor abans d\'imprimir-se."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionat. Torna-ho a provar."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Torna-ho a provar"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ara mateix, aquesta impressora no està disponible."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"La previsualització no es pot mostrar"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"S\'està preparant la previsualització..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index a4c412c..55fb21b 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Restartovat"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nelze se připojit k tiskárně"</string>
<string name="reason_unknown" msgid="5507940196503246139">"neznámé"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – není k dispozici"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Použít službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument může cestou do tiskárny projít jedním i více servery."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Litujeme, nepodařilo se. Zkuste to znovu."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Opakovat"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Tiskárna aktuálně není k dispozici."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Náhled nelze zobrazit"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Příprava náhledu…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index 9ee252167..49417bd 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Genstart"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse til printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ukendt"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ikke tilgængelig"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruge <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dit dokument passerer muligvis gennem én eller flere servere på vej til printeren."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Det virkede desværre ikke. Prøv igen."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Prøv igen"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Denne printer er i øjeblikket ikke tilgængelig."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Eksempelvisning kan ikke vises"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Eksempelvisning forberedes..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index ef451b7..cb7aeee 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Neu starten"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Keine Verbindung zum Drucker"</string>
<string name="reason_unknown" msgid="5507940196503246139">"unbekannt"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nicht verfügbar"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> verwenden?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dein Dokument passiert bei der Übermittlung an den Drucker möglicherweise einen oder mehrere Server."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuche es erneut."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Erneut versuchen"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Dieser Drucker ist momentan nicht verfügbar."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Vorschau kann nicht angezeigt werden"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Vorschau wird vorbereitet…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
index 9be81c1..4441ea2 100644
--- a/packages/PrintSpooler/res/values-el/strings.xml
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Επανεκκίνηση"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Δεν υπάρχει σύνδεση με εκτυπωτή"</string>
<string name="reason_unknown" msgid="5507940196503246139">"άγνωστο"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – μη διαθέσιμο"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Να χρησιμοποιηθεί η υπηρεσία <xliff:g id="SERVICE">%1$s</xliff:g>;"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Το έγγραφό σας μπορεί να περάσει από έναν ή περισσότερους διακομιστές κατά τη μετάβαση στον εκτυπωτή."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Δυστυχώς, αυτό δεν λειτούργησε. Δοκιμάστε ξανά."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Επανάληψη"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Αυτός ο εκτυπωτής δεν είναι διαθέσιμος αυτήν τη στιγμή."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Αδυναμία προβολής προεπισκόπησης"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Προετοιμασία προεπισκόπησης…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rAU/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Restart"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rGB/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Restart"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Restart"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 8fa6094..8d55597 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora."</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Deseas usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"No funcionó. Vuelve a intentarlo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Volver a intentar"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"No se puede mostrar la vista previa"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index dba0491..7d08a0e 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Volver a empezar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – no disponible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionado. Prueba de nuevo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Reintentar"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"No se puede mostrar la vista previa"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
index 6dde083..09da3e0 100644
--- a/packages/PrintSpooler/res/values-et-rEE/strings.xml
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Taaskäivita"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Printeriühendus puudub"</string>
<string name="reason_unknown" msgid="5507940196503246139">"teadmata"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – pole saadaval"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Kas soovite kasutada teenust <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Printerini jõudmiseks võib dokument läbida ühe või mitu serverit."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Kahjuks see ei toiminud. Proovige uuesti."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Proovi uuesti"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"See printer ei ole praegu saadaval."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Eelvaadet ei õnnestu kuvada"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Eelvaate ettevalmistamine ..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 858444b..6b760b4 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Berrabiarazi"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Inprimagailua ez dago konektatuta"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ezezaguna"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: ez dago erabilgarri"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> erabili nahi duzu?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Baliteke dokumentuak zerbitzari batean edo gehiagotan zehar igarotzea inprimagailurako bidean."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Horrek ez du funtzionatu. Saiatu berriro."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Saiatu berriro"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Une honetan inprimagailua ez dago erabilgarri."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Ezin da bistaratu aurrebista"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Aurrebista prestatzen…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 7c69c27..fa105d5 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"راهاندازی مجدد"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"اتصال با چاپگر برقرار نیست"</string>
<string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - در دسترس نیست"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"از <xliff:g id="SERVICE">%1$s</xliff:g> استفاده شود؟"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ممکن است سندتان برای رسیدن به چاپگر از یک یا چند سرور عبور کند."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"متأسفیم، تلاش ناموفق بود. دوباره امتحان کنید."</string>
<string name="print_error_retry" msgid="1426421728784259538">"امتحان مجدد"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"این چاپگر اکنون در دسترس نیست."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"نمایش پیشنمایش امکانپذیر نیست"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"در حال آمادهسازی پیشنمایش…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index dfd98f8..cf051f8 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Käynnistä uudelleen"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ei yhteyttä tulostimeen"</string>
<string name="reason_unknown" msgid="5507940196503246139">"tuntematon"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ei käytettävissä"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Käytetäänkö palvelua <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Asiakirja saattaa kulkea yhden tai useamman palvelimen kautta matkalla tulostimeen."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Ei valitettavasti onnistunut. Yritä uudelleen."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Yritä uudelleen"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Tämä tulostin ei ole käyttävissä juuri nyt."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Esikatselua ei voi näyttää."</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Esikatselua valmistellaan…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index a95d565..11d2875 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Recommencer"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante"</string>
<string name="reason_unknown" msgid="5507940196503246139">"inconnu"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — indisponible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'arriver à l\'imprimante."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Échec de l\'action. Réessayez."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Réessayer"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Cette imprimante n\'est pas accessible pour le moment."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossible d\'afficher l\'aperçu"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Préparation de l\'aperçu en cours…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index dd1f490..6b89281 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Redémarrer"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante."</string>
<string name="reason_unknown" msgid="5507940196503246139">"inconnue"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'être envoyé sur l\'imprimante."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Échec de l\'opération. Veuillez réessayer."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Réessayer"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Cette imprimante n\'est pas disponible actuellement."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossible d\'afficher l\'aperçu"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Préparation de l\'aperçu en cours…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index 81e080e..7ddc9f8 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Non hai conexión coa impresora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"descoñecido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: non dispoñible"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Queres usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"É posible que o teu documento pase por un ou máis servidores antes de imprimirse."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Non funcionou. Téntao de novo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Tentar de novo"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora non está dispoñible nestes momentos."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Non se pode mostrar a vista previa"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparando a vista previa…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
index 44ede86..6a7e0df 100644
--- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"પુનઃપ્રારંભ કરો"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"પ્રિન્ટર માટે કોઈ કનેક્શન નથી"</string>
<string name="reason_unknown" msgid="5507940196503246139">"અજાણ્યું"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – અનુપલબ્ધ"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> નો ઉપયોગ કરીએ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"તમારો દસ્તાવેજ પ્રિન્ટર સુધીના તેના માર્ગમાં એક અથવા વધુ સર્વર્સથી પસાર થઈ શકે છે."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"માફ કરશો, તે કામ કરતું નહોતું. ફરીથી પ્રયાસ કરો."</string>
<string name="print_error_retry" msgid="1426421728784259538">"ફરી પ્રયાસ કરો"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"આ પ્રિન્ટર અત્યારે ઉપલબ્ધ નથી."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"પૂર્વાવલોકન પ્રદર્શિત કરી શકતાં નથી"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"પૂર્વાવલોકનની તૈયારી કરી રહ્યું છે..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index f75630e..377dc62 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"पुन: आरंभ करें"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटर के लिए कोई कनेक्शन नहीं"</string>
<string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्ध"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> का उपयोग करें?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"प्रिंटर पर जाते समय आपका दस्तावेज़ एक या अधिक सर्वर से गुज़र सकता है."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"क्षमा करें, उससे बात नहीं बनी. पुन: प्रयास करें."</string>
<string name="print_error_retry" msgid="1426421728784259538">"फिर से प्रयास करें"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"यह प्रिंटर इस समय उपलब्ध नहीं है."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकन प्रदर्शित नहीं किया जा सकता"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तैयार हो रहा है..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index bd29d02..8550be4 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze s pisačem"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – zadatak nije dostupan"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li upotrijebiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Na putu do pisača vaš dokument može proći kroz jedan ili više poslužitelja."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Nažalost, to nije uspjelo. Pokušajte ponovo."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Pokušajte ponovno"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Pisač trenutačno nije dostupan."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Pregled nije dostupan"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
index 356cb76..20789a3 100644
--- a/packages/PrintSpooler/res/values-hu/strings.xml
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Újraindítás"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nincs kapcsolat a nyomtatóval"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ismeretlen"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nem érhető el"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Használni szeretné a következő szolgáltatást: <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"A dokumentum áthaladhat egy vagy több szerveren, mielőtt a nyomtatóhoz érne."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Sajnáljuk, de nem sikerült. Próbálja újra."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Újra"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ez a nyomtató jelenleg nem érhető el."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nem lehet megjeleníteni az előnézetet"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Előnézet előkészítése…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index 2d10166..8950338 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Վերագործարկել"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Տպիչի հետ կապ չկա"</string>
<string name="reason_unknown" msgid="5507940196503246139">"անհայտ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> տպիչն անհասանելի է"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Օգտագործե՞լ <xliff:g id="SERVICE">%1$s</xliff:g>-ը:"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Հնարավոր է՝ փաստաթուղթը մի քանի սերվերներով անցնի մինչ տպվելը:"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Չհաջողվեց: Նորից փորձեք:"</string>
<string name="print_error_retry" msgid="1426421728784259538">"Կրկնել"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Տպիչն այս պահին հասանելի չէ:"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Նախադիտումը հնարավոր չէ"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Նախադիտումը պատրաստվում է…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index 8e20d27..9b72250 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Mulai Ulang"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Tidak ada sambungan ke printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"tak diketahui"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen Anda dapat melewati satu atau beberapa server saat menuju printer."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Maaf, tidak berhasil. Coba lagi."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Coba lagi"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Saat ini printer ini tidak tersedia."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Tidak dapat menampilkan pratinjau"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Menyiapkan pratinjau..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index 73660fb..37abb5a 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Endurræsa"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Engin tenging við prentara"</string>
<string name="reason_unknown" msgid="5507940196503246139">"óþekkt"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ekki í boði"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Nota <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skjalið gæti þurft að fara í gegnum einn eða fleiri þjóna á leið sinni til prentarans."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Þetta virkaði því miður ekki. Reyndu aftur."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Reyna aftur"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Þessi prentari er ekki í boði núna."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Ekki hægt að birta forskoðun"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Undirbýr forskoðun…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index 46a570d..dd4a8cb 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Riavvia"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nessun collegamento alla stampante"</string>
<string name="reason_unknown" msgid="5507940196503246139">"sconosciuto"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - non disponibile"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Utilizzare <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Il tuo documento potrebbe passare da uno o più server per raggiungere la stampante."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Non ha funzionato. Riprova."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Riprova"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Al momento la stampante non è disponibile."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossibile visualizzare l\'anteprima"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparazione anteprima…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index c26c3d1..1d813bb 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"הפעל מחדש"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
<string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – לא זמינה"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש ב-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ייתכן שהמסמך שלך יעבור בשרת אחד או יותר בדרכו למדפסת."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"מצטערים, אך זה לא עבד. נסה שוב."</string>
<string name="print_error_retry" msgid="1426421728784259538">"נסה שוב"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"המדפסת הזו אינה זמינה כעת."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"לא ניתן להציג תצוגה מקדימה"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"מכין תצוגה מקדימה…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index a6e243f..946052a 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"再試行"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"プリンタに接続されていません"</string>
<string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>–使用不可"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>を利用しますか?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ドキュメントは1つ以上のサーバーを経由してプリンタに送信されることがあります。"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"エラーです。もう一度お試しください。"</string>
<string name="print_error_retry" msgid="1426421728784259538">"再試行"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"現在このプリンターは使用できません。"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"プレビューを表示できません"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"プレビューを準備しています…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index 2608ed4..94152b1 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"გადატვირთვა"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"პრინტერთან კავშირი არ არის"</string>
<string name="reason_unknown" msgid="5507940196503246139">"უცნობი"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – მიუწვდომელია"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"გსურთ, გამოიყენოთ <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"პრინტერამდე გზად დოკუმენტმა შეიძლება ერთი ან მეტი სერვერი გაიაროს."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"უკაცრავად, ვერ მოხერხდა. სცადეთ ისევ."</string>
<string name="print_error_retry" msgid="1426421728784259538">"გამეორება"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"პრინტერი ამჟამად მიუწვდომელია."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"გადახედვის ჩვენება ვერ ხერხდება"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"მზადდება გადახედვა…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index def0c3c..2bc5ab6 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Қайта бастау"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Принтермен байланыс жоқ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"белгісіз"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – қол жетімсіз"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> қолданылсын ба?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Құжат принтерге жеткенше бір немесе бірнеше серверден өтуі мүмкін."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Кешіріңіз, бұл нәтиже бермеді. Әрекетті қайталаңыз."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Қайталау"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Бұл принтер дәл қазір қол жетімді емес."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Алдын ала қарауды көрсету мүмкін емес"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Алдын ала қарау дайындалуда…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index 24048cf..330edf5 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"ចាប់ផ្ដើមឡើងវិញ"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មានការភ្ជាប់ទៅម៉ាស៊ីនបោះពុម្ព"</string>
<string name="reason_unknown" msgid="5507940196503246139">"មិនស្គាល់"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិនអាចប្រើបាន"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"ប្រើ <xliff:g id="SERVICE">%1$s</xliff:g> ឬ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ឯកសាររបស់អ្នកអាចនឹងឆ្លងកាត់ម៉ាស៊ីនមេមួយ ឬច្រើននៅពេលដែលវាធ្វើដំណើរទៅកាន់ម៉ាស៊ីនបោះពុម្ព។"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"សូមទោស វាមិនដំណើរការទេ។ ព្យាយាមម្ដងទៀត។"</string>
<string name="print_error_retry" msgid="1426421728784259538">"ព្យាយាមម្ដងទៀត"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ឥឡូវនេះ ម៉ាស៊ីនបោះពុម្ពនេះមិនអាចប្រើបាន។"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"មិនអាចបង្ហាញការមើលជាមុនបានទេ"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"កំពុងរៀបចំមើលជាមុន…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index af20965..f1cef86 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"ಮರುಪ್ರಾರಂಭಿಸು"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ಮುದ್ರಕಕ್ಕೆ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ಅಜ್ಞಾತ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ಬಳಸುವುದೇ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ನಿಮ್ಮ ಡಾಕ್ಯುಮೆಂಟ್ ಪ್ರಿಂಟರ್ಗೆ ಹೋಗುವ ಸಂದರ್ಭದಲ್ಲಿ ಒಂದು ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸರ್ವರ್ಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬಹುದು."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ಕ್ಷಮಿಸಿ, ಅದು ಕೆಲಸ ಮಾಡುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="print_error_retry" msgid="1426421728784259538">"ಮರುಪ್ರಯತ್ನಿಸು"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ಈ ಪ್ರಿಂಟರ್ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"ಪೂರ್ವವೀಕ್ಷಣೆ ಪ್ರದರ್ಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"ಪೂರ್ವವೀಕ್ಷಣೆ ತಯಾರಾಗುತ್ತಿದೆ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
index 0b297a2..d3cc967 100644
--- a/packages/PrintSpooler/res/values-ko/strings.xml
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"다시 시작"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"프린터와 연결되지 않음"</string>
<string name="reason_unknown" msgid="5507940196503246139">"알 수 없음"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 사용할 수 없음"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>을(를) 사용할까요?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"문서가 프린터로 전송되는 중에 하나 이상의 서버를 통과할 수 있습니다."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"죄송합니다. 오류가 발생했습니다. 다시 시도해 보세요."</string>
<string name="print_error_retry" msgid="1426421728784259538">"다시 시도"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"현재 이 프린터를 사용할 수 없습니다."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"미리보기를 표시할 수 없음"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"미리보기 준비 중…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index 85b2526..d84e5d8 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Кайра баштоо"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер менен байланыш жок"</string>
<string name="reason_unknown" msgid="5507940196503246139">"белгисиз"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – жеткиликтүү эмес"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> колдонулсунбу?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Принтерге жеткиче документиңиз бир же андан көп серверлерден өтүшү мүмкүн."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Кечиресиз, иштеген жок. Дагы бир жолу аракет кылып көрүңүз."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Дагы бир жолу аракет кылуу"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Учурда бул принтерди колдонуу мүмкүн эмес."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Алдын ала көрүнүшү көрсөтүлбөй жатат"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Алдын-ала көрүүгө даярданууда…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 81ace83..6a69053 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"ປິດເປີດໃໝ່"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ບໍ່ມີການເຊື່ອມຕໍ່ຫາເຄື່ອງພິມ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ບໍ່ຮູ້ຈັກ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - ບໍ່ມີຢູ່"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"ໃຊ້ <xliff:g id="SERVICE">%1$s</xliff:g> ບໍ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ເອກະສານຂອງທ່ານອາດເດີນທາງຜ່ານໜຶ່ງ ຫຼື ຫຼາຍເຊີບເວີ ເພື່ອໄປຮອດເຄື່ອງພິມ."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ຂໍອະໄພ, ໃຊ້ບໍ່ໄດ້. ໃຫ້ລອງໃໝ່ອີກເທື່ອນຶ່ງ."</string>
<string name="print_error_retry" msgid="1426421728784259538">"ລອງໃໝ່"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ບໍ່ສາມາດໃຊ້ເຄື່ອງພິມນີ້ໃນເວລານີ້ໄດ້."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"ບໍ່ສາມາດສະແດງຕົວຢ່າງໄດ້"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"ກຳລັງກະກຽມຕົວຢ່າງ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
index 40bc7f1..ddcaba7 100644
--- a/packages/PrintSpooler/res/values-lt/strings.xml
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Paleisti iš naujo"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nėra ryšio su spausdintuvu"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nežinoma"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ – nepasiekiama"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Naudoti „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Kai dokumentas siunčiamas į spausdintuvą, jis gali būti perduodamas per vieną ar daugiau serverių."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Deja, tai neveikia. Bandykite dar kartą."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Bandykite dar kartą"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Šis spausdintuvas šiuo metu nepasiekiamas."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nepavyksta pateikti peržiūros"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Ruošiama peržiūra…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
index 11e689b..50ba32d 100644
--- a/packages/PrintSpooler/res/values-lv/strings.xml
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Restartēt"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nav savienojuma ar printeri"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nezināms"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — nav pieejams"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Vai izmantot pakalpojumu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokuments, iespējams, tiek pārsūtīts caur vienu vai vairākiem serveriem, līdz tas nonāk līdz printerim."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Diemžēl tas neizdevās. Mēģiniet vēlreiz."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Mēģināt vēlreiz"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Šis printeris šobrīd nav pieejams."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nevar attēlot priekšskatījumu"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Notiek priekšskatījuma sagatavošana..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index bc2b498..a189042 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Рестартирај"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Нема поврзување со печатач"</string>
<string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - недостапен"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Користи <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"На пат до печатачот, документот може да помине преку еден или повеќе сервери."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"За жал, тоа не успеа. Обидете се повторно."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Обиди се повторно"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овој печатач не е достапен во моментов."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Прегледот не може да се прикаже"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Се подготвува преглед…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index ade7fb39..5625632 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"പുനരാരംഭിക്കുക"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"പ്രിന്ററിൽ കണക്ഷനൊന്നുമില്ല"</string>
<string name="reason_unknown" msgid="5507940196503246139">"അജ്ഞാതം"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ലഭ്യമല്ല"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ഉപയോഗിക്കണോ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"നിങ്ങളുടെ പ്രമാണം പ്രിന്ററിലേക്ക് പോകുന്നതിനിടെ അത് ഒന്നോ അതിലധികമോ സെർവറുകളിലൂടെ കടന്നുപോകാനിടയുണ്ട്."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ക്ഷമിക്കണം, അത് പ്രവർത്തിച്ചില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="print_error_retry" msgid="1426421728784259538">"വീണ്ടും ശ്രമിക്കുക"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ഈ പ്രിന്ററർ ഇപ്പോൾ ലഭ്യമല്ല."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"പ്രിവ്യൂ കാണിക്കാൻ കഴിയില്ല"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"പ്രിവ്യൂ തയ്യാറാക്കുന്നു…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
index 133d88c..7797944 100644
--- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Дахин эхлүүлэх"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер холбогдоогүй байна"</string>
<string name="reason_unknown" msgid="5507940196503246139">"тодорхойгүй"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ашиглах боломжгүй"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>-г ашиглах уу?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Таны документ хэвлэгчид иртэл нэг эсвэл хэд хэдэн серверээр дамжина."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Уучлаарай, ажилласангүй. Дахин оролдоно уу."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Дахин оролдох"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Одоо хэвлэгч ашиглах боломжгүй."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Урьдчилан үзүүлэх боломжгүй"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Урьдчилан харахыг бэлтгэж байна…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index 2b3b29f..ee09db2 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"रीस्टार्ट करा"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटरवर कोणतेही कनेक्शन नाही"</string>
<string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्ध"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> वापरायची?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"आपला दस्तऐवज प्रिंटरपर्यंत पोहचण्यापूर्वी एक किंवा अधिक सर्व्हरद्वारे जाऊ शकतो."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"क्षमस्व, त्याने कार्य केले नाही. पुन्हा प्रयत्न करा."</string>
<string name="print_error_retry" msgid="1426421728784259538">"पुन्हा प्रयत्न करा"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"हा प्रिंटर आत्ता उपलब्ध नाही."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकन प्रदर्शित करू शकत नाही"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकनाची तयारी करत आहे..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index 73104e1..4042c71 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Mulakan semula"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Tiada sambungan ke pencetak"</string>
<string name="reason_unknown" msgid="5507940196503246139">"tidak diketahui"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen anda mungkin melalui satu atau beberapa pelayan dalam perjalanan ke pencetak."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Maaf, itu tidak berjaya. Cuba lagi."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Cuba semula"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Pencetak ini tidak tersedia sekarang."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Tidak dapat memaparkan pratonton"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Menyediakan pratonton..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index 8cec068..f34ca67 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"အစက ပြန်စရန်"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"စာထုတ်စက်နဲ့ ဆက်သွယ်ထားမှု မရှိပါ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"အကြောင်းအရာ မသိရှိ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – မတွေ့ရှိပါ"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ကိုသုံးမလား။"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"သင်၏ စာရွက်စာတမ်းများသည် ပရင်တာထံသို့ သွားစဉ် ဆာဗာ တစ်ခု သို့မဟုတ် ပိုများပြီး ဖြတ်ကျော်နိုင်ရသည်။"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ဆော်ရီး၊ အဲဒါ အလုပ်မဖြစ်ခဲ့ပါ။ ထပ် စမ်းပါ။"</string>
<string name="print_error_retry" msgid="1426421728784259538">"ထပ်စမ်း"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ဒီပရင်တာမှာ ယခုအချိန်မှာ မရနိုင်ပါ။"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"အစမ်းကြည့်ခြင်းကို ပြသ၍မရပါ"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"အစမ်းကြည့်ရန် ပြင်ဆင်နေ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
index 0a6f6c3..6b74765 100644
--- a/packages/PrintSpooler/res/values-nb/strings.xml
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Start på nytt"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse med skriveren"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ukjent"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – utilgjengelig"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruke <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumentet ditt kan gå via flere tjenere før det når skriveren."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Beklager, det fungerte ikke. Prøv på nytt."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Prøv på nytt"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Denne skriveren er ikke tilgjengelig akkurat nå."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan ikke vise forhåndsvisningen"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Forbereder forhåndsvisningen …"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index 5af3a04..8e8bf15 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"पुनःस्टार्ट गर्नुहोस्"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिन्टरमा कुनै जडान छैन"</string>
<string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - अनुपलब्ध"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्ने हो?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"तपाईँको कागजात प्रिन्टरमा जाँदा यसको मार्गमा एक वा धेरै सर्भरहरू पार हुनसक्छन्।"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"माफ गर्नुहोस्, त्यसले काम गरेन। पुनः प्रयास गर्नुहोस्।"</string>
<string name="print_error_retry" msgid="1426421728784259538">"पुनःप्रयास गर्नुहोस्"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"यो प्रिन्टर अहिले उपलब्ध छैन।"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकनलाई प्रदर्शन गर्न सक्दैन"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तयारी..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 4afdb86..3c65d8a 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Opnieuw starten"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niet beschikbaar"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> gebruiken?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Je document kan via een of meer servers naar de printer worden verzonden."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Dat werkte niet. Probeer het opnieuw."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Opnieuw proberen"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Deze printer is momenteel niet beschikbaar."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan voorbeeld niet weergeven"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Voorbeeld voorbereiden…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
index 1886ef5..934123b 100644
--- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"ਰੀਸਟਾਰਟ ਕਰੋ"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ਪ੍ਰਿੰਟਰ ਲਈ ਕੋਈ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ਅਗਿਆਤ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ਅਣਉਪਲਬਧ"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਵਰਤਣੀ ਹੈ?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ਤੁਹਾਡਾ ਦਸਤਾਵੇਜ਼ ਪ੍ਰਿੰਟਰ ਵਿੱਚ ਜਾਣ ਲਈ ਇੱਕ ਜਾਂ ਦੋ ਸਰਵਰਾਂ ਵਿੱਚੋਂ ਲੰਘਦਾ ਹੈ।"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ਮਾਫ਼ ਕਰਨਾ, ਉਸਨੇ ਲਾਭਕਾਰੀ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="print_error_retry" msgid="1426421728784259538">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ਇਹ ਪ੍ਰਿੰਟਰ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"ਝਲਕ ਨਹੀਂ ਵਿਖਾਈ ਜਾ ਸਕਦੀ"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"ਪ੍ਰੀਵਿਊ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
index 45649bb..80b6070 100644
--- a/packages/PrintSpooler/res/values-pl/strings.xml
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Od nowa"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Brak połączenia z drukarką"</string>
<string name="reason_unknown" msgid="5507940196503246139">"brak informacji"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niedostępne"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Użyć usługi <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Zanim dokument dotrze do drukarki, może przejść przez jeden lub kilka serwerów."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"To nie zadziałało. Spróbuj jeszcze raz."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Ponów próbę"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Drukarka nie jest teraz dostępna."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nie można wyświetlić podglądu"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Przygotowuję podgląd…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 58eb24f..4bd1161 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Falhou. Tente novamente."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está disponível no momento."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível exibir a visualização"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparando visualização…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index 370bbb9..7660c5c 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Sem ligação à impressora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponível"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Pretende utilizar o <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"O seu documento pode passar por um ou mais servidores no respetivo caminho para a impressora."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Lamentamos, mas isso não funcionou. Tente novam."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está atualmente disponível."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível apresentar a pré-visualização"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"A preparar a pré-visualização..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 58eb24f..4bd1161 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
<string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Falhou. Tente novamente."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está disponível no momento."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível exibir a visualização"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Preparando visualização…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 1097d56..dd38c31 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Reporniți"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nu există conexiune la o imprimantă"</string>
<string name="reason_unknown" msgid="5507940196503246139">"necunoscut"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - indisponibil"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Folosiți <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Documentul poate trece prin unul sau mai multe servere pe calea spre imprimantă."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Ne pare rău, operațiunea nu a reușit. Încercați din nou."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Reîncercați"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Această imprimantă nu este disponibilă momentan."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Previzualizarea nu se poate afișa"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Se pregătește previzualizarea..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index 24b1e0d..6c074ed 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Повторить"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Нет связи с принтером"</string>
<string name="reason_unknown" msgid="5507940196503246139">"неизвестно"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступен"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Использовать <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ может пересылаться на принтер через несколько серверов."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Ошибка. Повторите попытку."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Повторить"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Принтер не готов."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Сбой предварительного просмотра"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Подготовка изображения…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index 707c151..8278aee 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"යළි අරඹන්න"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"මුද්රණ යන්ත්රය වෙත සම්බන්ධය නැත"</string>
<string name="reason_unknown" msgid="5507940196503246139">"නොදනී"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ලද නොහැක"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> භාවිත කරන්නද?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"ඔබගේ ලේඛනය මුද්රණ යන්ත්රයට යන අතරතුර සේවාදායක එකක් හෝ කිහිපයක් හරහා යා හැක."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"කණගාටුයි, එය වැඩ නොකරයි. නැවත උත්සහ කරන්න."</string>
<string name="print_error_retry" msgid="1426421728784259538">"නැවත උත්සාහ කරන්න"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"දැන් මෙම මුද්රණ යන්ත්රය නොපවතී."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"පෙරදසුන සංදර්ශනය කළ නොහැකිය"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"පෙරදසුන සූදානම් කරමින්…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index 1f13b54..610fe99 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Spustiť znova"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Žiadne pripojenie k tlačiarni"</string>
<string name="reason_unknown" msgid="5507940196503246139">"neznáme"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie je k dispozícii"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Použiť službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skôr ako sa váš dokument dostane do tlačiarne, môže prejsť jedným alebo viacerými servermi."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Je nám to ľúto, nefungovalo to. Skúste to znova."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Opakovať"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Táto tlačiareň nie je momentálne k dispozícii."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Ukážka sa nedá zobraziť"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Pripravuje sa ukážka..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
index 3f8a5e6..b5124b4 100644
--- a/packages/PrintSpooler/res/values-sl/strings.xml
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Začni znova"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ni povezave s tiskalnikom"</string>
<string name="reason_unknown" msgid="5507940196503246139">"neznano"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ni na voljo"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite uporabiti storitev <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument gre lahko na poti do tiskalnika skozi enega ali več strežnikov."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"To žal ni delovalo. Poskusite znova."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Poskusi znova"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ta tiskalnik trenutno ni na voljo."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Predogleda ni mogoče prikazati"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Priprava predogleda …"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
index 0b843d7..27bbbf9 100644
--- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml
+++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Rifillo"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Printeri nuk është i lidhur"</string>
<string name="reason_unknown" msgid="5507940196503246139">"e panjohur"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nuk mundësohet"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Përdor <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumenti mund të kalojë përmes një ose shumë serverëve deri te printeri."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Na vjen keq, nuk funksionoi! Provo përsëri."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Provo sërish"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ky printer nuk mund të përdoret tani."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Nuk mund të shfaqet paraafishimi"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Po përgatit shikimin paraprak…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index 8baa23c..ea6fcb7 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -81,7 +81,6 @@
<string name="restart" msgid="2472034227037808749">"Поново покрени"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
<string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступан"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ може да прође кроз један или више сервера на путу до штампача."</string>
<string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Жао нам је, ово није успело. Покушајте поново."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Покушајте поново"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овај штампач тренутно није доступан."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Није успео приказ прегледа"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Припрема прегледа..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
index 64b6b20..c909e19 100644
--- a/packages/PrintSpooler/res/values-sv/strings.xml
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Starta om"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen anslutning till skrivaren"</string>
<string name="reason_unknown" msgid="5507940196503246139">"okänt"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – inte tillgänglig"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Vill du använda <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"På vägen till skrivaren kan dokumentet passera en eller flera servrar."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Det fungerade tyvärr inte. Försök igen."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Försök igen"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Den här skrivaren är inte tillgänglig just nu."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Det gick inte att visa förhandsgranskningen"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Förbereder förhandsvisning ..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
index b3ffa71..bd14117 100644
--- a/packages/PrintSpooler/res/values-sw/strings.xml
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Anzisha upya"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Hakuna muunganisho kwa printa"</string>
<string name="reason_unknown" msgid="5507940196503246139">"haijulikani"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - haipatikani"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Ungependa kutumia <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Huenda hati yako ikapitia seva moja au zaidi kabla ya kufika kwenye printa."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Samahani, hiyo haikufanya kazi. Jaribu tena."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Jaribu tena"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Printa hii haipatikani kwa sasa."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Haiwezi kupakia onyesho la kuchungulia"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Inaandaa onyesho la kuchungulia..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index 7ae3cbc..782ebf2 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"மீண்டும் தொடங்கு"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"அச்சுப்பொறியுடன் இணைக்கப்படவில்லை"</string>
<string name="reason_unknown" msgid="5507940196503246139">"அறியப்படாதது"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – இல்லை"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ஐப் பயன்படுத்தவா?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"உங்கள் ஆவணம் பிரிண்டருக்குச் செல்லும் வழியில் ஒன்று அல்லது அதற்கு மேற்பட்ட சேவையகங்களைக் கடந்து செல்லக்கூடும்."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"செயல்படவில்லை. மீண்டும் முயலவும்."</string>
<string name="print_error_retry" msgid="1426421728784259538">"மீண்டும் முயலவும்"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"இப்போது பிரிண்டர் இல்லை."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"மாதிரிக்காட்சியைக் காட்ட முடியவில்லை"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"மாதிரிக்காட்சியைத் தயார்படுத்துகிறது…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index 9e8dea2..ca393c839 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"పునఃప్రారంభించు"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ప్రింటర్కు కనెక్షన్ లేదు"</string>
<string name="reason_unknown" msgid="5507940196503246139">"తెలియదు"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – అందుబాటులో లేదు"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ని ఉపయోగించాలా?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"మీ పత్రం ప్రింటర్కు వెళ్లే మార్గంలో ఒకటి లేదా అంతకంటే ఎక్కువ సర్వర్ల గుండా వెళ్లవచ్చు."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"క్షమించండి, అది పని చేయలేదు. మళ్లీ ప్రయత్నించండి."</string>
<string name="print_error_retry" msgid="1426421728784259538">"మళ్లీ ప్రయత్నించు"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ఈ ప్రింటర్ ప్రస్తుతం అందుబాటులో లేదు."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"పరిదృశ్యాన్ని ప్రదర్శించడం సాధ్యపడలేదు"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"పరిదృశ్యం సిద్ధమవుతోంది…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index c623dd7..92b960e 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"เริ่มต้นใหม่"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ไม่มีการเชื่อมต่อไปยังเครื่องพิมพ์"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ไม่ทราบ"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"ใช้ <xliff:g id="SERVICE">%1$s</xliff:g> ไหม"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"เอกสารของคุณอาจต้องผ่านมากกว่าหนึ่งเซิร์ฟเวอร์ระหว่างส่งไปยังเครื่องพิมพ์"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ขออภัย ไม่สามารถใช้งานได้ ลองอีกครั้ง"</string>
<string name="print_error_retry" msgid="1426421728784259538">"ลองอีกครั้ง"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"เครื่องพิมพ์นี้ไม่พร้อมใช้งานในขณะนี้"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"ไม่สามารถแสดงตัวอย่าง"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"กำลังเตรียมการแสดงตัวอย่าง…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index 0494cf6..5a73659 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"I-restart"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Hindi nakakonekta sa printer"</string>
<string name="reason_unknown" msgid="5507940196503246139">"hindi alam"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – hindi available"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Gusto mo bang gamitin ang <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Bago ma-print ang iyong dokumento, maaari itong dumaan sa isa o higit pang mga server."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Paumanhin, hindi iyon gumana. Subukang muli."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Subukang muli"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Hindi available ang printer na ito sa ngayon."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Hindi maipakita ang preview"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Inihahanda ang preview…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index 2818f36..f17bc9d 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Yeniden başlat"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Yazıcı bağlantısı yok"</string>
<string name="reason_unknown" msgid="5507940196503246139">"bilinmiyor"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – kullanılamıyor"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> kullanılsın mı?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokümanınız yazıcıya giderken bir veya daha fazla sunucudan geçebilir."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Maalesef bu işe yaramadı. Tekrar deneyin."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Yeniden dene"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Bu yazı şu anda kullanılamıyor."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Önizleme gösterilemiyor"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Önizleme hazırlanıyor…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
index 41051af..9629ad3 100644
--- a/packages/PrintSpooler/res/values-uk/strings.xml
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -82,7 +82,6 @@
<string name="restart" msgid="2472034227037808749">"Перезапустити"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Немає з’єднання з принтером"</string>
<string name="reason_unknown" msgid="5507940196503246139">"невідомо"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" не доступне"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Увімкнути службу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Коли ви надсилаєте документ на принтер, він може проходити через декілька серверів."</string>
<string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"На жаль, сталася помилка. Повторіть спробу."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Повторити"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Цей принтер зараз недоступний."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Не вдалося відкрити попередній перегляд"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Підготовка до попереднього перегляду…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index a94b16f..0d01ee2 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"دوبارہ شروع کریں"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"پرنٹر کے ساتھ کوئی کنکشن نہیں ہے"</string>
<string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – دستیاب نہیں ہے"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> استعمال کریں؟"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"آپ کی دستاویز پرنٹر تک جاتے ہوئے ممکن ہے ایک یا زیادہ سرورز سے گزرے۔"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"معذرت، اس نے کام نہیں کیا۔ دوبارہ کوشش کریں۔"</string>
<string name="print_error_retry" msgid="1426421728784259538">"دوبارہ کوشش کریں"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"یہ پرنٹر ابھی دستیاب نہیں ہے۔"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"پیش منظر ڈسپلے نہیں ہو سکتا"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"پیش منظر کو تیار کیا جا رہا ہے…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index a6af5bd..1f379d9 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Qayta boshlash"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Printer ulanmagan"</string>
<string name="reason_unknown" msgid="5507940196503246139">"noma’lum"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – mavjud emas"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xizmatidan foydalanilsinmi?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Hujjatingiz chop etilishidan oldin bir yoki bir necha serverlardan o‘tishi mumkin."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Kechirasiz, ishlamadi. Qayta urinib ko‘ring."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Qayta urinish"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ushbu printer hozirda mavjud emas."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Oldindan ko‘rsatib bo‘lmaydi"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Dastlabki ko\'rishga tayyorlanmoqda…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index df9e1a4..b931557 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Bắt đầu lại"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Không có kết nối nào với máy in"</string>
<string name="reason_unknown" msgid="5507940196503246139">"không xác định"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – không khả dụng"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Sử dụng <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Tài liệu của bạn có thể đi qua một hoặc nhiều máy chủ trên đường đến máy in."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Rất tiếc, tính năng đó không hoạt động. Hãy thử lại."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Thử lại"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Máy in này hiện không khả dụng."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Không thể hiển thị bản xem trước"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Đang chuẩn bị xem trước…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index fb30e44..ffc9f85 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"重新开始"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"未与打印机建立连接"</string>
<string name="reason_unknown" msgid="5507940196503246139">"未知"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - 无法使用"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用<xliff:g id="SERVICE">%1$s</xliff:g>吗?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文档可能会通过一个或多个服务器发送至打印机。"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"抱歉,操作失败。请重试。"</string>
<string name="print_error_retry" msgid="1426421728784259538">"重试"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"该打印机目前无法使用。"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"无法显示预览"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"即将显示预览…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index f7c8fc9..4411a23 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"重新開始"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與打印機連線"</string>
<string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用 <xliff:g id="SERVICE">%1$s</xliff:g> 嗎?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會通過一部或多部伺服器才傳送至打印機。"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"很抱歉,行不通。請再試一次。"</string>
<string name="print_error_retry" msgid="1426421728784259538">"重試"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"這部打印機目前無法使用。"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"無法顯示預覽"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"正在準備預覽…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index aa18f3c..98126a7 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"重新開始"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與印表機建立連線"</string>
<string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會透過一或多個伺服器輾轉傳送至印表機。"</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"很抱歉,無法執行這項操作。請再試一次。"</string>
<string name="print_error_retry" msgid="1426421728784259538">"重試"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"這台印表機目前無法使用。"</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"無法顯示預覽畫面"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"正在準備預覽…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
index 9cfcb33..f2b4990 100644
--- a/packages/PrintSpooler/res/values-zu/strings.xml
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -80,7 +80,6 @@
<string name="restart" msgid="2472034227037808749">"Qala kabusha"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Akukho ukuxhumana kuphrinta"</string>
<string name="reason_unknown" msgid="5507940196503246139">"akwaziwa"</string>
- <string name="printer_unavailable" msgid="2434170617003315690">"I-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ayitholakali"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Sebenzisa i-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="print_service_security_warning_summary" msgid="1427434625361692006">"Idokhumenti yakho ingase idlule iseva eyodwa noma amaningi lapho iya kuphrinta."</string>
<string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
<string name="print_error_default_message" msgid="8602678405502922346">"Uxolo, lokho akusebenzanga. Zama futhi."</string>
<string name="print_error_retry" msgid="1426421728784259538">"Zama futhi"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"Le phrinta ayitholakali khona manje."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Ayikwazi ukubonisa ukubuka kuqala"</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"Ilungiselela ukubuka kuqala…"</string>
</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index 3b5513a..7935440 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -267,9 +267,12 @@
// The contract is that if we already have a valid,
// result the we have to deliver it immediately.
- if (!mPrinters.isEmpty()) {
- deliverResult(new ArrayList<>(mPrinters));
- }
+ (new Handler(Looper.getMainLooper())).post(new Runnable() {
+ @Override public void run() {
+ deliverResult(new ArrayList<>(mPrinters));
+ }
+ });
+
// Always load the data to ensure discovery period is
// started and to make sure obsolete printers are updated.
onForceLoad();
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index bb34fcf..a24d664 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -2051,9 +2051,12 @@
mDestinationSpinnerAdapter.unregisterDataSetObserver(mPrintersObserver);
}
+ if (mSpoolerProvider != null) {
+ mSpoolerProvider.destroy();
+ }
+
if (mState != STATE_INITIALIZING) {
mProgressMessageController.cancel();
- mSpoolerProvider.destroy();
mPrintedDocument.finish();
mPrintedDocument.destroy();
mPrintPreviewController.destroy(new Runnable() {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 406c9b7..93415c0 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Tuis"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> gelede"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> oor"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Verstek"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groot"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Groter"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Grootste"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Gepasmaak (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index e4cd8b9..cf2a6ce 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"መነሻ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"ከ<xliff:g id="ID_1">%1$s</xliff:g> በፊት"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ቀርቷል"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ትንሽ"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ነባሪ"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ትልቅ"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ተለቅ ያለ"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"በጣም ተለቅ ያለ"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ብጁ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ad87a89..e21b02c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"الشاشة الرئيسية"</string>
<string name="charge_length_format" msgid="8978516217024434156">"قبل <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"يتبقى <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"صغير"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"افتراضي"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"كبير"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"أكبر"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"أكبر مستوى"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"مخصص (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index c141445..31d20a9 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Əsas səhifə"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> əvvəl"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qalıb"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kiçik"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Defolt"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Böyük"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Daha böyük"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ən böyük"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Fərdi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3e3cce0..4bd9b03 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Početni"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Pre <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mali"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Podrazumevano"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliki"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veći"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveći"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml
index 08aa3a0..ded4e41 100644
--- a/packages/SettingsLib/res/values-be-rBY/strings.xml
+++ b/packages/SettingsLib/res/values-be-rBY/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Галоўная"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> таму назад"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Засталося <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Маленькі"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандартны"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Вялікі"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Большы"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найвялікшы"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2dbeeac..e0641b1 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Начало"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Преди <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Оставащо време: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Малко"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"По подразбиране"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Голямо"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"По-голямо"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Най-голямо"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Персонализирано (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index eea4f06..5ca7d03 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"হোম"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> আগে"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> বাকী আছে"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ক্ষুদ্র"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ডিফল্ট"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"বড়"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"খুব বড়"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"বৃহত্তম"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"কাস্টম (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index cf9e4a4..dcce9a5 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Početna stranica"</string>
<string name="charge_length_format" msgid="8978516217024434156">"prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Još otprilike <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8d158ac..5106f5b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Inici"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Fa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Temps restant: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petit"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminat"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Gran"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Més gran"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Màxim"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalitzat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9e9abad..3d3dd6f 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Plocha"</string>
<string name="charge_length_format" msgid="8978516217024434156">"před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Zbývající čas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Výchozí"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Velké"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Větší"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Největší"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastní (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 659bd32..1f354b7 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Start"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> tilbage"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Lille"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stor"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Større"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Størst"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tilpasset (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 67d0198..404b72b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Startseite"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Vor <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Noch <xliff:g id="ID_1">%1$s</xliff:g> verbleibend"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groß"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Größer"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Am größten"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Benutzerdefiniert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 263703c..52988f6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Αρχική οθόνη"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Πριν από <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Απομένουν <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Μικρά"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Προεπιλογή"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Μεγάλα"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Πιο μεγάλα"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Μεγαλύτερα"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Προσαρμοσμένη (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Home"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Home"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Home"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b45753d..dd7ee4d 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Página principal"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Falta <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeño"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Más grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Máximo"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1e36088..0cc6cb6 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Inicio"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Tiempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeño"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Más grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Lo más grande posible"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index cb0e7f2..a275b1a 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Avaekraan"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> tagasi"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> on jäänud"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Väike"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Vaikimisi"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Suur"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Suurem"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Suurim"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kohandatud (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index f09949f..2556224 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Hasierako pantaila"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Duela <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> guztiz kargatu arte"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Txikia"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Lehenetsia"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Handia"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Oso handia"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Handiena"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pertsonalizatua (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index c621be3..a1393e8 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"صفحه اصلی"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی مانده است"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"کوچک"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"پیشفرض"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"بزرگ"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"بزرگتر"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"بزرگترین"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"سفارشی (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 8ec2f6e..3d8ac98 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Aloitusnäyttö"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> sitten"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> jäljellä"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pieni"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Oletus"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Suuri"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Suurempi"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Suurin"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Muokattu (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index e2de253..4eb3a427 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Accueil"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Durée restante :<xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petite"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Par défaut"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Plus grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"La plus grande"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisée (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index e3dd87a..efb10ec 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Accueil"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Il reste <xliff:g id="ID_1">%1$s</xliff:g>."</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petit"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Par défaut"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grand"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Plus grand"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Le plus grand"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisé (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index e75fee6..3d61e21 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Inicio"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Hai <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Tempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeno"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Máis grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"O máis grande"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 38b6089..628b4be 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"હોમ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> પહેલાં"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> બાકી"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"નાનું"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ડિફોલ્ટ"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"મોટું"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"વધુ મોટું"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"સૌથી મોટું"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"કસ્ટમ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index dce538b..047c7db 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"होम"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहले"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शेष"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"छोटा"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"डिफ़ॉल्ट"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"बड़ा"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"अधिक बड़ा"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सबसे बड़ा"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"कस्टम (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 7a2acd8..f5ad6d2 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Početni zaslon"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeno (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 426cff4..7279c9c 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Főoldal"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Ennyi ideje: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> van hátra"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kicsi"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Alapértelmezett"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Nagy"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Nagyobb"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Legnagyobb"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egyéni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 8c62221..afde9b5 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Գլխավոր էջ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> առաջ"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Մնացել է <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Փոքր"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Կանխադրված"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Մեծ"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Ավելի մեծ"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ամենամեծ"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Հատուկ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 662bb22..24fd0f1 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Layar Utama"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> lalu"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Tersisa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kecil"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Besar"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lebih besar"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Terbesar"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"(<xliff:g id="DENSITYDPI">%d</xliff:g>) khusus"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 30440da..e22dbe0 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Heim"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Fyrir <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> eftir"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Lítið"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Sjálfgefið"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stórt"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Stærra"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Stærst"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Sérsniðið (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 40802bc..84ff78a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Home page"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> fa"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> rimanenti"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Piccolo"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predefinito"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Più grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Massimo"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizzato (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index a651a3a..b1d4eea 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"דף הבית"</string>
<string name="charge_length_format" msgid="8978516217024434156">"לפני <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"נשארו <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"קטן"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ברירת מחדל"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"גדול"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"יותר גדול"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"הכי גדול"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"מותאם אישית (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index e17db51..2556d99 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -318,4 +318,10 @@
<string name="home" msgid="8263346537524314127">"ホーム"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"あと <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"デフォルト"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"特大"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"カスタム(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 11fa8a6..1c05631 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"მთავარი"</string>
<string name="charge_length_format" msgid="8978516217024434156">"გავიდა <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"დარჩენილია <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"პატარა"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ნაგულისხმევი"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"დიდი"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"უფრო დიდი"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"უდიდესი"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"მორგებული (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index aae7449..fdd3f95 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Негізгі бет"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> бұрын"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> қалды"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Кішкентай"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Әдепкі"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Үлкен"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Үлкенірек"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ең үлкен"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Арнаулы (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 4373c43..2cafa29 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"ដើម"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> មុន"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"នៅសល់ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"តូច"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"លំនាំដើម"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ធំ"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ធំជាង"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ធំបំផុត"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ផ្ទាល់ខ្លួន (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index f0d63fb..7c90cca 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"ಮುಖಪುಟ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ಹಿಂದೆ"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ಸಣ್ಣದು"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ಡಿಫಾಲ್ಟ್"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ದೊಡ್ಡದು"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ಸ್ವಲ್ಪ ದೊಡ್ಡ"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ದೊಡ್ಡ"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ಕಸ್ಟಮ್ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index a8b6c36..035793e 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"홈"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> 전"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> 남음"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"작게"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"기본"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"크게"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"더 크게"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"가장 크게"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"맞춤(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 6491d3c..9956271 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Башкы бет"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> мурун"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> калды"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Кичине"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Демейки"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Чоң"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Чоңураак"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Эң чоң"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ыңгайлаштырылган (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index cf90c4b..f158d44 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"ໜ້າຫຼັກ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ກ່ອນນີ້"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"ຍັງເຫຼືອ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ນ້ອຍ"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ຄ່າເລີ່ມຕົ້ນ"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ໃຫຍ່"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ໃຫຍ່ກວ່າ"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ໃຫຍ່ທີ່ສຸດ"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ປັບແຕ່ງເອງ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index fd245f3..d5cea8e 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Pagrindinis ekranas"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Prieš <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Liko <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mažas"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Numatytasis"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Didelis"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Didesnis"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Didžiausias"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tinkintas (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index b470fb54..ea6f4f9 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Sākums"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Pirms šāda laika: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Atlikušais laiks: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mazs"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Noklusējuma"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Liels"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lielāks"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Vislielākais"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pielāgots (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 7592cd3..e954cdf 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Почетна страница"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Пред <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Преостанаа <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мал"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандардно"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Голем"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Поголем"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Најголем"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Приспособен (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 13a7013..d6a28cd 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"ഹോം"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> മുമ്പ്"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ചെറുത്"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ഡിഫോൾട്ട്"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"വലുത്"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"കൂടുതൽ വലുത്"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ഏറ്റവും വലുത്"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ഇഷ്ടാനുസൃതം ( <xliff:g id="DENSITYDPI">%d</xliff:g> )"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index a77e32e..d989ef8 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Нүүр"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> өмнө"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> үлдсэн"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Жижиг"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Өгөгдмөл"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Том"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Илүү том"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Хамгийн том"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Тогтмол утга (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 4f12e46..eee940b 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"मुख्यपृष्ठ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पूर्वी"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शिल्लक"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"लहान"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"डीफॉल्ट"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"मोठा"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"आणखी मोठा"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सर्वात मोठा"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"सानुकूल करा (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 6ba7d20..ea79a46 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Skrin Utama"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> yang lalu"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> lagi"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kecil"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Lalai"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Besar"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lebih besar"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Terbesar"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tersuai (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 5c1a5ee..74e0f29 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"ပင်မ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"ပြီးခဲ့သည့် <xliff:g id="ID_1">%1$s</xliff:g> က"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ကျန်ပါသည်"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"သေး"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"မူရင်း"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ကြီး"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ပိုကြီး"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"အကြီးဆုံး"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"စိတ်ကြိုက် (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index de6faf4..1a0b468 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Startside"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> gjenstår"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Liten"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stor"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Større"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Størst"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egendefinert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 47ec137..3f39931 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"गृह"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहिले"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> बाँकी"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"सानो"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"पूर्वनिर्धारित"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ठूलो"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"अझ ठूलो"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सबैभन्दा ठूलो"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"अनुकूलन (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 9f72db5..301e327 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Startpagina"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> geleden"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> resterend"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standaard"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groot"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Groter"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Grootst"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index 8625b90..883fda0 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ਪਹਿਲਾਂ"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ਬਾਕੀ"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ਛੋਟਾ"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ਵੱਡਾ"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ਥੋੜ੍ਹਾ ਵੱਡਾ"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ਸਭ ਤੋਂ ਵੱਡਾ"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b4c030d..8aad98b1 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Ekran główny"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> temu"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Pozostało <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Małe"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Domyślne"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Duże"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Większe"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Największe"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Niestandardowe (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e76535a..c05458b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Início"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequena"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Padrão"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Muito grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Maior"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 7e4744c..402bc86 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Página inicial"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Há <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Resta(m) <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeno"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predefinição"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Maior"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"O maior"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e76535a..c05458b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Início"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequena"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Padrão"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Muito grande"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Maior"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 5b712d0..d5e0769 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Ecranul principal"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Acum <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Timp rămas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mic"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Prestabilit"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Mare"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Mai mare"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Cel mai mare"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b233c4c..7ad9f16 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Главная"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> назад"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Осталось <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мелкий"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"По умолчанию"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Крупный"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Очень крупный"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Максимальный"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Другой (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index c8af144..b3ead79 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"මුල් පිටුව"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>කට පෙර"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g>ක් ඉතිරිය"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"කුඩා"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"පෙරනිමි"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"විශාල"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"වඩා විශාල"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"විශාලතම"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"අභිරුචි (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 2c7a3b7..e5c9805 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Domov"</string>
<string name="charge_length_format" msgid="8978516217024434156">"pred <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Zostáva <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predvolená"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veľké"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Väčšie"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najväčšie"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastné (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 62797c3..8257e3c 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Začetni zaslon"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Pred toliko časa: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Še <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Majhno"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Privzeto"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Večje"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Največje"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Po meri (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index 0a069de..4a67348 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Kreu"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> më parë"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> të mbetura"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"I vogël"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"I parazgjedhur"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"I madh"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Më i madh"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Më i madhi"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"I personalizuar (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 61a87b5..eaf7ac5 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Почетни"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Пре <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Још <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мали"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Подразумевано"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Велики"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Већи"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Највећи"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 1de7317..b019672 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Startsida"</string>
<string name="charge_length_format" msgid="8978516217024434156">"för <xliff:g id="ID_1">%1$s</xliff:g> sedan"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kvar"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Små"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standardinställning"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stora"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Större"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Störst"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Anpassad (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index c02c256..3daa90f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Mwanzo"</string>
<string name="charge_length_format" msgid="8978516217024434156">"Zimepita <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Zimesalia <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Ndogo"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Chaguo-msingi"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Kubwa"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Kubwa kiasi"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Kubwa zaidi"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kiwango maalum (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index d28fe75..574d105 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"முகப்பு"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> முன்"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> உள்ளது"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"சிறியது"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"இயல்பு"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"பெரியது"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"கொஞ்சம் பெரியது"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"மிகப் பெரியது"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"தனிப்பயன் (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 9b6694c..2389112 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"హోమ్"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> క్రితం"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> మిగిలి ఉంది"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"చిన్నగా"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"డిఫాల్ట్"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"పెద్దగా"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"చాలా పెద్దగా"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"అతి పెద్దగా"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 5880b98..5d7b1a3 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"หน้าแรก"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>ที่ผ่านมา"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"เหลือ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"เล็ก"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ค่าเริ่มต้น"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ใหญ่"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ใหญ่ขึ้น"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ใหญ่ที่สุด"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"กำหนดเอง (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 3764d22..ef3dde7 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Home"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> na ang nakalipas"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> na lang"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Maliit"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Malaki"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Mas malaki"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Pinakamalaki"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 0a2c654..4b7490d 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Ana Ekran"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> önce"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kaldı"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Küçük"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Varsayılan"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Büyük"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Daha büyük"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"En büyük"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Özel (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5b88647..5e044c3 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Головний екран"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> тому"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Залишилося <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Малі елементи"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"За умовчанням"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Великі елементи"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Більші елементи"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найбільші елементи"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Спеціальний масштаб (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index e066736..6d3c6c4 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"ہوم"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی ہیں"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"چھوٹا"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ڈیفالٹ"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"بڑا"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"قدرے بڑا"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"سب سے بڑا"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"حسب ضرورت (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 23e8b0f..2311a66 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -317,4 +317,10 @@
<string name="home" msgid="8263346537524314127">"Bosh ekran"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> oldin"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qoldi"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kichkina"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Birlamchi"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Katta"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Kattaroq"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Eng katta"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Moslashtirilgan (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 27dd482..dd1d482 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Màn hình chính"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> trước"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"Còn <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Nhỏ"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Mặc định"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Lớn"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lớn hơn"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Lớn nhất"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tùy chỉnh (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 73cd252..4117ae1 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"主屏幕"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"还剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"默认"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"较大"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自定义 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 944082f..1fb4c5e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"主畫面"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"尚餘 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"預設"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"較大"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index dc029d9..9c85f0e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"主畫面"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"還剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"預設"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"較大"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9ba957a..6017d68 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -316,4 +316,10 @@
<string name="home" msgid="8263346537524314127">"Ekhaya"</string>
<string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> edlule"</string>
<string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> osele"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Okuncane"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Okuzenzakalelayo"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Okukhulu"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Okukhulu kakhulu"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Okukhulu kakhulu"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ngokwezifiso (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index ce69c5a..c3a5089 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -41,6 +41,7 @@
import android.widget.ListView;
import android.widget.Toolbar;
import com.android.settingslib.R;
+import com.android.settingslib.applications.InterestingConfigChanges;
import java.util.ArrayList;
import java.util.HashMap;
@@ -55,6 +56,7 @@
private static List<DashboardCategory> sDashboardCategories;
private static HashMap<Pair<String, String>, Tile> sTileCache;
+ private static InterestingConfigChanges sConfigTracker;
private final PackageReceiver mPackageReceiver = new PackageReceiver();
private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
@@ -153,8 +155,10 @@
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
updateDrawer();
} else {
- mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
- mDrawerLayout = null;
+ if (mDrawerLayout != null) {
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+ mDrawerLayout = null;
+ }
}
}
@@ -208,6 +212,7 @@
public List<DashboardCategory> getDashboardCategories() {
if (sDashboardCategories == null) {
sTileCache = new HashMap<>();
+ sConfigTracker = new InterestingConfigChanges();
sDashboardCategories = TileUtils.getCategories(this, sTileCache);
}
return sDashboardCategories;
@@ -267,6 +272,9 @@
private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
@Override
protected List<DashboardCategory> doInBackground(Void... params) {
+ if (sConfigTracker.applyNewConfig(getResources())) {
+ sTileCache.clear();
+ }
return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
}
diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
index 814aa8c..49759c5 100644
--- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
+++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
@@ -56,7 +56,7 @@
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
final RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, DOC_ID_ROOT);
- row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED);
+ row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY);
row.add(Root.COLUMN_ICON, android.R.mipmap.sym_def_app_icon);
row.add(Root.COLUMN_TITLE, getContext().getString(R.string.bugreport_storage_title));
row.add(Root.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
diff --git a/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml b/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml
new file mode 100644
index 0000000..b5bb4dc
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 3.25,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_a_b_dot_animation.xml b/packages/SystemUI/res/anim/major_a_b_dot_animation.xml
new file mode 100644
index 0000000..6443167
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_a_b_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueTo="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml b/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml
new file mode 100644
index 0000000..2e0a4fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 8.0,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_a_dot_animation.xml b/packages/SystemUI/res/anim/major_b_a_dot_animation.xml
new file mode 100644
index 0000000..731c87c
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_a_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueTo="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml b/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml
new file mode 100644
index 0000000..e8c2687
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 8.0,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_c_dot_animation.xml b/packages/SystemUI/res/anim/major_b_c_dot_animation.xml
new file mode 100644
index 0000000..731c87c
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_c_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueTo="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml b/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml
new file mode 100644
index 0000000..d0174bc
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 12.75,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_c_b_dot_animation.xml b/packages/SystemUI/res/anim/major_c_b_dot_animation.xml
new file mode 100644
index 0000000..6443167
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_c_b_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueTo="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml
new file mode 100644
index 0000000..b5bb4dc
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 3.25,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml
new file mode 100644
index 0000000..2e0a4fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 8.0,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml
new file mode 100644
index 0000000..e8c2687
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 8.0,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml
new file mode 100644
index 0000000..d0174bc
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 12.75,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
index 426238c..7356772 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver.xml
@@ -20,9 +20,11 @@
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="
- M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z
- m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z
- m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z
- m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/>
+ android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
index 0713548..fd9701e 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
@@ -17,12 +17,12 @@
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="#4DFFFFFF">
<path
- android:fillColor="#4DFFFFFF"
- android:pathData="
- M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z
- m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z
- m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z
- m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/>
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/major_a_b.xml b/packages/SystemUI/res/drawable/major_a_b.xml
new file mode 100644
index 0000000..9900048
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_a_b.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="major_a_b"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_01"
+ android:translateX="3.25"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_a_b_animation.xml b/packages/SystemUI/res/drawable/major_a_b_animation.xml
new file mode 100644
index 0000000..74d7544
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_a_b_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/major_a_b" >
+ <target
+ android:name="dot_01"
+ android:animation="@anim/major_a_b_dot_01_animation" />
+ <target
+ android:name="dot"
+ android:animation="@anim/major_a_b_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_b_a.xml b/packages/SystemUI/res/drawable/major_b_a.xml
new file mode 100644
index 0000000..3115887
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_a.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="major_b_a"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_01"
+ android:translateX="8"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_b_a_animation.xml b/packages/SystemUI/res/drawable/major_b_a_animation.xml
new file mode 100644
index 0000000..cf446e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_a_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/major_b_a" >
+ <target
+ android:name="dot_01"
+ android:animation="@anim/major_b_a_dot_01_animation" />
+ <target
+ android:name="dot"
+ android:animation="@anim/major_b_a_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_b_c.xml b/packages/SystemUI/res/drawable/major_b_c.xml
new file mode 100644
index 0000000..899109e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_c.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="major_b_c"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_01"
+ android:translateX="8"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_b_c_animation.xml b/packages/SystemUI/res/drawable/major_b_c_animation.xml
new file mode 100644
index 0000000..38e12f4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_c_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/major_b_c" >
+ <target
+ android:name="dot_01"
+ android:animation="@anim/major_b_c_dot_01_animation" />
+ <target
+ android:name="dot"
+ android:animation="@anim/major_b_c_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_c_b.xml b/packages/SystemUI/res/drawable/major_c_b.xml
new file mode 100644
index 0000000..cc6c615
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_c_b.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="major_c_b"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_01"
+ android:translateX="12.75"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_c_b_animation.xml b/packages/SystemUI/res/drawable/major_c_b_animation.xml
new file mode 100644
index 0000000..7f7850d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_c_b_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/major_c_b" >
+ <target
+ android:name="dot_01"
+ android:animation="@anim/major_c_b_dot_01_animation" />
+ <target
+ android:name="dot"
+ android:animation="@anim/major_c_b_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_a_b.xml b/packages/SystemUI/res/drawable/minor_a_b.xml
new file mode 100644
index 0000000..c5f5c98
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_a_b.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="minor_a_b"
+ android:alpha="0.3"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_02"
+ android:translateX="3.25"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_a_b_animation.xml b/packages/SystemUI/res/drawable/minor_a_b_animation.xml
new file mode 100644
index 0000000..50e20e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_a_b_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/minor_a_b" >
+ <target
+ android:name="dot_02"
+ android:animation="@anim/minor_a_b_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_a.xml b/packages/SystemUI/res/drawable/minor_b_a.xml
new file mode 100644
index 0000000..3bb08c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_a.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="minor_b_a"
+ android:alpha="0.3"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_02"
+ android:translateX="8"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_a_animation.xml b/packages/SystemUI/res/drawable/minor_b_a_animation.xml
new file mode 100644
index 0000000..460a2f7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_a_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/minor_b_a" >
+ <target
+ android:name="dot_02"
+ android:animation="@anim/minor_b_a_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_c.xml b/packages/SystemUI/res/drawable/minor_b_c.xml
new file mode 100644
index 0000000..95c6463
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_c.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="minor_b_c"
+ android:alpha="0.3"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_02"
+ android:translateX="8"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_c_animation.xml b/packages/SystemUI/res/drawable/minor_b_c_animation.xml
new file mode 100644
index 0000000..53b8bd6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_c_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/minor_b_c" >
+ <target
+ android:name="dot_02"
+ android:animation="@anim/minor_b_c_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_c_b.xml b/packages/SystemUI/res/drawable/minor_c_b.xml
new file mode 100644
index 0000000..523afaa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_c_b.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="minor_c_b"
+ android:alpha="0.3"
+ android:width="16dp"
+ android:viewportWidth="16"
+ android:height="8dp"
+ android:viewportHeight="8" >
+ <group
+ android:name="dot_02"
+ android:translateX="12.75"
+ android:translateY="4" >
+ <group
+ android:name="dot_group" >
+ <path
+ android:name="dot"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_c_b_animation.xml b/packages/SystemUI/res/drawable/minor_c_b_animation.xml
new file mode 100644
index 0000000..bf5e81e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_c_b_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/minor_c_b" >
+ <target
+ android:name="dot_02"
+ android:animation="@anim/minor_c_b_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
index a45f9a2..c36678d 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
@@ -23,10 +23,12 @@
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="
- M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z
- m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z
- m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z
- m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/>
+ android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
</vector>
</inset>
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
index 6cb8470..381fb16 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
@@ -16,7 +16,7 @@
~ limitations under the License
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="14sp"
android:paddingStart="24dp"
diff --git a/packages/SystemUI/res/layout/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
index 75f8fa4..6438564 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel_content.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
@@ -31,7 +31,8 @@
android:layout_height="0dp"
android:layout_weight="1"
android:scrollIndicators="top"
- android:scrollbars="vertical" />
+ android:scrollbars="vertical"
+ android:importantForAccessibility="no" />
<View
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index d897956..5e6c5f7 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Liggingversoeke aktief"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Kennisgewingsinstellings"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-instellings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is in veiligmodus gedeaktiveer."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Geskiedenis"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vee uit"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vee alles uit"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Hierdie program steun nie veelvuldige vensters nie"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Program steun nie veelvuldige vensters nie"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Verdeel horisontaal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Wys boaan die kennisgewingslys, verskyn vlugtig op die skerm en laat klank toe"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Meer instellings"</string>
<string name="notification_done" msgid="5279426047273930175">"Klaar"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-kennisgewingkontroles"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Kleur en voorkoms"</string>
<string name="night_mode" msgid="3540405868248625488">"Nagmodus"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibreer skerm"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Verminder werkverrigting en agtergronddata"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knoppie <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Op"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Af"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Links"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Regs"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Middel"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Spasie"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Syferpaneel <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Stelsel"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Tuis"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Onlangs"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Skuif op"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Skuif links"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Skuif regs"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
index 391bf7d..0ed4860 100644
--- a/packages/SystemUI/res/values-af/strings_tv.xml
+++ b/packages/SystemUI/res/values-af/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Hou "<b>"TUIS"</b>" om PIP te beheer"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Druk en hou die TUIS-knoppie om PIP te beheer"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Het dit"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Maak toe"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4286af0..3537b97 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"የአካባቢ ጥያቄዎች ነቅተዋል"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"የማሳወቂያ ቅንብሮች"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"የ<xliff:g id="APP_NAME">%s</xliff:g> ቅንብሮች"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> በጥንቃቄ ሁነታ ውስጥ ታግዷል።"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ታሪክ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ጥረግ"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ሁሉንም አጽዳ"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ይህ መተግበሪያ ብዝሃ-መስኮትን አይደግፍም"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"መተግበሪያው ብዝሃ-መስኮትን አይደግፍም"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"አግድም ክፈል"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"በማሳወቂያዎች ዝርዝር አናት ላይ አሳይ፣ ወደ ማያ ገጹ አሳይና ድምፅ ፍቀድ"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ተጨማሪ ቅንብሮች"</string>
<string name="notification_done" msgid="5279426047273930175">"ተከናውኗል"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ማሳወቂያ ቁጥጥሮች"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ቀለም እና መልክ"</string>
<string name="night_mode" msgid="3540405868248625488">"የሌሊት ሁነታ"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ማሳያን ይለኩ"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"አፈጻጸምን እና የጀርባ ውሂብን ይቀንሳል"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"አዝራር <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"መነሻ"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ተመለስ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ላይ"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ወደታች"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ግራ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ቀኝ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"መሃል"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"ትር"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"ክፍተት"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"አስገባ"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"የኋሊት መደምሰሻ"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"አጫውት/ለአፍታ አቁም"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"አቁም"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ቀጣይ"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ቀዳሚ"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ወደኋላ አጠንጥን"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"በፍጥነት አሳልፍ"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"ገጽ ወደ ላይ"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"ገጽ ወደ ታች"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ሰርዝ"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"መነሻ"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"መጨረሻ"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"አስገባ"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"የቁጥር ሰሌዳ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ሥርዓት"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"መነሻ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"የቅርብ ጊዜዎቹ"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ወደ ላይ ሂድ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ወደ ግራ ሂድ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ወደ ቀኝ ሂድ"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index 19e27ca..9df1916 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIPን ለመቆጣጠር "<b>"መነሻ"</b>"ን ይያዙ"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIPን ለመቆጣጠር የመነሻ አዝራሩን ተጭነው ይያዙ"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"ገባኝ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"አሰናብት"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5d859ac..1b05192 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -240,8 +240,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"و<xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"إعدادات الإشعارات"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"إعدادات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"سيتم تدوير الشاشة تلقائيًا."</string>
@@ -314,8 +313,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"تم تعطيل <xliff:g id="APP">%s</xliff:g> في الوضع الآمن."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"السجلّ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"محو"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"مسح الكل"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"لا يتيح هذا التطبيق النوافذ المتعددة."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"لا يتيح التطبيق النوافذ المتعددة."</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسيم أفقي"</string>
@@ -484,8 +482,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"عرض هذا الإشعار بأعلى قائمة الإشعارات وعرضه بسرعة على الشاشة مع السماح بإصدار تنبيه صوتي"</string>
<string name="notification_more_settings" msgid="816306283396553571">"المزيد من الإعدادات"</string>
<string name="notification_done" msgid="5279426047273930175">"تم"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"عناصر التحكم في إشعارات <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"اللون والمظهر"</string>
<string name="night_mode" msgid="3540405868248625488">"الوضع الليلي"</string>
<string name="calibrate_display" msgid="5974642573432039217">"معايرة الشاشة"</string>
@@ -505,6 +502,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"لخفض مستوى الأداء وبيانات الخلفية"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"الزر <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"أعلى"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"أسفل"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"يسار"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"يمين"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"وسط"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"مسافة"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"تشغيل / إيقاف مؤقت"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"إيقاف"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"التالي"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"السابق"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"إرجاع"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"تقديم سريع"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"الرئيسية"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"لوحة الأرقام <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"النظام"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string>
@@ -563,4 +586,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"نقل لأعلى"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"نقل لليسار"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"نقل لليمين"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"يمكن ألا يعمل التطبيق مع وضع النوافذ المتعددة."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
index db91b69..e6fbffc 100644
--- a/packages/SystemUI/res/values-ar/strings_tv.xml
+++ b/packages/SystemUI/res/values-ar/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"اضغط "<b>"الرئيسية"</b>" للتحكم في PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"اضغط مع الاستمرار على زر الشاشة الرئيسية للتحكم في PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"حسنًا"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"رفض"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index ad106f4..bd7572f 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Yer GPS tərəfindən müəyyən edildi"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Məkan sorğuları arxivi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Bütün bildirişləri sil."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildiriş ayarları"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik döndəriləcək."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"axtarış"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlana bilmir."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> güvənli rejimdə deaktiv edildi."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Tarixçə"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Təmizləyin"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hamısını silin"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu tətbiq çoxsaylı pəncərəni dəstəkləmir"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Bu tətbiq çoxsaylı pəncərəni dəstəkləyir"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Üfüqi Böl"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Bildirişlər siyahısında yuxarıda göstərin, ekrana nəzər salın və səsə icazə verin"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Daha çox ayar"</string>
<string name="notification_done" msgid="5279426047273930175">"Hazırdır"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildiriş nəzarəti"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Rəng və görünüş"</string>
<string name="night_mode" msgid="3540405868248625488">"Gecə rejimi"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Ekranı kalibrləyin"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı azaldır və arxa fon datasını məhdudlaşdırır"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Düymə <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Əsas səhifə"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Geri"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Yuxarı"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Aşağı"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sol"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Sağ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Mərkəz"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Boşluq"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Daxil olun"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Gerisil"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Oxut/Durdur"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Dayandırın"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Növbəti"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Öncəki"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Geri ötürmə"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"İrəli Ötürmə"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Yuxarı Səhifə"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Aşağı Səhifə"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Silin"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Əsas səhifə"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Son"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Daxil edin"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Nömrələr"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Rəqəmli düymələr <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Yuxarıya keçin"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sola köçürün"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sağa köçürün"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Tətbiq çoxsaylı pəncərə ilə işləməyə bilər."</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
index a7a6c5d..63fc9fd 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP idarı etmək üçün "<b>"Əsas səhifəni"</b>" tutub saxlayın"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PİP nəzarət etmək üçün ƏSAS EKRAN düyməni basıb saxlayın"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Rədd edin"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index edec332..4935d99 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -237,8 +237,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju je podesio GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Ima aktivnih zahteva za lokaciju"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Obriši sva obaveštenja."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"i još <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Podešavanja obaveštenja"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Podešavanja za <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran će se automatski rotirati."</string>
@@ -311,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g> nije uspelo."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je onemogućena u bezbednom režimu."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ova aplikacija ne podržava režim sa više prozora"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava režim sa više prozora"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
@@ -481,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Prikazuju se u vrhu liste obaveštenja, nakratko se prikazuju na ekranu i emituju zvuk"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Još podešavanja"</string>
<string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole obaveštenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
<string name="night_mode" msgid="3540405868248625488">"Noćni režim"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibrišite ekran"</string>
@@ -502,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje performanse i pozadinske podatke"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Taster Početna"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Taster Nazad"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Taster sa strelicom nagore"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Taster sa strelicom nadole"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Taster sa strelicom nalevo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Taster sa strelicom nadesno"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Taster sa centralnom strelicom"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Taster za razmak"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Taster za brisanje unazad"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Taster za reprodukciju/pauziranje"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Taster za zaustavljanje"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Taster Sledeća"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Taster Prethodna"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Taster za premotavanje unazad"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Taster za premotavanje unapred"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Taster za stranicu nagore"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Taster za stranicu nadole"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Taster za brisanje"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Taster Početna"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Taster za kraj"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Taster za umetanje"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Taster <xliff:g id="NAME">%1$s</xliff:g> na numeričkoj tastaturi"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomeri nagore"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomeri ulevo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomeri udesno"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index a285627..d026d2c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"POČETNI EKRAN"</b>" kont. PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Pritisnite i zadržite dugme POČETNI EKRAN da biste kontrolisali PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Važi"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml
index e5771d7..9a3fc33 100644
--- a/packages/SystemUI/res/values-be-rBY/strings.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings.xml
@@ -240,8 +240,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Ёсць актыўныя запыты пра месцазнаходжанне"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Налады апавяшчэнняў"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Налады <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран паварочваецца аўтаматычна."</string>
@@ -314,8 +313,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Не атрымалася запусціць <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> адключана ў бяспечным рэжыме."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Гісторыя"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ачысціць"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ачысціць усё"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Гэта праграма не падтрымлівае функцыю некалькіх вокнаў"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Праграма не падтрымлівае функцыю некалькіх вокнаў"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Падзяліць гарызантальна"</string>
@@ -484,8 +482,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Паказваць уверсе спіса апавяшчэнняў, хутка паказаць на экране і дазволіць прайграванне гуку"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Дадатковыя налады"</string>
<string name="notification_done" msgid="5279426047273930175">"Гатова"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Элементы кантролю апавяшчэнняў <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Колер і выгляд"</string>
<string name="night_mode" msgid="3540405868248625488">"Начны рэжым"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Каліброўка дысплэя"</string>
@@ -505,6 +502,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Эканомія зараду акумулятара недаступная падчас зарадкі"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Эканомія зараду"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Памяншае прадукцыйнасць і фонавую перадачу даных"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Уверх"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Уніз"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Улева"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Управа"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Цэнтр"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Прабел"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Прайграванне/Паўза"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Спыніць"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Наступны"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Папярэдні"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перамотка назад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перамотка наперад"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Лічбавая клавіятура: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Сістэмныя"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Галоўная"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Апошнія"</string>
@@ -564,4 +587,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Перамясціць уверх"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Перамясціць улева"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Перамясціць управа"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-be-rBY/strings_tv.xml b/packages/SystemUI/res/values-be-rBY/strings_tv.xml
index 1c93d24..6138155 100644
--- a/packages/SystemUI/res/values-be-rBY/strings_tv.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings_tv.xml
@@ -29,6 +29,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Утрым. "<b>"HOME"</b>" для кір. PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Націсніце і ўтрымлівайце кнопку HOME для кіравання PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Зразумела"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Адхіліць"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6c65f9f..17e9f690 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни заявки за местоположение"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки за известия"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложението <xliff:g id="APP">%s</xliff:g> е деактивирано в безопасния режим."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"История"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Изчистване"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Изчистване на всичко"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Това приложение не поддържа няколко прозореца"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Приложението не поддържа няколко прозореца"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хоризонтално разделяне"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Показване най-горе в списъка с известия, както и на екрана и разрешаване на звуков сигнал"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Още настройки"</string>
<string name="notification_done" msgid="5279426047273930175">"Готово"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроли за известията от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Цвят и облик"</string>
<string name="night_mode" msgid="3540405868248625488">"Нощен режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Калибриране на дисплея"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Намалява ефективността и данните на заден план"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Бутон „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Начало"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Нагоре"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Надолу"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Наляво"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Надясно"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Център"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Интервал"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Пускане/пауза"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Спиране"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Напред"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Превъртане назад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Превъртане напред"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Страница нагоре"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Страница надолу"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Изтриване"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифрова клавиатура – <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Системни"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Преместване нагоре"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Преместване наляво"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Преместване надясно"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложението може да не работи в режим за няколко прозореца"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index 9926ef8..38e251b 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Контр. на PIP: Задр. "<b>"HOME"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"За контролиране на PIP натиснете и задръжте бутона „HOME“"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрах"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Отхвърляне"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 446d4af..068e1c1 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS এর দ্বারা সেট করা অবস্থান"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"অবস্থান অনুরোধ সক্রিয় রয়েছে"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"সমস্ত বিজ্ঞপ্তি সাফ করুন৷"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>টি"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"বিজ্ঞপ্তির সেটিংস"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> সেটিংস"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"স্ক্রীন স্বয়ংক্রিয়ভাবে ঘুরে যাবে৷"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> অক্ষম করা হয়েছে৷"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ইতিহাস"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"সাফ করুন"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"সবকিছু সাফ করুন"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"এই অ্যাপ্লিকেশানটি মাল্টি-উইন্ডো সমর্থন করে না"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"অ্যাপ্লিকেশানগুলি মাল্টি-উইন্ডো সমর্থন করে না"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"অনুভূমিক স্প্লিট"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"বিজ্ঞপ্তি তালিকার শীর্ষে দেখানো হয় এবং স্ক্রীনের উপরে প্রদর্শিত এবং শব্দ করার মঞ্জুরি দেয়"</string>
<string name="notification_more_settings" msgid="816306283396553571">"আরো সেটিংস"</string>
<string name="notification_done" msgid="5279426047273930175">"সম্পন্ন"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"রঙ এবং চেহারা"</string>
<string name="night_mode" msgid="3540405868248625488">"রাতের মোড"</string>
<string name="calibrate_display" msgid="5974642573432039217">"প্রদর্শন ক্যালিব্রেট করুন"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"কার্য-সম্পাদনা ও পশ্চাদপট ডেটাকে কমিয়ে দেয়"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> বোতাম"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"হোম"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ফিরুন"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"উপরে"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"নীচে"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"বাম"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ডান"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"কেন্দ্র"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"ট্যাব"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"স্পেস"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"এন্টার"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"ব্যাকস্পেস"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"প্লে/বিরতি"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"থামান"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"পরবর্তী"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"পূর্ববর্তী"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"পেছনের দিকে যান"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"দ্রুত ফরওয়ার্ড"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"পেজ আপ"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"পেজ ডাউন"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"মুছুন"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"হোম"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"শেষ"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"ঢোকান"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"সংখ্যা লক"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"সংখ্যাপ্যাড <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"সিস্টেম"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string>
@@ -544,8 +567,8 @@
<string name="qs_edit" msgid="2232596095725105230">"সম্পাদনা করুন"</string>
<string name="tuner_time" msgid="6572217313285536011">"সময়"</string>
<string-array name="clock_options">
- <item msgid="5965318737560463480">"ঘন্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
- <item msgid="1427801730816895300">"ঘন্টা এবং মিনিট দেখান (ডিফল্ট)"</item>
+ <item msgid="5965318737560463480">"ঘণ্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
+ <item msgid="1427801730816895300">"ঘণ্টা এবং মিনিট দেখান (ডিফল্ট)"</item>
<item msgid="3830170141562534721">"এই আইকনটি দেখাবেন না"</item>
</string-array>
<string-array name="battery_options">
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"উপরে সরান"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"বাঁয়ে সরান"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ডানে সরান"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings_tv.xml b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
index cbed4a1..6fa2d5b 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP নিয়ন্ত্রণ করতে "<b>"হোম"</b>" কী ধরে রাখুন"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP নিয়ন্ত্রণ করতে HOME বোতামটিকে টিপুন ও ধরে থাকুন"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"বুঝেছি"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"খারিজ করুন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 024bf70..728c874 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -237,8 +237,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija utvrđena GPS signalom"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktiviran je zahtjev za lokaciju"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Uklanjanje svih obavještenja."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavještenja"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran će se automatski rotirati."</string>
@@ -311,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraga"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> je onemogućena u sigurnom načinu rada."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historija"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ova aplikacija ne podržava rad sa više prozora"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava rad sa više prozora"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
@@ -481,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Prikaži na vrhu liste obavještenja, kratko prikaži na ekranu i dozvoli zvuk"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
<string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole <xliff:g id="APP_NAME">%1$s</xliff:g> obavještenja"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
<string name="night_mode" msgid="3540405868248625488">"Noćni način rada"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibracija zaslona"</string>
@@ -502,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Tipka za početak"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Nazad"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gore"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolje"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Lijevo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Razmaknica"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Tipka za novi red"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tipka za brisanje"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Pokreni/pauziraj"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zaustavi"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sljedeće"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prethodno"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Premotaj"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Ubrzaj"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Tipka Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Tipka Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Tipka za brisanje"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Tipka za početak"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Kraj"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Tipka za umetanje"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Tipka Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerička tastatura <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početak"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string>
@@ -561,4 +584,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomjeri gore"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomjeri lijevo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomjeri desno"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija možda neće raditi s višestrukim prozorom"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
index 5d20c8c..65c0982 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
@@ -29,6 +29,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Za kontrolu PIP, pritisnite i držite dugme POČETAK"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 645c84f..352e132 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuració de les notificacions"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuració de l\'aplicació <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"En mode segur, l\'aplicació <xliff:g id="APP">%s</xliff:g> està desactivada."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Esborra"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Esborra-ho tot"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aquesta aplicació no admet el mode multifinestra"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'aplicació no admet el mode multifinestra"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisió horitzontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Les notificacions es mostren al capdamunt de la llista, apareixen a la pantalla i poden emetre sons"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Més opcions"</string>
<string name="notification_done" msgid="5279426047273930175">"Fet"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controls de notificació de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Color i aparença"</string>
<string name="night_mode" msgid="3540405868248625488">"Mode nocturn"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibra la pantalla"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Redueix el rendiment i les dades en segon pla"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botó <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Inici"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Enrere"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Amunt"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Avall"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Esquerra"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dreta"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Pestanya"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espai"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Retorn"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retrocés"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reprodueix/Pausa"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Atura"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Següent"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobina"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avança ràpidament"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Re Pàg"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Av Pàg"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Suprimeix"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inici"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Final"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insereix"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueig de teclat numèric"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclat numèric <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mou amunt"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mou a l\'esquerra"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mou a la dreta"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"És possible que l\'aplicació no funcioni amb el Mode multifinestra"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index 35482d4..8876664 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Prem "<b>"INICI"</b>" per controlar PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén premut el botó INICI per controlar PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"D\'acord"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignora"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5ce6bd9..ea8ae38 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -311,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikace <xliff:g id="APP">%s</xliff:g> je v nouzovém režimu zakázána."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historie"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazat"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazat vše"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Tato aplikace režim v několika oknech nepodporuje"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikace režim v několika oknech nepodporuje"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vodorovné rozdělení"</string>
@@ -501,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omezuje výkon a data na pozadí"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tlačítko <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Zpět"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nahoru"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolů"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vlevo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Vpravo"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Střed"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulátor"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Mezerník"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Přehrát/Pozastavit"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zastavit"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Další"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Předchozí"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Přetočit zpět"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Přetočit vpřed"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> na numerické klávesnici"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string>
@@ -559,4 +584,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Přesunout nahoru"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Přesunout vlevo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Přesunout vpravo"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0538bdb..b6c2b73 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle underretninger."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> mere"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Underretningsindstillinger"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Indstillinger for <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er deaktiveret i sikker tilstand."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ryd"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ryd alle"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Denne app understøtter ikke flere vinduer"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen understøtter ikke flere vinduer"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Vis øverst på listen over underretninger, vis på skærmen, og tillad lyd"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Flere indstillinger"</string>
<string name="notification_done" msgid="5279426047273930175">"Færdig"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrolelementer til underretninger for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Farve og udseende"</string>
<string name="night_mode" msgid="3540405868248625488">"Nattilstand"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibrer skærmen"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reducerer ydeevne og baggrundsdata"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g>-knap"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Tilbage"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Op"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Venstre"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Højre"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midtertast"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulatortast"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Mellemrumstast"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tilbagetast"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Afspil/pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Næste"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Forrige"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spol tilbage"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spol frem"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerisk tastatur <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flyt op"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flyt til venstre"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flyt til højre"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index 51b8582..45bba75 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" nede for at styre PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Tryk på HOME-knappen, og hold den nede for at styre PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Afvis"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4cd0316..922939e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Benachrichtigungseinstellungen"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Einstellungen von <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ist im abgesicherten Modus deaktiviert."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Verlauf"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Löschen"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alle löschen"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Diese App unterstützt den Mehrfenstermodus nicht"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App unterstützt Mehrfenstermodus nicht"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Geteilte Schaltfläche – horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Ganz oben in der Benachrichtigungsliste anzeigen, auf dem Display einblenden und Ton zulassen"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Weitere Einstellungen"</string>
<string name="notification_done" msgid="5279426047273930175">"Fertig"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-Benachrichtigungseinstellungen"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Farbe und Darstellung"</string>
<string name="night_mode" msgid="3540405868248625488">"Nachtmodus"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Bildschirm kalibrieren"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduzierung der Leistung und Hintergrunddaten"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Taste <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Pos1"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Zurück"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nach oben"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Nach unten"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Nach links"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Nach rechts"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Zentrieren"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulatortaste"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Leertaste"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Eingabetaste"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Rücktaste"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Wiedergabe/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stopp"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Weiter"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Zurück"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Zurückspulen"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Vorspulen"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Nach oben"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Nach unten"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Entf"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Pos1"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Ende"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Einfg"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Ziffernblock <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Nach oben verschieben"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Nach links verschieben"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Nach rechts verschieben"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"App funktioniert im Mehrfenstermodus möglicherweise nicht"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index f448737..3d9c233 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"STARTBILDSCHIRMTASTE"</b>" drücken, um PIP zu steuern"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Halte die Taste für die Startseite gedrückt, um das Bild-in-Bild zu steuern"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Beenden"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 59810c2..7a23ac9 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Τα αιτήματα τοποθεσίας έχουν ενεργοποιηθεί"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ρυθμίσεις ειδοποιήσεων"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ρυθμίσεις <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Η εφαρμογή <xliff:g id="APP">%s</xliff:g> έχει απενεργοποιηθεί στην ασφαλή λειτουργία."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Ιστορικό"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Εκκαθάριση"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Διαγραφή όλων"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Η εφαρμογή αυτή δεν υποστηρίζει τη λειτουργία πολλαπλών παραθύρων"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Η εφαρμογή δεν υποστηρίζει τη λειτουργία πολλαπλών παραθύρων"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Οριζόντιος διαχωρισμός"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Να εμφανίζονται στην κορυφή της λίστας ειδοποιήσεων, να προβάλλονται στην οθόνη και να επιτρέπεται ο ήχος"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Περισσότερες ρυθμίσεις"</string>
<string name="notification_done" msgid="5279426047273930175">"Τέλος"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Στοιχεία ελέγχου κοινοποίησης <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Χρώμα και εμφάνιση"</string>
<string name="night_mode" msgid="3540405868248625488">"Νυχτερινή λειτουργία"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Βαθμονόμηση οθόνης"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Μειώνει την απόδοση και τα δεδομένα παρασκηνίου"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Κουμπί <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Πίσω"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Πάνω"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Κάτω"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Αριστερά"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Δεξιά"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Κέντρο"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Πλήκτρο διαστήματος"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Αναπαραγωγή/Παύση"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Διακοπή"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Επόμενο"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Προηγούμενο"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Επαναφορά"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Γρήγορη προώθηση"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Προηγούμενη σελίδα"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Επόμενη σελίδα"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Λήξη"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Αριθμητικό πληκτρολόγιο <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Σύστημα"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Μετακίνηση προς τα επάνω"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Μετακίνηση αριστερά"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Μετακίνηση δεξιά"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Η εφαρμογή ενδέχεται να μη λειτουργεί με τη λειτουργία πολλαπλών παραθύρων"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
index 355c9b0..c54c7be 100644
--- a/packages/SystemUI/res/values-el/strings_tv.xml
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Κρατήστε το πλήκτρο "<b>"HOME"</b>" πατημένο για έλεγχο του PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Πιέστε παρατεταμένα το κουμπί HOME, για να ελέγξετε τη λειτουργία PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Κατάλαβα"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Παράβλεψη"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 45b4020..9106592 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración de notificaciones"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -304,14 +303,13 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Modo de trabajo"</string>
<string name="recents_empty_message" msgid="808480104164008572">"No hay elementos recientes"</string>
- <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Borraste todo"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Todo borrado"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Fijar pantalla"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> está inhabilitada en modo seguro."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta app no es compatible con el modo multiventana"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"La app no es compatible con el modo multiventana"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostrar en la parte superior de la lista de notificaciones, ver en la pantalla y permitir sonidos"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Más opciones de configuración"</string>
<string name="notification_done" msgid="5279426047273930175">"Listo"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Color y apariencia"</string>
<string name="night_mode" msgid="3540405868248625488">"Modo nocturno"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrar pantalla"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y el uso de datos en segundo plano"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Página principal"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Atrás"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abajo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Izquierda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Derecha"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulación"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espacio"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Ingresar"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retroceso"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/pausar"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Detener"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Siguiente"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avanzar rápido"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Página anterior"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Página siguiente"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Borrar"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Página principal"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Finalizar"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insertar"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueo numérico"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover hacia arriba"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover a la izquierda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover a la derecha"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index 98ad35b..72ea127 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Mantén presionado "<b>"INICIO"</b>" para controlar PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén presionado el botón INICIO para controlar PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Entendido"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Descartar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 5c84999..c2f3a3a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -236,7 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
- <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ de <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ajustes de notificaciones"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ajustes de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"La aplicación <xliff:g id="APP">%s</xliff:g> se ha inhabilitado en modo seguro."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicación no admite el modo multiventana."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"La aplicación no admite el modo multiventana"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y las conexiones automáticas"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Inicio"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Atrás"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abajo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Izquierda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Derecha"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulador"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espacio"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Intro"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tecla de retroceso"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/Pausa"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Detener"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Siguiente"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobinar"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rápido"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Retroceder página"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Avanzar página"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supr"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inicio"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloq Num"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Subir"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover a la izquierda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover a la derecha"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Es posible que la aplicación no funcione con el modo multiventana"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 423166f..0524d3b 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Rakendus <xliff:g id="APP">%s</xliff:g> on turvarežiimis keelatud."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Ajalugu"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kustuta"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kustuta kõik"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"See rakendus ei toeta mitut akent"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Rakendus ei toeta mitut akent"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horisontaalne poolitamine"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vähendab jõudlust ja taustaandmeid"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Nupp <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Avaekraan"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Tagasi"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Üles"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Alla"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vasakule"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Paremale"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Keskele"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulaator"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Tühik"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Sisestusklahv"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tagasilüke"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Esita/peata"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Peata"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Järgmine"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Eelmine"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Keri tagasi"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Keri edasi"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Lehe võrra üles"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Lehe võrra alla"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Kustuta"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Avaekraan"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Lõpp"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Sisesta"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Numbrilukk"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numbriklahvistik <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Süsteem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Avaekraan"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Hiljutised"</string>
@@ -557,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Liigu üles"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Liigu vasakule"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Liigu paremale"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 435e821..2e207c1 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Kokapena GPS bidez ezarri da"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aplikazioen kokapen-eskaerak aktibo daude"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Garbitu jakinarazpen guztiak."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Jakinarazpen-ezarpenak"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ezarpenak"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Pantaila automatikoki biratuko da."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> desgaituta dago modu seguruan."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Garbitu"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Garbitu guztiak"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aplikazioak ez du onartzen leiho bat baino gehiago erabiltzea"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikazioak ez du onartzen leiho bat baino gehiago erabiltzea"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Zatitze horizontala"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Erakutsi jakinarazpen hauek zerrendaren goialdean, agerrarazi pantailan eta egin soinua"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Ezarpen gehiago"</string>
<string name="notification_done" msgid="5279426047273930175">"Eginda"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak kontrolatzeko aukerak"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Kolorea eta itxura"</string>
<string name="night_mode" msgid="3540405868248625488">"Gau modua"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibratu pantaila"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Errendimendua eta atzeko planoko datuen erabilera murrizten ditu"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> botoia"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Hasiera"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Atzera"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gora"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Behera"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ezkerrera"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Eskuinera"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Erdiratu"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabuladorea"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Zuriunea"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Sartu"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Atzera"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Erreproduzitu/Pausatu"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Gelditu"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Hurrengoa"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Aurrekoa"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Atzeratu"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Aurreratu"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Orria gora"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Orria behera"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ezabatu"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Hasiera"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Amaitu"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Txertatu"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Blok Zenb"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Zenbaki-teklatuko <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Eraman gora"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Eraman ezkerrera"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Eraman eskuinera"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
index f28ec5e..b812143 100644
--- a/packages/SystemUI/res/values-eu-rES/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"HASIERA"</b>" PIP kontrolatzeko"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Eduki sakatuta hasierako botoia pantaila txikia kontrolatzeko"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Ados"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Baztertu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f2e977c..777fd2b 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"درخواستهای موقعیت مکانی فعال است"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"تنظیمات اعلان"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"تنظیمات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"صفحه به صورت خودکار میچرخد."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> در حالت ایمن غیرفعال است."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"سابقه"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"پاک کردن"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"پاک کردن همه"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"این برنامه از چندپنجره پشتیبانی نمیکند"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"برنامه از چندپنجره پشتیبانی نمیکند"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسیم افقی"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"در بالای فهرست اعلان نشان داده شوند، در صفحه نشان داده شوند و صدادار باشند"</string>
<string name="notification_more_settings" msgid="816306283396553571">"تنظیمات بیشتر"</string>
<string name="notification_done" msgid="5279426047273930175">"تمام"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"کنترلهای اعلان <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"رنگ و ظاهر"</string>
<string name="night_mode" msgid="3540405868248625488">"حالت شب"</string>
<string name="calibrate_display" msgid="5974642573432039217">"درجهبندی نمایشگر"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینهسازی باتری» در دسترس نیست"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینهسازی باتری"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"عملکرد و اطلاعات پسزمینه را کاهش میدهد"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"دکمه <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"ابتدا"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"برگشت"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"بالا"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"پایین"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"چپ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"راست"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"مرکز"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"جهش"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"فاصله"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"ورود"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"پسبر"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"پخش/مکث"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"توقف"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"بعدی"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"قبلی"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"عقب بردن"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"جلو بردن سریع"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"صفحه بعدی"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"صفحه قبلی"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"حذف"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"ابتدا"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"انتها"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"درج"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"قفل اعداد"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"صفحهکلید عددی <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سیستم"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"انتقال به بالا"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"انتقال به چپ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"انتقال به راست"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"برنامه ممکن است با چندپنجره کار نکند"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index 5177724..0d028d8 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"کنترل PIP با نگهداشتن "<b>"HOME"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"برای کنترل PIP دکمه صفحه اصلی را فشار داده و نگهدارید"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"متوجه شدم"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"رد کردن"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 11cb91e..f100d21 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Sijaintipyynnöt aktiiviset"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ilmoitusasetukset"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Asetukset – <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> on poistettu käytöstä vikasietotilassa."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tyhjennä"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tyhjennä kaikki"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Tämä sovellus ei tue usean ikkunan tilaa."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Sovellus ei tue usean ikkunan tilaa."</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vaakasuuntainen jako"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Näytä ilmoitukset näytöllä ja ilmoitusluettelon yläosassa ja salli niiden äänet."</string>
<string name="notification_more_settings" msgid="816306283396553571">"Lisäasetukset"</string>
<string name="notification_done" msgid="5279426047273930175">"Valmis"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ilmoitusten hallinta"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Väri ja ulkoasu"</string>
<string name="night_mode" msgid="3540405868248625488">"Yötila"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibroi näyttö"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Rajoittaa suorituskykyä ja taustatiedonsiirtoa."</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Painike <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Takaisin"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Ylös"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Alas"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vasemmalle"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Oikealle"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Keskelle"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Sarkain"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Välilyönti"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Askelpalautin"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Toisto/keskeytys"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Pysäytä"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seuraava"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Edellinen"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Kelaa taaksepäin"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Kelaa eteenpäin"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numeronäppäimistö <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Järjestelmä"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Siirrä ylöspäin"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Siirrä vasemmalle"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Siirrä oikealle"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 642ed20..9124f67 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP: paina pitkään "<b>"aloituspain"</b>"."</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Hallinnoi PIP-tilaa painamalla ALOITUSNÄYTTÖ-painiketta pitkään."</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Selvä"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hylkää"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index c647cc9..1bec7fd 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Effacer tout"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Cette application ne prend pas en charge le mode multifenêtre"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'application ne prend pas en charge le mode multifenêtre"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Afficher en haut de la liste des notifications, afficher sur l\'écran et émettre un son"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Plus de paramètres"</string>
<string name="notification_done" msgid="5279426047273930175">"Terminé"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Commandes de notification pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Couleur et apparence"</string>
<string name="night_mode" msgid="3540405868248625488">"Mode Nuit"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrer l\'affichage"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Réduit les performances et les données en arrière-plan"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Accueil"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Précédent"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Haut"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Bas"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Gauche"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Droite"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrer"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulation"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espace"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Entrée"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retour arrière"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lecture/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Arrêter"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Suivant"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Précédent"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Reculer"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rapide"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page précédente"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page suivante"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supprimer"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Accueil"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insérer"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Verr num"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pavé numérique <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Déplacer vers le haut"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Déplacer vers la gauche"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Déplacer vers la droite"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index 1ae3c5c..597a588 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Maint. enf. "<b>"ACC."</b>" pr gér. mode IDI"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Maintenez enfoncé le bouton ACCUEIL pour gérer le mode IDI."</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Fermer"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7d91f6f..bb22848 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> autres"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"L\'application <xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tout effacer"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Application incompatible avec le mode multifenêtre."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Application incompatible avec le mode multifenêtre"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Afficher en haut de la liste des notifications, afficher sur l\'écran et émettre un son"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Plus de paramètres"</string>
<string name="notification_done" msgid="5279426047273930175">"Terminé"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Commandes de notification de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Couleur et apparence"</string>
<string name="night_mode" msgid="3540405868248625488">"Mode Nuit"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrer l\'affichage"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Limite les performances et les données en arrière-plan."</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Accueil"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Précédent"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Vers le haut"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Vers le bas"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vers la gauche"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Vers la droite"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulation"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espace"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Entrée"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retour arrière"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lire ou suspendre la lecture"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Arrêter"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Suivant"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Précédent"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retour arrière"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rapide"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page précédente"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page suivante"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supprimer"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Accueil"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insérer"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Verr Num"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pavé numérique <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Déplacer vers le haut"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Déplacer vers la gauche"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Déplacer vers la droite"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index 68c4dcb..0478eea 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Appui long "<b>"ACCUEIL"</b>" pour contrôler PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Appuyez de manière prolongée sur le bouton ACCUEIL pour contrôler le mode PIP."</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorer"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 1474acf..6d4b7eb 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localización establecida polo GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de localización activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas as notificacións."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración das notificacións"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A pantalla xirará automaticamente."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"A aplicación <xliff:g id="APP">%s</xliff:g> está desactivada no modo seguro"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicación non é compatible con varias ventás"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"A aplicación non é compatible con varias ventás"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dividir en horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificacións, amosar na pantalla e permitir que emita son"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Máis opcións"</string>
<string name="notification_done" msgid="5279426047273930175">"Feito"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controis de notificacións de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Cor e aspecto"</string>
<string name="night_mode" msgid="3540405868248625488">"Modo nocturno"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrar pantalla"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función aforro de batería non está dispoñible durante a carga"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce o rendemento e os datos en segundo plano"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Inicio"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Volver"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abaixo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Esquerda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dereita"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulador"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espazo"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Intro"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retroceso"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/Pausar"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Deter"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seguinte"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobinar"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rápido"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Re Páx"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Av Páx"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supr"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inicio"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserir"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueo numérico"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Subir"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover á esquerda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover á dereita"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings_tv.xml b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
index 11d2d4c..d43d8cc 100644
--- a/packages/SystemUI/res/values-gl-rES/strings_tv.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Manter premido "<b>"INICIO"</b>" para controlar PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén premido o botón de INICIO para controlar PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"De acordo"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 7b64214..5b68088 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"શોધ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી શકાયું નથી."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"સુરક્ષિત મોડમાં <xliff:g id="APP">%s</xliff:g> અક્ષમ કરેલ છે."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ઇતિહાસ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"સાફ કરો"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"બધું સાફ કરો"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"આ ઍપ્લિકેશન મલ્ટિ-વિંડોનું સમર્થન કરતી નથી"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ઍપ્લિકેશન મલ્ટિ-વિંડોનું સમર્થન કરતી નથી"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"આડું વિભક્ત કરો"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"બટન <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"સિસ્ટમ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string>
@@ -557,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ઉપર ખસેડો"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ડાબે ખસેડો"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"જમણે ખસેડો"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 84c073d..44c0dbc 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> को सुरक्षित-मोड में अक्षम किया गया."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ़ करें"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"यह ऐप्लिकेशन एकाधिक विंडो का समर्थन नहीं करता है"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ऐप्लिकेशन एकाधिक विंडो का समर्थन नहीं करता है"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"निष्पादन और पृष्ठभूमि डेटा को कम करता है"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"बटन <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ऊपर तीर"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"नीचे तीर"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"बायां तीर"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"दायां तीर"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"मध्य तीर"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टम"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ऊपर ले जाएं"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"बाएं ले जाएं"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"दाएं ले जाएं"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"हो सकता है कि ऐप्लिकेशन एकाधिक विंडो के साथ काम ना करे"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e69ad31..c3d6a24 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -237,8 +237,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Zahtjevi za lokaciju aktivni su"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"još <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavijesti"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
@@ -311,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> onemogućena je u sigurnom načinu."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Povijest"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši sve"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacija ne podržava više prozora"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava više prozora"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podijeli vodoravno"</string>
@@ -481,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Prikaži pri vrhu popisa obavijesti, prikaži na zaslonu i dopusti zvuk"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
<string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole obavijesti za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
<string name="night_mode" msgid="3540405868248625488">"Noćni način rada"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibriranje zaslona"</string>
@@ -502,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje količinu rada i pozadinske podatke"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tipka <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Početak"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Natrag"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gore"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolje"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Lijevo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Razmaknica"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Unos"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Povratna tipka"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reprodukcija/pauza"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zaustavi"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sljedeće"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prethodno"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Unatrag"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Brzo naprijed"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Stranica prema gore"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Stranica prema dolje"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Izbriši"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Početak"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Kraj"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Umetni"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Zaključavanje brojčane tipkovnice"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Brojčana tipkovnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sustav"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomakni prema gore"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomakni ulijevo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomakni udesno"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija možda neće funkcionirati uz više prozora"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
index 3d5c8f8..340a613 100644
--- a/packages/SystemUI/res/values-hr/strings_tv.xml
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Držite "<b>"POČETNI"</b>" za PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Pritisnite i zadržite tipku POČETNI ZASLON da biste upravljali slikom u slici"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Shvaćam"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a7d62c3..40fb3e23 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"A(z) <xliff:g id="APP">%s</xliff:g> csökkentett módban ki van kapcsolva."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Előzmények"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Törlés"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Összes törlése"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ez az alkalmazás nem támogatja a többablakos nézetet"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Az alkalmazás nem támogatja a többablakos nézetet"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Osztott vízszintes"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Csökkenti a teljesítményt és a háttéradatok használatát"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> gomb"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Kezdőképernyő"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Vissza"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Fel"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Le"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Balra"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Jobbra"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Középre"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Szóköz"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Visszatörlés"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lejátszás/szünet"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Leállítás"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Következő"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Előző"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Visszatekerés"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Gyors előretekerés"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Kezdőképernyő"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerikus: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Rendszer"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Otthon"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Legutóbbiak"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mozgatás felfelé"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mozgatás balra"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mozgatás jobbra"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Lehet, hogy az alkalmazás nem működik többablakos nézetben"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 79e5268..a2e45e1 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Տեղադրությունը կարգավորվել է GPS-ի կողմից"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Տեղադրության հարցումներն ակտիվ են"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ծանուցման կարգավորումներ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-ի կարգավորումներ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնաշխատ կպտտվի:"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> հավելվածը անվտանգ ռեժիմում անջատված է:"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Պատմություն"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Մաքրել"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Մաքրել բոլորը"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Այս հավելվածը չի աջակցում բազմապատուհան ռեժիմը"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Հավելվածը չի աջակցում բազմապատուհան ռեժիմը"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Հորիզոնական տրոհում"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Ցույց տալ ծանուցումների ցանկի վերևում, թռուցիկ ցուցադրել էկրանին և թույլատրել ձայնային ազդանշանը"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Այլ կարգավորումներ"</string>
<string name="notification_done" msgid="5279426047273930175">"Պատրաստ է"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ծանուցումների կառավարներ"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Գույնը և արտաքին տեսքը"</string>
<string name="night_mode" msgid="3540405868248625488">"Գիշերային ռեժիմ"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Չափաբերել էկրանը"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> կոճակ"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Գլխավոր էջ"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Հետ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Վերև"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ներքև"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ձախ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Աջ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Կենտրոն"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Բացատ"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Մուտք"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Հետշարժ"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Նվագարկում/դադար"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Դադարեցնել"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Հաջորդը"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Նախորդը"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Հետ անցնել"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Արագ առաջ անցնել"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ջնջել"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Գլխավոր էջ"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Վերջ"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Տեղադրել"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Համակարգ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Տեղափոխել վերև"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Տեղափոխել ձախ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Տեղափոխել աջ"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
index dc4c312..5f9c127 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP-ն կառավարելու համար սեղմած պահեք "<b>"HOME"</b>" կոճակը"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-ն կառավարելու համար սեղմեք և պահեք HOME կոճակը"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Պարզ է"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Փակել"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3ac5904..cad0e22 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setelan pemberitahuan"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> setelan"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dinonaktifkan dalam mode aman."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Riwayat"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hapus"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hapus semua"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aplikasi ini tidak mendukung multijendela"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikasi tidak mendukung multijendela"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Pisahkan Horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Tampilkan di bagian atas daftar notifikasi, muncul di layar, dan izinkan suara"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Setelan lainnya"</string>
<string name="notification_done" msgid="5279426047273930175">"Selesai"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrol notifikasi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Warna dan tampilan"</string>
<string name="night_mode" msgid="3540405868248625488">"Mode malam"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibrasi layar"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangi performa dan data latar belakang"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tombol <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Naikkan"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pindahkan ke kiri"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pindahkan ke kanan"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikasi mungkin tidak berfungsi dengan multi-jendela"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index 8e3a5e0..7de1a78 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Tahan "<b>"LAYAR UTAMA"</b>" untuk mengontrol PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Tekan dan tahan tombol LAYAR UTAMA untuk mengontrol PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Mengerti"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Tutup"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index c063c73..f609800 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Staðsetning valin með GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Staðsetningarbeiðnir virkar"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Hreinsa allar tilkynningar."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tilkynningastillingar"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Stillingar fyrir <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjárinn snýst sjálfkrafa."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Slökkt er á <xliff:g id="APP">%s</xliff:g> í öruggri stillingu."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Ferill"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hreinsa"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hreinsa allt"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Þetta forrit styður ekki marga glugga"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Forritið styður ekki marga glugga"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Lárétt skipting"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Sýna efst á tilkynningalistanum, birta á skjánum og leyfa hljóð"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Fleiri stillingar"</string>
<string name="notification_done" msgid="5279426047273930175">"Lokið"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Tilkynningastýringar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Litur og útlit"</string>
<string name="night_mode" msgid="3540405868248625488">"Næturstilling"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kvarða skjáinn"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Dregur úr afköstum og bakgrunnsgögnum"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Hnappur <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Til baka"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Upp"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Niður"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vinstri"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Hægri"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Miðja"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Bilslá"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Bakklykill"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spila/gera hlé"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stöðva"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Áfram"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Fyrri"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spóla til baka"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spóla áfram"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tölulykill <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Kerfi"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Færa upp"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Færa til vinstri"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Færa til hægri"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings_tv.xml b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
index 053beaf..09c67ec 100644
--- a/packages/SystemUI/res/values-is-rIS/strings_tv.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Haltu "<b>"HOME"</b>"-hnappinum inni til að stjórna innfelldri mynd"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Haltu „Home“-hnappinum inni til að stjórna innfelldri mynd"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Ég skil"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hunsa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 5ccc39c..591bf0d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Richieste di accesso alla posizione attive"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Impostazioni di notifica"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Impostazioni di <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"L\'app <xliff:g id="APP">%s</xliff:g> è stata disattivata in modalità provvisoria."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Cronologia"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Cancella"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Cancella tutto"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Questa app non supporta la modalità multi-finestra"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'app non supporta la modalità multi-finestra"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisione in orizzontale"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostra in cima all\'elenco delle notifiche, visualizza sullo schermo e attiva l\'audio"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Altre impostazioni"</string>
<string name="notification_done" msgid="5279426047273930175">"Fine"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controlli di notifica per <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Colore e aspetto"</string>
<string name="night_mode" msgid="3540405868248625488">"Modalità notturna"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibra display"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Riduce le prestazioni e i dati in background"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Pulsante <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home page"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Indietro"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Su"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Giù"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sinistra"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Destra"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Al centro"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Scheda"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Spazio"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Invio"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pausa"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Interrompi"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avanti"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Precedente"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Riavvolgi"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avanza velocemente"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Pagina su"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Pagina giù"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Elimina"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home page"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fine"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"INS"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloc Num"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tastierino numerico <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Sposta su"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sposta a sinistra"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sposta a destra"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index 5001b95..4ea019b 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Tieni premuto "<b>"HOME"</b>" per controllare PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Tieni premuto il pulsante HOME per controllare PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignora"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 52c83ba..7e0122d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"הגדרות עבור הודעות"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"הגדרות <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> מושבת במצב בטוח."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"היסטוריה"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"נקה"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"נקה הכל"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"אפליקציה זו אינה תומכת בריבוי חלונות"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"האפליקציה אינה תומכת בריבוי חלונות"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"פיצול אופקי"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"הצג בראש רשימת ההודעות, הצג לרגע על גבי המסך ואשר השמעת צליל"</string>
<string name="notification_more_settings" msgid="816306283396553571">"הגדרות נוספות"</string>
<string name="notification_done" msgid="5279426047273930175">"סיום"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> פקדי הודעות"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"צבע ומראה"</string>
<string name="night_mode" msgid="3540405868248625488">"מצב לילה"</string>
<string name="calibrate_display" msgid="5974642573432039217">"כיול תצוגה"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"מפחית את רמת הביצועים ואת נתוני הרקע"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"דף הבית"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"הקודם"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"למעלה"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"למטה"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"שמאלה"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ימינה"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"מרכז"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"כרטיסייה"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"רווח"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"BACKSPACE"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"הפעל/השהה"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"עצור"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"הבא"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"הקודם"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"הרץ אחורה"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"הרץ קדימה"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"דפדוף למעלה"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"דפדוף למטה"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"מחיקה"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"דף הבית"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"סיום"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"הזן"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"מקש Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"מקלדת נומרית <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"מערכת"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string>
@@ -562,4 +585,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"הזז למעלה"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"הזז שמאלה"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"הזז ימינה"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"ייתכן שהאפליקציה לא תפעל עם ריבוי חלונות"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index f4d4094..9130d53 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"לחץ לחיצה ארוכה על "<b>"דף הבית"</b>" כדי לשלוט ב-PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"לחץ לחיצה ממושכת על לחצן דף הבית כדי לשלוט ב-PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"הבנתי"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"דחה"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index f7aacee..36c0e1a 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"現在地リクエストがアクティブ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"他 <xliff:g id="NUMBER">%s</xliff:g> 件"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>の設定"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」はセーフモードでは無効になります。"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"履歴"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"消去"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"すべて消去"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"このアプリはマルチウィンドウに対応していません"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"アプリはマルチウィンドウに対応していません"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"横に分割"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"通知リストの先頭に表示し、画面に数秒間表示し、音声でも知らせる"</string>
<string name="notification_more_settings" msgid="816306283396553571">"詳細設定"</string>
<string name="notification_done" msgid="5279426047273930175">"完了"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」の通知の管理"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"色と表示"</string>
<string name="night_mode" msgid="3540405868248625488">"夜間モード"</string>
<string name="calibrate_display" msgid="5974642573432039217">"表示の調整"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"パフォーマンスとバックグラウンド データを制限します"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> ボタン"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"戻る"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"上"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"下"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"左"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"右"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"中央"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"再生 / 一時停止"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"次へ"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"前へ"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"巻き戻し"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"早送り"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"PageUp"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"PageDown"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"NumLock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"テンキーの <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"システム"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"上に移動"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"左に移動"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"右に移動"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"アプリはマルチウィンドウでは動作しないことがあります"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index a4c49b3..0f0032f 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP を管理するには ["<b>"ホーム"</b>"] を押し続けます"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP を管理するには [ホーム] ボタンを押し続けます"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"閉じる"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"閉じる"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 9730323..0e6f335 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-ით დადგენილი მდებარეობა"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"მდებარეობის მოთხოვნები აქტიურია"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"შეტყობინების პარამეტრები"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> პარამეტრები"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ეკრანი შეტრიალდება ავტომატურად."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> გათიშულია უსაფრთხო რეჟიმში."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ისტორია"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"გასუფთავება"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ყველას გასუფთავება"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"მრავალი ფანჯრის რეჟიმი არ არის მხარდაჭერილი ამ აპის მიერ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"მრავალი ფანჯრის რეჟიმი არ არის მხარდაჭერილი აპის მიერ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ჰორიზონტალური გაყოფა"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"შეტყობინებების სიის თავში ჩვენება, პირდაპირ ეკრანზე გამოჩენა და ხმის დაშვება"</string>
<string name="notification_more_settings" msgid="816306283396553571">"დამატებითი პარამეტრები"</string>
<string name="notification_done" msgid="5279426047273930175">"მზადაა"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> შეტყობინებების მართვის საშუალებები"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ფერი და იერსახე"</string>
<string name="night_mode" msgid="3540405868248625488">"ღამის რეჟიმი"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ეკრანის კალიბრაცია"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ამცირებს წარმადობას და ფონურ მონაცემებს"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ღილაკი „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"უკან"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ზემოთ"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ქვემოთ"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"მარცხნივ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"მარჯვნივ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ცენტრში"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"შორისი"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"დაკვრა/პაუზა"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"შეწყვეტა"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"შემდეგი"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"წინა"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"უკან გადახვევა"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"წინ გადახვევა"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"რიცხვთა პანელი <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"სისტემა"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ზემოთ გადატანა"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"მარცხნივ გადატანა"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"მარჯვნივ გადატანა"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
index 3a556ae..7d615ba 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP-ის სამართავად, გეჭიროთ "<b>"მთავარ ღილაკზე"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-ის სამართავად, ხანგრძლივად დააჭირეთ მთავარ ღილაკს"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"გასაგებია"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"დახურვა"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index f6c1152..0a06bdf 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Орын GPS арқылы орнатылған"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Орын өтініштері қосылған"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Барлық хабарларды жойыңыз."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Хабарландыру параметрлері"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> параметрлері"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматты түрде бұрылады."</string>
@@ -310,8 +309,8 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> қауіпсіз режимде өшіріледі."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Тарих"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалау"</string>
+ <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+ <skip />
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Бұл қолданба көп терезені қолдамайды"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Қолданба көп терезені қолдамайды"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Бөлінген көлденең"</string>
@@ -480,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Хабарландырулар тізімінің жоғарғы жағында көрсету, экранда көрсету және дыбысқа рұқсат ету"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Қосымша параметрлер"</string>
<string name="notification_done" msgid="5279426047273930175">"Дайын"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> хабарландыруларды басқару элементтері"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Түс және сыртқы түрі"</string>
<string name="night_mode" msgid="3540405868248625488">"Түнгі режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Дисплейді калибрлеу"</string>
@@ -501,6 +499,58 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Өнімділікті және фондық деректерді азайтады"</string>
+ <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+ <skip />
+ <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+ <skip />
+ <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+ <skip />
+ <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+ <skip />
+ <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+ <skip />
+ <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+ <skip />
+ <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+ <skip />
+ <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+ <skip />
+ <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+ <skip />
+ <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+ <skip />
+ <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+ <skip />
+ <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+ <skip />
+ <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+ <skip />
+ <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+ <skip />
+ <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+ <skip />
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Жүйе"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string>
@@ -559,4 +609,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Жоғары қарай жылжыту"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Солға жылжыту"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Оңға жылжыту"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Қолданба көп тереземен жұмыс істемеуі мүмкін"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
index ef930b0..06c84a8 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP басқару үшін "<b>"HOME"</b>" басып тұрыңыз"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP функциясын басқару үшін HOME түймесін басып тұрыңыз"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Түсіндім"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Жабу"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 4a306da..46b1435 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ទីតាំងកំណត់ដោយ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"សំណើទីតាំងសកម្ម"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"សម្អាតការជូនដំណឹងទាំងអស់។"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"កំណត់ការជូនដំណឹង"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ការកំណត់ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"នឹងបង្វិលអេក្រង់ស្វ័យប្រវត្តិ។"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"មិនអាចចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ត្រូវបានបិទដំណើរការក្នុងរបៀបសុវត្ថិភាព"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ប្រវត្តិ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"សម្អាត"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ជម្រះទាំងអស់"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"កម្មវិធីនេះមិនគាំទ្រផ្ទាំងវិដូច្រើនទេ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"កម្មវិធីមិនគាំទ្រផ្ទាំងវិដូច្រើនទេ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"បំបែកផ្តេក"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"បង្ហាញនៅផ្នែកខាងលើបញ្ជីនៃការជូនដំណឹង លោតបង្ហាញនៅលើអេក្រង់ និងអនុញ្ញាតឲ្យបន្លឺសំឡេង"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ការកំណត់ច្រើនទៀត"</string>
<string name="notification_done" msgid="5279426047273930175">"រួចរាល់"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"អង្គគ្រប់គ្រងការជូនដំណឹង <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ពណ៌ និងរូបរាង"</string>
<string name="night_mode" msgid="3540405868248625488">"របៀបពេលយប់"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ការបង្ហាញក្រិត"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ប៊ូតុង <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ប្រព័ន្ធ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ផ្លាស់ទីឡើងលើ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ផ្លាស់ទីទៅឆ្វេង"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ផ្លាស់ទីទៅស្តាំ"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"កម្មវិធីអាចនឹងមិនដំណើរការជាមួយពហុវិនដូទេ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
index 8076010..123cb76 100644
--- a/packages/SystemUI/res/values-km-rKH/strings_tv.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"សង្កត់ប៊ូតុង "<b>"ដើម"</b>" ដើម្បីគ្រប់គ្រង PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"ចុច និងសង្កត់ប៊ូតុង ដើម ដើម្បីគ្រប់គ្រង PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"យល់ហើយ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"បដិសេធ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 046d5d8..f26abdc 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ಸ್ಥಾನವನ್ನು GPS ಮೂಲಕ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ಸ್ಥಾನ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ಪರದೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಿರುಗುತ್ತದೆ."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ಇತಿಹಾಸ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ತೆರವುಗೊಳಿಸು"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸು"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಹು-ವಿಂಡೊಗಳನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ಅಪ್ಲಿಕೇಶನ್ ಬಹು-ವಿಂಡೊಗಳನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ಅಡ್ಡಲಾಗಿ ವಿಭಜಿಸಿದ"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"ಅಧಿಸೂಚನೆಗಳ ಪಟ್ಟಿಯ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೋರಿಸು, ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಧ್ವನಿ ಅನುಮತಿಸಿ"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="notification_done" msgid="5279426047273930175">"ಮುಗಿದಿದೆ"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ಬಣ್ಣ ಮತ್ತು ಗೋಚರತೆ"</string>
<string name="night_mode" msgid="3540405868248625488">"ರಾತ್ರಿ ಮೋಡ್"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ಅಣಿಗೊಳಿಸುವ ಪ್ರದರ್ಶನ"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> ಬಟನ್"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ಹಿಂದೆ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ಮೇಲೆ"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ಕೆಳಗೆ"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ಎಡ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ಬಲ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ಮಧ್ಯ"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"ಸ್ಪೇಸ್"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ಮುಂದೆ"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ಹಿಂದೆ"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ಫಾಸ್ಟ್ ಫಾರ್ವರ್ಡ್"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> ಸಂಖ್ಯೆಪ್ಯಾಡ್"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ಸಿಸ್ಟಂ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ಮೇಲೆ ಸರಿಸಿ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"ಬಹು ವಿಂಡೋದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings_tv.xml b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
index d275de6..6491587 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP ನಿಯಂತ್ರಿಸಲು "<b>"HOME"</b>" ಕೀಯನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP ನಿಯಂತ್ರಿಸಲು HOME ಬಟನ್ ಒತ್ತಿರಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"ಅರ್ಥವಾಯಿತು"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"ವಜಾಗೊಳಿಸಿ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5e16258..5e28f0b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"위치 요청 있음"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g>개 더보기"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"알림 설정"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> 설정"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>은(는) 안전 모드에서 사용 중지됩니다."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"기록"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"삭제"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"모두 지우기"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"이 앱은 다중 창을 지원하지 않습니다."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"앱이 다중 창을 지원하지 않습니다."</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"수평 분할"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"알림 목록 맨 위에 표시, 화면에 표시하고 소리로 알림"</string>
<string name="notification_more_settings" msgid="816306283396553571">"설정 더보기"</string>
<string name="notification_done" msgid="5279426047273930175">"완료"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> 알림 관리"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"색상 및 모양"</string>
<string name="night_mode" msgid="3540405868248625488">"야간 모드"</string>
<string name="calibrate_display" msgid="5974642573432039217">"디스플레이 보정"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"성능 및 백그라운드 데이터를 줄입니다."</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 버튼"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"뒤로"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"위쪽"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"아래쪽"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"왼쪽"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"오른쪽"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"중앙"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"재생/일시중지"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"중지"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"다음"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"이전"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"되감기"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"빨리 감기"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"숫자 패드 <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"시스템"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"위로 이동"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"왼쪽으로 이동"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"오른쪽으로 이동"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index 52747b4..da3ab9e 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"HOME"</b>"을 눌러 PIP 제어"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"홈 버튼을 길게 눌러 PIP 제어"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"확인"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"닫기"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 60db439..9cd5f60 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS боюнча аныкталган жайгашуу"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Жайгаштыруу талаптары иштелүүдө"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бардык эскертмелерди тазалоо."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Эскертме жөндөөлөрү"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> жөндөөлөрү"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматтык түрдө бурулат."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> коопсуз режиминде өчүрүлдү."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Таржымал"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалоо"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Баарын тазалоо"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Бул колдонмодо бир нече терезе режими колдоого алынбайт"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Колдонмодо бир нече терезе режими колдоого алынбайт"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Туурасынан бөлүү"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Эскертмелер тизмесинин эң башында көрсөтүлүп, үн менен коштолуп, экранга чыгарылсын"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Дагы жөндөөлөр"</string>
<string name="notification_done" msgid="5279426047273930175">"Аткарылды"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> эскертмесин көзөмөлдөө каражаттары"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Түсү жана көрүнүшү"</string>
<string name="night_mode" msgid="3540405868248625488">"Түнкү режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Дисплейди калибрлөө"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Иштин майнаптуулугун начарлатып, фондук дайындарды чектейт"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> баскычы"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Башкы бет"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Артка"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Өйдө"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Төмөн"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Солго"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Оңго"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Экрандын ортосунда"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Өтмөк"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Боштук"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Киргизүү"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Артка өчүрүү"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Ойнотуу/Тындыруу"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Токтотуу"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Кийинки"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Мурунку"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Артка түрүү"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Алдыга түрүү"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Бир бет жогору"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Бир бет төмөн"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Жок кылуу"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Башкы бет"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Бүтүрүү"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Салуу"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Тутум"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Жогору жылдыруу"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Солго жылдыруу"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Оңго жылдыруу"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
index e54aae2..b030542 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"БАШКЫ БЕТ"</b>" басып туруп PIP\'ти башкарыңыз"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP башкаруу үчүн БАШКЫ БЕТ баскычын басып, кармап туруңуз"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Түшүндүм"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Көз жаздымда калтыруу"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index ecb1eb3..182abe9 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ສະຖານທີ່ກຳນົດໂດຍ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ການຮ້ອງຂໍສະຖານທີ່ທີ່ເຮັດວຽກຢູ່"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ການຕັ້ງຄ່າການແຈ້ງເຕືອນ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ການຕັ້ງຄ່າ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ໜ້າຈໍຈະໝຸນໂດຍອັດຕະໂນມັດ."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່ສາມາດເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ຖືກປິດໃຊ້ໃນໂໝດຄວາມມປອດໄພ."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ປະຫວັດ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ລຶບ"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ລຶບລ້າງທັງໝົດ"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ແອັບນີ້ບໍ່ຮອງຮັບຫຼາຍໜ້າຈໍ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ແອັບບໍ່ຮອງຮັບຫຼາຍໜ້າຈໍ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ການແຍກລວງຂວາງ"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"ສະແດງຢູ່ເທິງສຸດຂອງລາຍການແຈ້ງເຕືອນ, ແຈ້ງໄປໜ້າຈໍ ແລະ ອະນຸຍາດໃຫ້ໃຊ້ສຽງໄດ້"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ການຕັ້ງຄ່າເພີ່ມເຕີມ"</string>
<string name="notification_done" msgid="5279426047273930175">"ສຳເລັດແລ້ວ"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"ການຄວບຄຸມການແຈ້ງເຕືອນ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ສີ ແລະ ລັກສະນະ"</string>
<string name="night_mode" msgid="3540405868248625488">"ໂໝດກາງຄືນ"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ປັບໜ້າຈໍ"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດແບັດເຕີຣີ"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ຫຼຸດປະສິທິພາບການໃຊ້ງານ ແລະ ຂໍ້ມູນພື້ນຫຼັງ"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ປຸ່ມ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ກັບຄືນ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ຂຶ້ນ"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ລົງ"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ຊ້າຍ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ຂວາ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ເຄິ່ງກາງ"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ຫຼິ້ນ/ຢຸດຊົ່ວຄາວ"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ຢຸດ"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ຕໍ່ໄປ"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ກ່ອນໜ້າ"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ຣີວາຍກັບ"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ເລື່ອນໄປໜ້າ"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ລະບົບ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ໜ້າຫຼັກ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາກໍໃຊ້"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ເລື່ອນຂຶ້ນ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ເລື່ອນຊ້າຍ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ເລື່ອນຂວາ"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ກັບຫຼາຍໜ້າຈໍ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
index 911dcf9..6e36d3f 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"ກົດ "<b>"HOME"</b>" ຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"ແຕະປຸ່ມ HOME ຄ້າງໄວ້ເພື່ອຄວບຄຸມຮູບນ້ອຍ"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"ເຂົ້າໃຈແລ້ວ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"ປິດໄວ້"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4de42c0..f3b6842 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Dar <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Pranešimų nustatymai"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"„<xliff:g id="APP_NAME">%s</xliff:g>“ nustatymai"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Programa „<xliff:g id="APP">%s</xliff:g>“ išjungta saugos režimu."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Išvalyti"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Išvalyti viską"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ši programa nepalaiko kelių langų režimo"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Programa nepalaiko kelių langų režimo"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontalus skaidymas"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Rodyti pranešimų sąrašo viršuje, rodyti ekrane ir leisti skambėti"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Daugiau nustatymų"</string>
<string name="notification_done" msgid="5279426047273930175">"Atlikta"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ pranešimų valdikliai"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Spalva ir išvaizda"</string>
<string name="night_mode" msgid="3540405868248625488">"Naktinis režimas"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibruoti ekraną"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Mygtukas <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Pagrindinis"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Atgal"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Aukštyn"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Žemyn"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kairėn"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dešinėn"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centras"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabuliavimo klavišas"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Tarpas"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Įvesti"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Naikinimo klavišas"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Leisti / pristabdyti"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Sustabdyti"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Kitas"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Ankstesnis"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Sukti atgal"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Sukti pirmyn"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Ankstesnis puslapis"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Tolesnis puslapis"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ištrinti"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Pagrindinis"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Baigti"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Įterpti"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Skaičių režimas"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Klaviatūros skaitmenų sritis <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string>
@@ -561,4 +584,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Perkelti aukštyn"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Perkelti kairėn"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Perkelti dešinėn"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index 928b4c7..c8fce8a 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Kad vald. PIP, pal. pasp. m. "<b>"PAGRINDINIS"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Jei norite valdyti PIP, paspauskite ir palaikykite pagrindinio puslapio mygtuką"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Supratau"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Atsisakyti"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index f473971..8983cde 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -310,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Lietotne <xliff:g id="APP">%s</xliff:g> ir atspējota drošajā režīmā."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Vēsture"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Notīrīt"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Notīrīt visu"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Šajā lietotnē netiek atbalstīts vairāku logu režīms."</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Lietotnē netiek atbalstīts vairāku logu režīms"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontāls dalījums"</string>
@@ -500,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Samazina veiktspēju un fona datus."</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Poga <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Sākumvietas taustiņš"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Atpakaļ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Uz augšu"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Uz leju"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Pa kreisi"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Pa labi"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrā"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulēšanas taustiņš"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Atstarpe"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Ievadīšanas taustiņš"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Atpakaļatkāpes taustiņš"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Atskaņot/apturēt"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Apturēt"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nākamais"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Iepriekšējais"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Attīt atpakaļ"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Pārtīt uz priekšu"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Lapa uz augšu"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Lapa uz leju"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Dzēšanas taustiņš"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Sākumvietas taustiņš"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Beigvietas taustiņš"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Ievietošanas taustiņš"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Ciparslēga taustiņš"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Cipartastatūra <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistēma"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string>
@@ -558,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pārvietot uz augšu"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pārvietot pa kreisi"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pārvietot pa labi"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 1666273..954a9d0 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацијата е поставена со ГПС"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни барања за локација"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Исчисти ги сите известувања."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Поставки на известувања"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Поставки на <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранот ќе ротира автоматски."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> е оневозможен во безбеден режим."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Исчисти"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Исчисти ги сите"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Апликацијава не поддржува повеќе прозорци"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апликацијата не поддржува повеќе прозорци"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Раздели хоризонтално"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Прикажувај ги на врвот на списокот со известувања, ѕиркање на екранот и овозможи звук"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Повеќе поставки"</string>
<string name="notification_done" msgid="5279426047273930175">"Готово"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроли за известувања на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Боја и изглед"</string>
<string name="night_mode" msgid="3540405868248625488">"Ноќен режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Калибрирај го екранот"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ја намалува изведбата и податоците во заднина"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Копче <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Почетна страница"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрелка нагоре"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрелка надолу"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрелка налево"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрелка надесно"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центар"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Картичка"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Празно место"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Внеси"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Бришење наназад"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Пушти/Паузирај"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Сопри"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Следно"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Претходно"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Премотување наназад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Брзо премотување нанапред"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Страница нагоре"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Страница надолу"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Избриши"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Почетна страница"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Крај"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Вметни"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетна страница"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Неодамнешни"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Преместете нагоре"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Преместете налево"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Преместете надесно"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
index 10bf41f..2d6da0c 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Задржете "<b>"ДОМА"</b>" за кон. PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Притиснете и задржете го копчето ДОМА за контролирање PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрав"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Отфрли"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 882f189..1149147 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ലൊക്കേഷൻ സജ്ജീകരിച്ചത് GPS ആണ്"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ലൊക്കേഷൻ അഭ്യർത്ഥനകൾ സജീവമാണ്"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"എല്ലാ വിവരങ്ങളും മായ്ക്കുക."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"അറിയിപ്പ് ക്രമീകരണങ്ങൾ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ക്രമീകരണങ്ങൾ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"സ്ക്രീൻ യാന്ത്രികമായി തിരിയും."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"സുരക്ഷിത മോഡിൽ <xliff:g id="APP">%s</xliff:g> പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ചരിത്രം"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"മായ്ക്കുക"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"എല്ലാം മായ്ക്കുക"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ഒന്നിലധികം വിൻഡോകളെ ഈ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ഒന്നിലധികം വിൻഡോകളെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"അറിയിപ്പ് ലിസ്റ്റിന്റെ ഏറ്റവും മുകളിൽ കാണിക്കുക, ശബ്ദമുണ്ടാക്കുക"</string>
<string name="notification_more_settings" msgid="816306283396553571">"കൂടുതൽ ക്രമീകരണം"</string>
<string name="notification_done" msgid="5279426047273930175">"പൂർത്തിയായി"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"വർണ്ണവും രൂപഭാവവും"</string>
<string name="night_mode" msgid="3540405868248625488">"നൈറ്റ് മോഡ്"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ഡിസ്പ്ലേ കാലിബ്രേറ്റുചെയ്യുക"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്ക്കുന്നു"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"ഹോം"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ബാക്ക്"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"മുകളിലേക്ക്"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"താഴേക്ക്"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ഇടത്"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"വലത്"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"മധ്യം"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"ടാബ്"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"സ്പെയ്സ്"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"എന്റർ"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"ബാക്ക്സ്പെയ്സ്"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"നിർത്തുക"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"അടുത്തത്"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"മുമ്പത്തേത്"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"റിവൈൻഡ്"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ഫാസ്റ്റ് ഫോർവേഡ്"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"പേജ് അപ്പ്"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"പേജ് ഡൗൺ"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ഡിലീറ്റ്"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"ഹോം"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"എൻഡ്"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"ഇൻസേർട്ട്"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"നം ലോക്ക്"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"നംപാഡ് <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"സിസ്റ്റം"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"മുകളിലേക്ക് നീക്കുക"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ഇടത്തേക്ക് നീക്കുക"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"വലത്തേക്ക് നീക്കുക"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"മൾട്ടി-വിൻഡോയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
index c054eed..09fe4ce 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP നിയന്ത്രിക്കാൻ "<b>"ഹോം"</b>" പിടിക്കുക"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP നിയന്ത്രിക്കാൻ ഹോം ബട്ടൺ അമർത്തിപ്പിടിക്കുക"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"മനസ്സിലായി"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"ഡിസ്മിസ് ചെയ്യുക"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index b9ddad7..bafb558 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -234,8 +234,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS байршил"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Байршлын хүсэлтүүд идэвхтэй"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Мэдэгдлийн тохиргоо"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> тохиргоо"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Дэлгэц автоматаар эргэнэ."</string>
@@ -308,8 +307,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>-г аюулгүй горимд идэвхгүй болгосон."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Түүх"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Устгах"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Бүгдийг арилгах"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Энэ апп олон цонхыг дэмждэггүй"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апп олон цонхыг дэмждэггүй"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хэвтээ чиглэлд хуваах"</string>
@@ -478,8 +476,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Мэдэгдлийг жагсаалтын эхэнд яаралтай дуутай харуулах"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Бусад тохиргоо"</string>
<string name="notification_done" msgid="5279426047273930175">"Дууссан"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> мэдэгдлийн хяналт"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Өнгө, харагдах байдал"</string>
<string name="night_mode" msgid="3540405868248625488">"Шөнийн горим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Дэлгэцийг тохируулах"</string>
@@ -499,6 +496,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Гүйцэтгэл болон дэвсгэрийн датаг багасгадаг"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> товчлуур"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Нүүр хуудас"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Буцах"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Дээш"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Доош"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Зүүн"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Баруун"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Гол хэсэг"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Чихтэй хуудас"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Зай"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Оруулах"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Арилгах"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Тоглуулах/Түр зогсоох"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Зогсоох"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Дараах"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Өмнөх"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Буцааж хураах"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Хурдан урагшлуулах"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Хуудас дээш"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Хуудас доош"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Устгах"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Нүүр хуудас"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Төгсгөл"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Оруулах"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Тоо бичих горим"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Тоо бичих товчлуур <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string>
@@ -557,4 +580,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Дээш зөөх"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Зүүн тийш зөөх"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Баруун тийш зөөх"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Олон цонхтой үед апп ажиллахгүй байж болзошгүй"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
index 54f2282..ca522d3 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP-г удирдахын тулд "<b>"HOME"</b>" товчлуурыг дарна уу"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-г удирдахын тулд НҮҮР ХУУДАС товчлуурыг дараад хүлээнэ үү"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Ойлголоо"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Хаах"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index e65897c..00d65cd 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारे स्थान सेट केले"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान विनंत्या सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सर्व सूचना साफ करा."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"सूचना सेटिंग्ज"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिंग्ज"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वयंचलितपणे फिरेल."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> सुरक्षित-मोडमध्ये अक्षम केला आहे."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ करा"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सर्व साफ करा"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"हा अॅप एकाधिक-विंडोला समर्थन देत नाही"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"अॅप एकाधिक-विंडोला समर्थन देत नाही"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज विभाजित करा"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"सूचनांच्या शीर्षस्थानी दर्शवा, स्क्रीनवर पहा आणि ध्वनीस अनुमती द्या"</string>
<string name="notification_more_settings" msgid="816306283396553571">"अधिक सेटिंग्ज"</string>
<string name="notification_done" msgid="5279426047273930175">"पूर्ण झाले"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> सूचना नियंत्रणे"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"रंग आणि स्वरूप"</string>
<string name="night_mode" msgid="3540405868248625488">"रात्र मोड"</string>
<string name="calibrate_display" msgid="5974642573432039217">"प्रदर्शनाचे मापन करा"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"बटण <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"परत"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"वर"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"खाली"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"डावा"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"उजवा"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"मध्यवर्ती"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"टॅब"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"प्ले करा/विराम द्या"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"थांबा"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"पुढील"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"मागील"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"मागे न्या"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"पुढे करा"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"हटवा"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"घाला"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टीम"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"वर हलवा"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"डावीकडे हलवा"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"उजवीकडे हलवा"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings_tv.xml b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
index 6a29867..318e3e9 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP नियंत्रित करण्यासाठी "<b>"मुख्यपृष्ठ"</b>" धरून ठेवा"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP नियंत्रित करण्यासाठी मुख्यपृष्ठ बटण दाबा आणि धरून ठेवा"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"समजले"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"डिसमिस करा"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 432110c..68ce748 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tetapan pemberitahuan"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> tetapan"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dilumpuhkan dalam mod selamat."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Sejarah"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kosongkan"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kosongkan semua"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Apl ini tidak menyokong berbilang tetingkap"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Apl tidak menyokong berbilang tetingkap"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Mendatar Terpisah"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Tunjukkan pada bahagian atas senarai pemberitahuan, intai pada skrin dan benarkan bunyi"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Lagi tetapan"</string>
<string name="notification_done" msgid="5279426047273930175">"Selesai"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kawalan pemberitahuan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Warna dan penampilan"</string>
<string name="night_mode" msgid="3540405868248625488">"Mod malam"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Tentukur paparan"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangkan prestasi dan data latar belakang"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butang <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Skrin Utama"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Kembali"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Ke atas"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ke bawah"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ke kiri"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Ke kanan"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Tengah"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Undur ruang"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Main/Jeda"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Berhenti"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seterusnya"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Sebelumnya"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Mandir"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Mara Laju"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pad nombor <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Alih ke atas"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Alih ke kiri"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Alih ke kanan"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
index d358cc0..eb5af9e3 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Thn "<b>"SKRN UTMA"</b>" utk kwl PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Tekan dan tahan butang SKRIN UTAMA untuk mengawal PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ketepikan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 8994499..3cfc675 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ကို ဘေးကင်းလုံခြုံသည့်မုဒ်တွင် ပိတ်ထားပါသည်။"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"မှတ်တမ်း"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ရှင်းလင်းပါ"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"အားလုံး ရှင်းလင်းပါ"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ဤအက်ပ်သည် ဝင်းဒိုးများစွာဖွင့်ခြင်းကို ပံ့ပိုးမထားပါ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"အက်ပ်သည် ဝင်းဒိုးများစွာဖွင့်ခြင်းကို ပံ့ပိုးမထားပါ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"လုပ်ဆောင်မှု နှင့် နောက်ခံ ဒေတာကို လျော့နည်းစေပါသည်"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ခလုတ် <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"ပင်မ"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"နောက်သို့"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"အပေါ်"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"အောက်"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ဘယ်"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ညာ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ဌာန"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"တဘ်"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"နေရာခြားပါ"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"ဝင်ပါ"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"နောက်ပြန်ဖျက်ပါ"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ဖွင့်ပါ/ခဏရပ်ပါ"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ရပ်ပါ"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ရှေ့သို့"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"အနောက်သို့"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"နောက်သို့ရစ်ပါ"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ရှေ့သို့ရစ်ပါ"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"အပေါ်စာမျက်နှာသို့သွားပါ"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"အောက်စာမျက်နှာသို့သွားပါ"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ဖျက်ပါ"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"ပင်မ"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"ပြီးပါပြီ"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"ထည့်ပါ"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"နံပါတ်လော့ခ်ချပါ"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"နံပါတ်ခလုတ်ခုံ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"စနစ်"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"အပေါ်သို့ရွှေ့ပါ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ဘယ်ဘက်သို့ရွှေ့ပါ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ညာဘက်သို့ရွှေ့ပါ"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"အက်ပ်သည် ဝင်းဒိုးများတပြိုင်နက်ဖွင့်ခြင်းကို မပံ့ပိုးပါ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9ee29ab..0a21abc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er slått av i sikker modus."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Logg"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tøm"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tøm alt"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Denne appen har ikke støtte for flervindusmodus"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen har ikke støtte for flervindusmodus"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Del horisontalt"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduserer ytelsen og begrenser bakgrunnsdataene"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g>-knappen"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Startskjerm"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Tilbake"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Opp"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Venstre"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Høyre"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midttasten"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Mellomrom"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tilbaketasten"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spill av / sett på pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stopp"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Neste"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Forrige"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spol tilbake"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spol fremover"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Startskjerm"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> på talltastaturet"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flytt opp"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flytt mot venstre"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flytt mot høyre"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Appen fungerer kanskje ikke i Flervindusmodus"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 5b139d1..d2d4e97 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा स्थान सेट गरिएको"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोधहरू सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"अधिसूचना सेटिङ्हरू"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिङ्हरू"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रिन स्वतः घुम्ने छ।"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> लाई सुरक्षित-मोडमा असक्षम गरिएको छ।"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"मेटाउनुहोस्"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सबै हटाउनुहोस्"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"यस अनुप्रयोगले बहु-विन्डोलाई समर्थन गर्दैन"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"अनुप्रयोगले बहु-विन्डोलाई समर्थन गर्दैन"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"सूचना सूचीको शीर्षमा देखाउने, स्क्रिनमा चियाउने र ध्वनि निकाल्न अनुमति दिने"</string>
<string name="notification_more_settings" msgid="816306283396553571">"थप सेटिङहरू"</string>
<string name="notification_done" msgid="5279426047273930175">"सम्पन्न भयो"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> का सूचनाका लागि नियन्त्रणहरू"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"रंग र रूप"</string>
<string name="night_mode" msgid="3540405868248625488">"रात्री मोड"</string>
<string name="calibrate_display" msgid="5974642573432039217">"प्रदर्शनको स्तर मिलाउनुहोस्"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यसम्पादन र पृष्ठभूमि डेटा घटाउँछ"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> बटन"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"पछाडि"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"माथि"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"तल"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"बायाँ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"दायाँ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"केन्द्र"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"स्पेस"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"ब्याकस्पेस"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"प्ले गर्नुहोस्/पज गर्नुहोस्"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"रोक्नुहोस्"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"अर्को"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"अघिल्लो"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"रिवाइन्ड गर्नुहोस्"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"फास्ट फर्वार्ड"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"नमप्याड <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"प्रणाली"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"माथि सार्नुहोस्"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"बाँया सार्नुहोस्"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"दायाँ सार्नुहोस्"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"अनुप्रयोगले बहु-विन्डोमा काम नगर्न सक्छ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings_tv.xml b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
index 7234d3b..d9245d2 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP लाई नियन्त्रण गर्न "<b>"गृह"</b>" कुञ्जीलाई थिचिरहनुहोस्"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"IP लाई नियन्त्रण गर्न गृह बटनलाई थिची होल्ड गर्नुहोस्"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"बुझेँ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"खारेज गर्नुहोस्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b49cf66..42dea78 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is uitgeschakeld in de veilige modus"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Geschiedenis"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wissen"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alles wissen"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Deze app ondersteunt de modus voor meerdere vensters niet"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App ondersteunt meerdere vensters niet"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontaal splitsen"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Accubesparing niet beschikbaar tijdens opladen"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Accubesparing"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knop <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Terug"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Omhoog"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Omlaag"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Links"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Rechts"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midden"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Spatiebalk"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Afspelen/Onderbreken"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stoppen"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Volgende"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Vorige"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Terugspoelen"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Vooruitspoelen"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> op numeriek toetsenblok"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systeem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startpagina"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Omhoog"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Naar links"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Naar rechts"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index f67c51a..b58b2c8 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS ਵੱਲੋਂ ਸੈਟ ਕੀਤਾ ਨਿਰਧਾਰਿਤ ਸਥਾਨ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾ ਬੇਨਤੀਆਂ ਸਕਿਰਿਆ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਹਟਾਓ।"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ਸੈਟਿੰਗਾਂ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ਸਕ੍ਰੀਨ ਆਟੋਮੈਟਿਕਲੀ ਰੋਟੇਟ ਕਰੇਗੀ।"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ਖੋਜੋ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਸੁਰੱਖਿਅਤ-ਮੋਡ ਵਿੱਚ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ਇਤਿਹਾਸ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ਸਾਫ਼ ਕਰੋ"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ਸਭ ਸਾਫ਼ ਕਰੋ"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ਇਹ ਐਪ ਮਲਟੀ-ਵਿੰਡੋ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ਐਪ ਮਲਟੀ-ਵਿੰਡੋ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"ਸੂਚਨਾਵਾਂ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ, ਸਕ੍ਰੀਨ \'ਤੇ ਝਲਕ ਵਿਖਾਉਣ ਅਤੇ ਧੁਨੀ ਦੀ ਮਨਜ਼ੂਰੀ ਦਿਓ"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
<string name="notification_done" msgid="5279426047273930175">"ਹੋ ਗਿਆ"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"ਰੰਗ ਅਤੇ ਵਿਖਾਲਾ"</string>
<string name="night_mode" msgid="3540405868248625488">"ਰਾਤ ਮੋਡ"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ਡਿਸਪਲੇ ਨੂੰ ਕੈਲੀਬ੍ਰੇਟ ਕਰੋ"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਡੈਟੇ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ਬਟਨ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ਸਿਸਟਮ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ਉੱਪਰ ਲੈ ਜਾਓ"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ਖੱਬੇ ਲੈ ਜਾਓ"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ਸੱਜੇ ਲੈ ਜਾਓ"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings_tv.xml b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
index 78a5322..7cbda258 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP ਕੰਟਰੋਲ ਕਰਨ ਲਈ "<b>"ਹੋਮ"</b>" ਦਬਾਈ ਰੱਖੋ"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਹੋਮ ਬਟਨ ਨੂੰ ਦੱਬੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"ਸਮਝ ਲਿਆ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"ਖ਼ਾਰਜ ਕਰੋ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 12452f6..bb8f200 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ustawienia powiadomień"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ustawienia aplikacji <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacja <xliff:g id="APP">%s</xliff:g> została wyłączona w trybie bezpiecznym."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wyczyść"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Wyczyść wszystko"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacja nie obsługuje trybu wielu okien"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacja nie obsługuje trybu wielu okien"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podziel poziomo"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Pokazuj na początku listy powiadomień, wyświetlaj na ekranie i sygnalizuj dźwiękiem"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Więcej ustawień"</string>
<string name="notification_done" msgid="5279426047273930175">"Gotowe"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> – ustawienia powiadomień"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Kolor i wygląd"</string>
<string name="night_mode" msgid="3540405868248625488">"Tryb nocny"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibracja wyświetlacza"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Zmniejsza wydajność i ogranicza dane w tle"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Przycisk <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Wstecz"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"W górę"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"W dół"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"W lewo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"W prawo"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Do środka"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Spacja"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Odtwórz/wstrzymaj"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zatrzymaj"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Następny"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Poprzedni"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Przewiń do tyłu"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Przewiń do przodu"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Klawiatura numeryczna <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string>
@@ -561,4 +584,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Przesuń w górę"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Przesuń w lewo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Przesuń w prawo"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacja może nie działać w trybie wielu okien"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index 78bb18e..70be3d9 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Przytrzymaj "<b>"EKRAN GŁÓWNY"</b>", by sterować PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Przytrzymaj przycisk EKRAN GŁÓWNY, by sterować PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Zamknij"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 10d3181..dd9fbf0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"O app não é compatível com o modo de várias janelas"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar parcialmente na tela e permitir sons"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Mais configurações"</string>
<string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Cor e aparência"</string>
<string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrar tela"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Voltar"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centralizar"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Barra de espaço"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/pausar"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avançar"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar rapidamente"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index 6061af3..0827f9c7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Mantenha a tecla \"HOME\" pressionada para controlar o PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Dispensar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 7a2866d..a700215 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Definições de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Definições do <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"O <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicação não é compatível com várias janelas"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"A aplicação não é compatível com várias janelas"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar no ecrã e permitir som"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Mais definições"</string>
<string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controlos de notificações do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Cor e aspeto"</string>
<string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrar ecrã"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados de segundo plano"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Início"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Anterior"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Ao centro"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulação"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Espaço"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retrocesso"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/interromper"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seguinte"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Recuar"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Página para cima"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Página para baixo"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Eliminar"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Início"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fim"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserir"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 78d1352..2f465d2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Prima sem soltar o botão "<b>"HOME"</b>" para controlar o PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Prima sem soltar o botão HOME para controlar o PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Compreendi"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 10d3181..dd9fbf0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"O app não é compatível com o modo de várias janelas"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar parcialmente na tela e permitir sons"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Mais configurações"</string>
<string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Cor e aparência"</string>
<string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrar tela"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Voltar"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centralizar"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Barra de espaço"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/pausar"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avançar"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar rapidamente"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index 6061af3..0827f9c7 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Mantenha a tecla \"HOME\" pressionada para controlar o PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Dispensar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5f71c41..353f11c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -237,8 +237,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locație setată prin GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeți toate notificările."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setări pentru notificări"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Setări <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
@@ -311,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplicația <xliff:g id="APP">%s</xliff:g> este dezactivată în modul sigur."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Istoric"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ștergeți"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ștergeți-le pe toate"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Această aplicație nu acceptă ferestre multiple"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplicația nu acceptă ferestre multiple"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divizare pe orizontală"</string>
@@ -481,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Apar în partea de sus a listei cu notificări, se afișează pentru scurt timp pe ecran și se permite un sunet"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Mai multe setări"</string>
<string name="notification_done" msgid="5279426047273930175">"Terminat"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Opțiuni privind notificările pentru <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Culoare și aspect"</string>
<string name="night_mode" msgid="3540405868248625488">"Modul Noapte"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Calibrați afișarea"</string>
@@ -502,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce performanța și datele de fundal"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butonul <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"La început"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Înapoi"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"În sus"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"În jos"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"La stânga"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"La dreapta"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"În centru"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Spațiu"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Redați/Întrerupeți"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Opriți"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Înainte"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Înapoi"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Derulați înapoi"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Derulați rapid înainte"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"O pagină mai sus"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"O pagină mai jos"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ștergeți"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"La început"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"La final"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserați"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tasta numerică <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mutați în sus"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mutați spre stânga"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mutați spre dreapta"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index fcbfd07..9ef90dd 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Apăsați lung "<b>"ACASĂ"</b>" pentru a controla PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Apăsați lung butonul ECRAN DE PORNIRE pentru a controla PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Am înțeles"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Închideți"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ffb0a73..26d936a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Координаты по GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Есть активные запросы на определение местоположения"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки уведомлений"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки приложения \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" отключено в безопасном режиме."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Журнал"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистить"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистить все"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Приложение не поддерживает многооконный режим"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Приложение не поддерживает многооконный режим"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Разделить по горизонтали"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Показывать со звуком в начале списка уведомлений и поверх всех окон"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Другие настройки"</string>
<string name="notification_done" msgid="5279426047273930175">"Готово"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Управление оповещениями (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Цвета и стиль"</string>
<string name="night_mode" msgid="3540405868248625488">"Ночной режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Калибровка дисплея"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ограничивает производительность и фоновую передачу данных"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Главный экран"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрелка вверх"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрелка вниз"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрелка влево"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрелка вправо"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центральная стрелка"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Пробел"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Ввод"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Воспроизведение/пауза"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Стоп"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Далее"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перемотка назад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перемотка вперед"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифровая клавиатура <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string>
@@ -561,4 +584,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Поднять"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Сдвинуть влево"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Сдвинуть вправо"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложение не поддерживает многооконный режим"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index 309ce73..027cb1f 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Управляйте кадром в кадре, удерживая кнопку "<b>"ГЛАВНАЯ"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Управляйте режимом \"Кадр в кадре\", удерживая кнопку ГЛАВНАЯ"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"ОК"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Закрыть"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 84c2f1b..b47af0d 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS මඟින් ස්ථානය සකසා ඇත"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"පිහිටීම් ඉල්ලීම් සක්රියයි"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"දැනුම්දීම් සැකසීම්"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> සැකසීම්"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"තිරය ස්වයංක්රීයව කරකැවේ."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ආරක්ෂිත ප්රකාරය තුළ අබලයි."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ඉතිහාසය"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"හිස් කරන්න"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"සියල්ල හිස් කරන්න"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"මෙම යෙදුම බහු-කවුළුව සඳහා සහාය නොදක්වයි"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"යෙදුම බහු-කවුළුව සඳහා සහාය නොදක්වයි"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"තිරස්ව වෙන් කරන්න"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"දැනුම්දීම් ලැයිස්තුවෙහි ඉහළින්ම පෙන්වන්න, තිරයට එබිකම් කර ශබ්දයට ඉඩ දෙන්න"</string>
<string name="notification_more_settings" msgid="816306283396553571">"තව සැකසීම්"</string>
<string name="notification_done" msgid="5279426047273930175">"නිමයි"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> දැනුම්දීම් පාලන"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"වර්ණය සහ පෙනුම"</string>
<string name="night_mode" msgid="3540405868248625488">"රාත්රී ප්රකාරය"</string>
<string name="calibrate_display" msgid="5974642573432039217">"සංදර්ශකය ක්රමාංකනය කරන්න"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ක්රියාකාරිත්වය සහ පසුබිම් දත්ත අඩු කරන්න"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> බොත්තම"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home යතුර"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"ආපසු"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"උඩු"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"යටි"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"වම්"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"දකුණු"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"මැද"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab යතුර"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"ඉඩ යතුර"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter යතුර"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace යතුර"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ධාවනය කරන්න/විරාම කරන්න"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"නතර කරන්න"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ඊළඟ"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"පෙර"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"නැවත ඔතන්න"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"වේගයෙන් ඉදිරියට යන"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up යතුර"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down යතුර"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete යතුර"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home යතුර"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End යතුර"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert යතුර"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock යතුර"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> අංක පෑඩය"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"පද්ධතිය"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ඉහළට ගෙන යන්න"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"වමට ගෙන යන්න"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"දකුණට ගෙන යන්න"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"යෙදුම බහු-කවුළුව සමඟ ක්රියා නොකළ හැකිය."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings_tv.xml b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
index f3e95a1..3380754 100644
--- a/packages/SystemUI/res/values-si-rLK/strings_tv.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP පාලනයට "<b>"HOME"</b>" අල්ලාගන්න"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP පාලනය කිරීමට HOME බොත්තම ඔබා අල්ලාගෙන සිටින්න"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"හරි, තේරුණා"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"අස් කරන්න"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index e53b037..6c3b477 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavenia upozornení"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavenia aplikácie <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikácia <xliff:g id="APP">%s</xliff:g> je v núdzovom režime zakázaná."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"História"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazať"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazať všetko"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Táto aplikácia nepodporuje režim viacerých okien"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikácia nepodporuje režim viacerých okien"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Rozdeliť vodorovné"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Zobrazovať v hornej časti zoznamu upozornení, zobrazovať cez obrazovku a povoliť zvukový signál"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Ďalšie nastavenia"</string>
<string name="notification_done" msgid="5279426047273930175">"Hotovo"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Ovládacie prvky pre upozornenia z aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Farba a vzhľad"</string>
<string name="night_mode" msgid="3540405868248625488">"Nočný režim"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibrovať obrazovku"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Obmedzí výkonnosť a údaje na pozadí"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tlačidlo <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Domov"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Späť"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nahor"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Nadol"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Doľava"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Doprava"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Do stredu"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulátor"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Medzerník"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Prehrať/pozastaviť"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zastaviť"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nasledujúce"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Predchádzajúce"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Pretočiť späť"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Pretočiť dopredu"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Posunúť o stranu vyššie"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Posunúť o stranu nižšie"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Odstrániť"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Domov"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Ukončiť"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Vložiť"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Číselná klávesnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string>
@@ -561,4 +584,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Posunúť nahor"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Posunúť doľava"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Posunúť doprava"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
index 64fa0e8..cc48e07 100644
--- a/packages/SystemUI/res/values-sk/strings_tv.xml
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Režim PIP ovládajte pomocou tlačidla "<b>"PLOCHA"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Režim PIP ovládajte stlačením a podržaním tlačidla PLOCHA"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Dobre"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odmietnuť"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8cff73b1..359c909 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -238,8 +238,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"in <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavitve obvestil"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavitve aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
@@ -312,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je v varnem načinu onemogočena."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Zgodovina"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši vse"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacija ne podpira načina z več okni"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podpira načina z več okni"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Razdeli vodoravno"</string>
@@ -482,8 +480,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Prikaži na vrhu seznama obvestil, za hip pokaži predogled na zaslonu in dovoli zvok"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Več nastavitev"</string>
<string name="notification_done" msgid="5279426047273930175">"Dokončano"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrolniki obvestil za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Barva in videz"</string>
<string name="night_mode" msgid="3540405868248625488">"Nočni način"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Umerjanje zaslona"</string>
@@ -503,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omeji zmogljivost delovanja in prenos podatkov v ozadju"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Gumb <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Začetek"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Nazaj"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gor"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dol"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Levo"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Zavihek"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Preslednica"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Vnesi"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Premik nazaj"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Predvajaj/zaustavi"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Ustavi"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Naslednji"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prejšnji"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Previj nazaj"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Previj naprej"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Stran gor"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Stran dol"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Izbriši"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Začetek"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Konec"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Vstavi"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Številska tipkovnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string>
@@ -561,4 +584,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Premakni navzgor"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Premakni levo"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Premakni desno"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija morda ne deluje v načinu z več okni"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index 4d0576b..38f9e8e 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Pridr. "<b>"HOME"</b>" za up. n. PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Pridržite gumb HOME za upravljanje načina PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Razumem"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Opusti"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 35b4dc7..2448a4a 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vendndodhja është caktuar nga GPS-ja"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Kërkesat për vendodhje janë aktive"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Pastro të gjitha njoftimet."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cilësimet e njoftimeve"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cilësimet e <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrani do të rrotullohet automatikisht."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"kërko"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nuk mundi të nisej."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> është i çaktivizuar në modalitetin e sigurt."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historiku"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Pastro"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Pastroji të gjitha"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ky aplikacion nuk e mbështet modalitetin me shumë dritare"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacioni nuk e mbështet modalitetin me shumë dritare"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Ndaje horizontalisht"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Shfaqi në krye të listës së njoftimeve, shfaq vështrim të shpejtë në ekran dhe lësho një tingull"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Cilësime të tjera"</string>
<string name="notification_done" msgid="5279426047273930175">"U krye"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrollet e njoftimeve të <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Ngjyra dhe pamja"</string>
<string name="night_mode" msgid="3540405868248625488">"Modaliteti i natës"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibro ekranin"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butoni <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Kreu"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Prapa"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Lart"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Poshtë"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Majtas"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Djathtas"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Qendror"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Skedë"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Hapësirë"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Kthim prapa"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Luaj/pauzë"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Ndalo"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Përpara"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prapa"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rikthe me shpejtësi"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Përparo me shpejtësi"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Faqja lart"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Faqja poshtë"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Fshi"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Kreu"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fundi"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Fut"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Kyçja e numrave"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tastiera numerike <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistemi"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Kreu"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Të fundit"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Lëviz lart"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Lëviz majtas"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Lëviz djathtas"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacioni mund të mos punojë me funksionin me shumë dritare."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
index bcb53fc..672a119 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Mbaj shtypur "<b>"HOME"</b>" për të kontrolluar PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Shtyp dhe mbaj shtypur butonin HOME për të kontrolluar PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"E kuptova"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hiqe"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5bc07fa..a2a61db 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -237,8 +237,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Има активних захтева за локацију"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Подешавања обавештења"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Подешавања за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран ће се аутоматски ротирати."</string>
@@ -311,8 +310,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Апликација <xliff:g id="APP">%s</xliff:g> је онемогућена у безбедном режиму."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Обриши"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Обриши све"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ова апликација не подржава режим са више прозора"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апликација не подржава режим са више прозора"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Подели хоризонтално"</string>
@@ -481,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Приказују се у врху листе обавештења, накратко се приказују на екрану и емитују звук"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Још подешавања"</string>
<string name="notification_done" msgid="5279426047273930175">"Готово"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроле обавештења за апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Боја и изглед"</string>
<string name="night_mode" msgid="3540405868248625488">"Ноћни режим"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Калибришите екран"</string>
@@ -502,6 +499,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Смањује перформансе и позадинске податке"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Дугме <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Тастер Почетна"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Тастер Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Тастер са стрелицом нагоре"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Тастер са стрелицом надоле"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Тастер са стрелицом налево"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Тастер са стрелицом надесно"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Тастер са централном стрелицом"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Табулатор"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Тастер за размак"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Тастер за брисање уназад"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Тастер за репродукцију/паузирање"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Тастер за заустављање"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Тастер Следећа"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Тастер Претходна"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Тастер за премотавање уназад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Тастер за премотавање унапред"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Тастер за страницу нагоре"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Тастер за страницу надоле"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Тастер за брисање"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Тастер Почетна"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Тастер за крај"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Тастер за уметање"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Тастер <xliff:g id="NAME">%1$s</xliff:g> на нумеричкој тастатури"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Помери нагоре"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Помери улево"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Помери удесно"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
index a92374f..d822e4e 100644
--- a/packages/SystemUI/res/values-sr/strings_tv.xml
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109"><b>"ПОЧЕТНИ ЕКРАН"</b>" конт. PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Притисните и задржите дугме ПОЧЕТНИ ЕКРАН да бисте контролисали PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Важи"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Одбаци"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7e40ce0..a78841c 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> till"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Aviseringsinställningar"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Inställningar för <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> är inaktiverad i säkert läge."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Rensa"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Rensa alla"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Den här appen har inte stöd för flera fönster"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen har inte stöd för flera fönster"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dela horisontellt"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Visa högst upp i aviseringslistan och med snabbtitt på skärmen samt tillåt ljud"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Fler inställningar"</string>
<string name="notification_done" msgid="5279426047273930175">"Klar"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Inställningar för <xliff:g id="APP_NAME">%1$s</xliff:g>-aviseringar"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Färg och utseende"</string>
<string name="night_mode" msgid="3540405868248625488">"Nattläge"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Kalibrera skärmen"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Minskar prestanda och bakgrundsdata"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knappen <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Start"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Tillbaka"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Upp"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vänster"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Höger"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrera"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Flik"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Blanksteg"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Retur"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backsteg"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spela upp/Pausa"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Avsluta"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nästa"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Föregående"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spola tillbaka"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Snabbspola framåt"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Sida upp"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Sida ned"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Radera"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Start"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Slut"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Infoga"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numeriskt tangentbord <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flytta uppåt"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flytta åt vänster"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flytta åt höger"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Appen fungerar eventuellt inte i flerfönsterläge"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index 790ef76..0c0afc3 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Styr PIP med "<b>"startknappen"</b></string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Styr bild-i-bild genom att hålla ned startsideknappen"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorera"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index aa9ed8a..7351edc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Maombi ya eneo yanatumika"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mipangilio ya arifa"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mipangilio ya <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> imezimwa katika hali salama."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Futa"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Futa zote"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Programu hii haitumiki katika hali ya madirisha mengi"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Programu haitumiki katika hali ya madirisha mengi"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gawanya Mlalo"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Onyesha katika sehemu ya juu ya orodha ya arifa, chungulia kwenye skrini na uruhusu sauti"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Mipangilio zaidi"</string>
<string name="notification_done" msgid="5279426047273930175">"Nimemaliza"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Vidhibiti vya arifa za <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Rangi na mwonekano"</string>
<string name="night_mode" msgid="3540405868248625488">"Hali ya usiku"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Rekebisha onyesho"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Hupunguza data ya chini chini na utendaji"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Kitufe cha <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Nyuma"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Juu"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Chini"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kushoto"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Kulia"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Katikati"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Cheza/Sitisha"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Simamisha"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Inayofuata"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Iliyotangulia"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rudisha nyuma"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Sogeza mbele Haraka"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Mfumo"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Sogeza juu"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sogeza kushoto"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sogeza kulia"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
index bd29705..4875f73 100644
--- a/packages/SystemUI/res/values-sw/strings_tv.xml
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Shikilia kitufe cha "<b>"HOME"</b>" ili udhibiti PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Bonyeza na ushikilie kitufe cha HOME ili kudhibiti PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Nimeelewa"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ondoa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 3eb7565..cfa587b 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS அமைத்த இருப்பிடம்"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"இருப்பிடக் கோரிக்கைகள் இயக்கப்பட்டன"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"எல்லா அறிவிப்புகளையும் அழி."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"அறிவிப்பு அமைப்புகள்"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> அமைப்புகள்"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"திரை தானாகச் சுழலும்."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"பாதுகாப்புப் பயன்முறையில் <xliff:g id="APP">%s</xliff:g> முடக்கப்பட்டது."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"வரலாறு"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"அழி"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"அனைத்தையும் அழி"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"இந்தப் பயன்பாடு பல சாளர அம்சத்தை ஆதரிக்கவில்லை"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"பயன்பாடு பல சாளர அம்சத்தை ஆதரிக்காது"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"கிடைமட்டமாகப் பிரி"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"அறிவிப்புகள் பட்டியலின் மேற்பகுதியில், சில வினாடிகளுக்கு ஒலியுடன் திரையில் காட்டு"</string>
<string name="notification_more_settings" msgid="816306283396553571">"மேலும் அமைப்புகள்"</string>
<string name="notification_done" msgid="5279426047273930175">"முடிந்தது"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> அறிவிப்புக் கட்டுப்பாடுகள்"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"வண்ணமும் தோற்றமும்"</string>
<string name="night_mode" msgid="3540405868248625488">"இரவுப் பயன்முறை"</string>
<string name="calibrate_display" msgid="5974642573432039217">"திரையை அளவுத்திருத்தம் செய்"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"செயல்திறனையும் பின்புலத்தில் தரவு செயலாக்கப்படுவதையும் குறைக்கும்"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> பொத்தான்"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"ஹோம்"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"பேக்"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"மேலே"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"கீழே"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"இடது"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"வலது"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"நடு"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"டேப்"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"ஸ்பேஸ்"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"என்டர்"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"பேக்ஸ்பேஸ்"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"பிளே/பாஸ்"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ஸ்டாப்"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"நெக்ஸ்ட்"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ப்ரீவியஸ்"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ரீவைன்ட்"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ஃபாஸ்ட் பார்வேர்டு"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"பேஜ் அப்"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"பேஜ் டவுன்"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"டெலிட்"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"ஹோம்"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"என்ட்"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"இன்சர்ட்"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"நம்பர் லாக்"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"நம்பர் பேடு <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"முறைமை"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"மேலே நகர்த்து"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"இடப்புறம் நகர்த்து"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"வலப்புறம் நகர்த்து"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings_tv.xml b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
index e75d86a..7412e27 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIPஐக் கட்டுப்படுத்த, "<b>"முகப்பைப்"</b>" பிடித்திருக்கவும்"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIPஐக் கட்டுப்படுத்த, முகப்புப் பொத்தானை அழுத்திப் பிடிக்கவும்"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"சரி"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"நிராகரி"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 4a6e2d7..b04d074 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్లో నిలిపివేయబడింది."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"చరిత్ర"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"తీసివేయి"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"అన్నీ తీసివేయి"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ఈ అనువర్తనం బహుళ విండోలకు మద్దతు ఇవ్వదు"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"అనువర్తనం బహుళ విండోలకు మద్దతు ఇవ్వదు"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"సమతలంగా విభజించు"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"పనితీరుని మరియు నేపథ్య డేటాను తగ్గిస్తుంది"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"బటన్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"వెనుకకు"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"పైకి"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"కిందికి"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ఎడమ"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"కుడి"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"మధ్య"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"అంతరం"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ప్లే చేయి/పాజ్ చేయి"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ఆపివేయి"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"తదుపరి"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"మునుపటి"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"రివైండ్ చేయి"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"వేగంగా ఫార్వార్డ్ చేయి"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"నంబర్ ప్యాడ్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"సిస్టమ్"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"హోమ్"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ఇటీవలివి"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"పైకి తరలించు"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ఎడమవైపుకు తరలించు"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"కుడివైపుకు తరలించు"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"అనువర్తనం బహుళ విండోల రూపంలో పని చేయకపోవచ్చు"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 33e4346..31e7634 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"คำขอตำแหน่งที่มีการใช้งาน"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"การตั้งค่าการแจ้งเตือน"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"การตั้งค่า <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"หน้าจอจะหมุนโดยอัตโนมัติ"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ปิดใช้ในโหมดปลอดภัย"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"ประวัติ"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ล้าง"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ล้างทั้งหมด"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"แอปนี้ไม่สนับสนุนหลายหน้าต่าง"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"แอปไม่สนับสนุนหลายหน้าต่าง"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"แยกในแนวนอน"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"แสดงที่ด้านบนของรายการการแจ้งเตือน แสดงบนหน้าจอและให้ส่งเสียงได้"</string>
<string name="notification_more_settings" msgid="816306283396553571">"การตั้งค่าเพิ่มเติม"</string>
<string name="notification_done" msgid="5279426047273930175">"เสร็จสิ้น"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"ส่วนควบคุมการแจ้งเตือนของ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"สีและลักษณะที่ปรากฏ"</string>
<string name="night_mode" msgid="3540405868248625488">"โหมดกลางคืน"</string>
<string name="calibrate_display" msgid="5974642573432039217">"ปรับเทียบการแสดงผล"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"ลดประสิทธิภาพการทำงานและข้อมูลแบ็กกราวด์"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"ปุ่ม <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"กลับ"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ขึ้น"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ลง"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ซ้าย"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ขวา"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"กึ่งกลาง"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"แท็บ"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"วรรค"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"ลบถอยหลัง"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"เล่น/หยุดชั่วคราว"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"หยุด"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"ถัดไป"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ก่อนหน้า"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"กรอกลับ"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"กรอไปข้างหน้า"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"เลื่อนหน้าขึ้น"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"เลื่อนหน้าลง"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ลบ"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"แทรก"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"แผงตัวเลข <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ระบบ"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string>
@@ -560,4 +583,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"เลื่อนขึ้น"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"เลื่อนไปทางซ้าย"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"เลื่อนไปทางขวา"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"แอปอาจทำงานกับหลายหน้าต่างไม่ได้"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index b43078d..d7b26687 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"กด "<b>"HOME"</b>" ค้างไว้เพื่อควบคุม PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"กดปุ่ม HOME ค้างไว้เพื่อควบคุม PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"รับทราบ"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"ปิด"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 61eaa9d..c144b9b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktibo ang mga kahilingan ng lokasyon"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mga setting ng notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mg setting ng <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Naka-disable ang <xliff:g id="APP">%s</xliff:g> sa safe-mode."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"I-clear"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"I-clear lahat"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Hindi sinusuportahan ng app na ito ang multi-window"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Hindi sinusuportahan ng app na ito ang multi-window"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Ipakita sa itaas ng listahan ng mga notification, palitawin sa screen at payagang tumunog"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Higit pang mga setting"</string>
<string name="notification_done" msgid="5279426047273930175">"Tapos Na"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Mga kontrol sa notification ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Kulay at hitsura"</string>
<string name="night_mode" msgid="3540405868248625488">"Night mode"</string>
<string name="calibrate_display" msgid="5974642573432039217">"I-calibrate ang display"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Binabawasan ang pagganap at data sa background"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button na <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Ilipat pataas"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Ilipat pakaliwa"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Ilipat pakanan"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Maaaring hindi gumana ang app sa maraming window"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index 8d4b1b0..74fe314 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"I-hold ang "<b>"HOME"</b>" para makontrol ang PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Pindutin nang matagal ang button ng HOME upang makontrol ang PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"I-dismiss"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d5a8b9b..0b40840 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirim ayarları"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>, güvenli modda devre dışıdır."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Geçmiş"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sil"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tümünü temizle"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu uygulama, çoklu pencere kullanımını desteklemiyor"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Uygulama, çoklu pencere kullanımını desteklemiyor"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Yatay Ayırma"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Bildirim listesinin üstünde göster, ekrana getir ve sesli bildirime izin ver"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Diğer ayarlar"</string>
<string name="notification_done" msgid="5279426047273930175">"Bitti"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildirim denetimleri"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Renk ve görünüm"</string>
<string name="night_mode" msgid="3540405868248625488">"Gece modu"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Ekranı kalibre et"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı ve arka plan verilerini azaltır"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> düğmesi"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Geri"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Yukarı"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Aşağı"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sol"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Sağ"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Orta"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Sekme"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Boşluk"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Geri tuşu"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Oynat/Duraklat"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Durdur"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sonraki"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Önceki"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Geri Sar"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"İleri Sar"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Sayfa Yukarı"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Sayfa Aşağı"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> Sayısal Tuş Takımı"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Yukarı taşı"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sola taşı"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sağa taşı"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index a5be6a2..57da7fb 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP\'yi kontrol etmek için "<b>"ANA EKRAN"</b>"\'ı basılı tutun"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP\'yi kontrol etmek için ANA EKRAN düğmesini basılı tutun"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Kapat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 398dea1..d6da864 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -311,8 +311,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Додаток <xliff:g id="APP">%s</xliff:g> вимкнено в безпечному режимі."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Історія"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистити"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистити все"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Цей додаток не підтримує багатоекранний режим"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Додаток не підтримує багатоекранний режим"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Розділити горизонтально"</string>
@@ -501,6 +500,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим економії заряду акумулятора недоступний під час заряджання"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим економії заряду акумулятора"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Знижується продуктивність і обмежується обмін даними у фоновому режимі"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрілка вгору"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрілка вниз"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрілка вліво"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрілка вправо"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центр"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Пробіл"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Відтворити/призупинити"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Зупинити"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Далі"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перемотати назад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перемотати вперед"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Сторінка вгору"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Сторінка вниз"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string>
@@ -559,4 +584,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Перемістити вгору"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Перемістити ліворуч"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Перемістити праворуч"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Додаток може не працювати в багатовіконному режимі"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 7b5013f..cc7b8d2 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مقام متعین کیا گیا بذریعہ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"مقام کی درخواستیں فعال ہیں"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"سبھی اطلاعات صاف کریں۔"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> +"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"اطلاع کی ترتیبات"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ترتیبات"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"اسکرین خود بخود گردش کرے گی۔"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"محفوظ موڈ میں <xliff:g id="APP">%s</xliff:g> غیر فعال ہوتی ہے۔"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"سرگزشت"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"صاف کریں"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"سبھی کو صاف کریں"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"یہ ایپ ملٹی ونڈو کی معاونت نہیں کرتی"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ایپ ملٹی ونڈز کی معاونت نہیں کرتی"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"بلحاظ افقی الگ کریں"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"اطلاعات کی فہرست پر سب سے اوپر دکھائیں، اسکرین پر دکھائیں اور آواز کی اجازت دیں"</string>
<string name="notification_more_settings" msgid="816306283396553571">"مزید ترتیبات"</string>
<string name="notification_done" msgid="5279426047273930175">"ہوگیا"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے نوٹیفکیشن کنٹرولز"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"رنگ اور ظہور"</string>
<string name="night_mode" msgid="3540405868248625488">"رات موڈ"</string>
<string name="calibrate_display" msgid="5974642573432039217">"نشان زد ڈسپلے"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"کارکردگی اور پس منظر کا ڈیٹا کم کر دیتا ہے"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"بٹن <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"پیچھے"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"اوپر"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"نیچے"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"بائیں"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"دائیں"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"سینٹر"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"چلائیں/موقوف کریں"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"روکیں"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"اگلا"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"گزشتہ"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ریوائینڈ کریں"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"تیزی سے فارورڈ کریں"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"نمبر پیڈ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سسٹم"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string>
@@ -559,4 +582,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"اوپر منتقل کریں"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"بائیں منتقل کریں"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"دائیں منتقل کریں"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
index aff14b2..78de898 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"PIP کنٹرول کرنے کیلئے "<b>"ہوم"</b>" پکڑے رکھیں"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"PIP کنٹرول کرنے کیلئے ہوم بٹن دبائیں اور پکڑے رکھیں"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"سمجھ آ گئی"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"برخاست کریں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index bd606c2..eb4f402 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS yordamida manzilni o‘rnatish"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Joylashuv so‘rovlari yoniq"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Barcha eslatmalarni tozalash."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirishnoma sozlamalari"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> sozlamalari"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik buriladi."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"Xavfsiz rejimda <xliff:g id="APP">%s</xliff:g> ilovasi o‘chirib qo‘yildi."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Jurnal"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tozalash"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Barchasini tozalash"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu ilova ko‘p oynali rejimni qo‘llab-quvvatlamaydi"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Bu ilova ko‘p oynali rejimni qo‘llab-quvvatlamaydi"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Bildirishnomalar ro‘yxatining boshida va barcha oynalar ustida ovoz bilan ko‘rsatilsin"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Boshqa sozlamalar"</string>
<string name="notification_done" msgid="5279426047273930175">"Tayyor"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildirishnomalarini boshqarish"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Rang va ko‘rinishi"</string>
<string name="night_mode" msgid="3540405868248625488">"Tungi rejim"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Ekranni kalibrlash"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Unumdorlik pasayadi va fonda internetdan foydalanish cheklanadi"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> tugmasi"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Bosh ekran"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Orqaga"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Tepaga qaragan ko‘rsatkichli chiziq"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Pastga qaragan ko‘rsatkichli chiziq"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Chapga qaragan ko‘rsatkichli chiziq"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"O‘ngga qaragan ko‘rsatkichli chiziq"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Markaziy ko‘rsatkichli chiziq"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Bo‘sh joy"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Ijro/Pauza"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"To‘xtatish"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Keyingi"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Avvalgi"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Orqaga o‘tkazish"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Oldinga o‘tkazish"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Raqamli tugma: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Tizim"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string>
@@ -560,4 +583,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Tepaga siljitish"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Chapga siljitish"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"O‘ngga siljitish"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
index 3a4d176..9300aaa 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"“Kadr ichida kadr” rejimini boshqarish uchun "<b>"BOSHI"</b>" tugmasini bosib turing"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"“Kadr ichida kadr” rejimini boshqarish uchun BOSHIGA tugmasini bosib turing"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Yopish"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index edd0a8b..94eb62f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cài đặt thông báo"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cài đặt <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> bị tắt ở chế độ an toàn."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Lịch sử"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Xóa"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Xóa tất cả"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ứng dụng này không hỗ trợ chế độ nhiều cửa sổ"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Ứng dụng không hỗ trợ chế độ nhiều cửa sổ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Phân tách ngang"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Hiển thị ở đầu danh sách thông báo, hiển thị trên màn hình và phát ra âm thanh"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Cài đặt khác"</string>
<string name="notification_done" msgid="5279426047273930175">"Xong"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"Điều khiển thông báo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Màu sắc và giao diện"</string>
<string name="night_mode" msgid="3540405868248625488">"Chế độ ban đêm"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Hiệu chỉnh hiển thị"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Giảm hiệu suất và dữ liệu nền"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Nút <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Quay lại"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Lên"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Xuống"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Trái"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Phải"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Giữa"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Dấu cách"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Phát/Tạm dừng"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Dừng"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Tiếp theo"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Trước"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Tua lại"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Tua nhanh"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Cuối"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Bàn phím số <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Hệ thống"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Chuyển lên"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Di chuyển sang trái"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Di chuyển sang phải"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Ứng dụng có thể không hoạt động với nhiều cửa sổ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index 7a5e34a..b781503 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Giữ "<b>"HOME"</b>" để đ.khiển PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Bấm và giữ nút HOME để điều khiển PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Loại bỏ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 23fb020..614ae70 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"已通过GPS确定位置"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"应用发出了有效位置信息请求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知设置"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>设置"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
@@ -310,8 +309,8 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>已在安全模式下停用。"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"历史记录"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+ <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+ <skip />
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"此应用不支持多窗口模式"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"应用不支持多窗口模式"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -480,8 +479,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"在通知列表顶部显示,同时在屏幕上短暂显示,并允许发出提示音"</string>
<string name="notification_more_settings" msgid="816306283396553571">"更多设置"</string>
<string name="notification_done" msgid="5279426047273930175">"完成"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>通知控件"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"颜色和外观"</string>
<string name="night_mode" msgid="3540405868248625488">"夜间模式"</string>
<string name="calibrate_display" msgid="5974642573432039217">"校准显示画面"</string>
@@ -501,6 +499,58 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用节电助手"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"节电助手"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低性能并限制后台流量"</string>
+ <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+ <skip />
+ <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+ <skip />
+ <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+ <skip />
+ <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+ <skip />
+ <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+ <skip />
+ <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+ <skip />
+ <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+ <skip />
+ <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+ <skip />
+ <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+ <skip />
+ <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+ <skip />
+ <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+ <skip />
+ <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+ <skip />
+ <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+ <skip />
+ <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+ <skip />
+ <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+ <skip />
+ <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+ <skip />
+ <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+ <skip />
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系统"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
@@ -559,4 +609,6 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"上移"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"左移"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"右移"</string>
+ <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index 2bfe478..77d3bff 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主屏幕"</b>"按钮即可控制画中画功能"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"按住主屏幕按钮即可控制画中画功能"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"关闭"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 902cf71..f5cdcf8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -309,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」已在安全模式中停用。"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"記錄"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"此應用程式不支援多視窗模式"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"應用程式不支援多視窗模式"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -499,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景數據傳輸"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 鍵"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"返回"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"向上"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"向下"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"向左"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"向右"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"箭咀中心"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"空格"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"輸入 (Enter)"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"播放/暫停"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"下一首"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"上一首"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"倒帶"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"向前快轉"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"上一頁"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"下一頁"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"刪除"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"頁面頂端"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"頁面底端"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"插入"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"數字鎖定"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵盤 <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string>
@@ -557,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"向上移"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"向左移"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"向右移"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多重視窗下運作"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ea32930..fea3cc7 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"有位置資訊要求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>設定"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」在安全模式中為停用狀態。"</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"紀錄"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"這個應用程式不支援多視窗模式"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"應用程式不支援多視窗模式"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"顯示在通知清單頂端,同時短暫顯示在畫面上並發出音效"</string>
<string name="notification_more_settings" msgid="816306283396553571">"更多設定"</string>
<string name="notification_done" msgid="5279426047273930175">"完成"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」通知控制項"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"顏色和外觀"</string>
<string name="night_mode" msgid="3540405868248625488">"夜間模式"</string>
<string name="calibrate_display" msgid="5974642573432039217">"校正顯示畫面"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景資料傳輸"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 按鈕"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home 鍵"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"返回"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"向上鍵"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"向下鍵"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"向左鍵"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"向右鍵"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"中央鍵"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab 鍵"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"空格鍵"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter 鍵"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace 鍵"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"播放/暫停"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"下一個"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"上一個"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"倒轉"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"快轉"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up 鍵"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down 鍵"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete 鍵"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home 鍵"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End 鍵"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert 鍵"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock 鍵"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵 <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"向上移"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"向左移"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"向右移"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多視窗模式下運作"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index a6744e7..4420d87 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"按住「主畫面」"<b></b>"按鈕即可控制子母畫面"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"按住「主畫面」按鈕即可控制子母畫面"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"我知道了"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"關閉"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9f8f298..e94c687 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -236,8 +236,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Izicelo zendawo ziyasebenza"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
- <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
- <skip />
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Izilungiselelo zesaziso"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> izilungiselelo"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
@@ -310,8 +309,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"I-<xliff:g id="APP">%s</xliff:g> ikhutshaziwe kumodi yokuphepha."</string>
- <string name="recents_history_button_label" msgid="5153358867807604821">"Umlando"</string>
- <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sula"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Sula konke"</string>
<string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Lolu hlelo lokusebenza alusekeli amawindi amaningi"</string>
<string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Uhlelo lokusebenza alusekeli amawindi amaningi"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Hlukanisa okuvundlile"</string>
@@ -480,8 +478,7 @@
<string name="notification_importance_max" msgid="5806278962376556491">"Bonisa phezulu kohlu lwezaziso, beka phezu kwesikrini futhi uvumele umsindo"</string>
<string name="notification_more_settings" msgid="816306283396553571">"Izilungiselelo eziningi"</string>
<string name="notification_done" msgid="5279426047273930175">"Kwenziwe"</string>
- <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
- <skip />
+ <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> izilawuli zasaziso"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Umbala nokubonakala"</string>
<string name="night_mode" msgid="3540405868248625488">"Imodi yasebusuku"</string>
<string name="calibrate_display" msgid="5974642573432039217">"Sika isibonisi"</string>
@@ -501,6 +498,32 @@
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
<string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sehlisa ukusebenza nedatha yasemuva"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Inkinobho <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Ekhaya"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Emuva"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Phezulu"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Phansi"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kwesobunxele"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Kwesokudla"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Maphakathi"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Ithebhu"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Isikhala"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Faka"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Isikhala"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Dlala/Misa okwesikhashana"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Misa"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Okulandelayo"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Okwangaphambilini"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Buyisela emuva"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Iya phambili ngokushesha"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Ikhasi phezulu"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Ikhasi phansi"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Susa"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Ekhaya"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"Phelisa"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Faka"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Izinombolo"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Phedi yezinombolo <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Isistimu"</string>
<string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string>
@@ -559,4 +582,5 @@
<string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Iya phezulu"</string>
<string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Iya kwesokunxele"</string>
<string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Iya kwesokudla"</string>
+ <string name="forced_resizable_info_text" msgid="7591061837558867999">"Uhlelo lokusebenza kungenzeka lungasebenzi namawindi amaningi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
index 5fb063d..1904237 100644
--- a/packages/SystemUI/res/values-zu/strings_tv.xml
+++ b/packages/SystemUI/res/values-zu/strings_tv.xml
@@ -26,6 +26,5 @@
<string name="pip_hold_home" msgid="340086535668778109">"Bamba "<b>"IKHAYA"</b>" ukuze ulawule i-PIP"</string>
<string name="pip_onboarding_description" msgid="2882896641362814195">"Cindezela futhi ubambe inkinobho EKHAYA ukuze ulawule i-PIP"</string>
<string name="pip_onboarding_button" msgid="3957426748484904611">"Ngiyezwa"</string>
- <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
- <skip />
+ <string name="recents_tv_dismiss" msgid="3555093879593377731">"Cashisa"</string>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 88230bc..d1faa4a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -179,7 +179,8 @@
<dimen name="qs_date_collapsed_text_size">14sp</dimen>
<dimen name="qs_date_text_size">16sp</dimen>
<dimen name="qs_header_gear_translation">16dp</dimen>
- <dimen name="qs_page_indicator_size">12dp</dimen>
+ <dimen name="qs_page_indicator_width">16dp</dimen>
+ <dimen name="qs_page_indicator_height">8dp</dimen>
<dimen name="qs_tile_icon_size">24dp</dimen>
<dimen name="qs_tile_text_size">12sp</dimen>
<dimen name="qs_tile_divider_height">1dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 25ecd888..a523a41 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1532,4 +1532,32 @@
<!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
<string name="forced_resizable_info_text">App may not work with multi-window</string>
+
+ <!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>, <xliff:g id="tile_name" example="Wi-Fi">%2$s</xliff:g>. Double tap to edit.</string>
+
+ <!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_add_tile_label"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g>. Double tap to add.</string>
+
+ <!-- Accessibility description of a place to drop a tile while editing positions [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_position_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>. Double tap to select.</string>
+
+ <!-- Accessibility description of option to move QS tile [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_move_tile">Move <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
+
+ <!-- Accessibility description of option to remove QS tile [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_remove_tile">Remove <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
+
+ <!-- Accessibility action when QS tile is added [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_added"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is added to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+
+ <!-- Accessibility action when QS tile is removed [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_removed"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is removed</string>
+
+ <!-- Accessibility action when QS tile is moved [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_moved"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> moved to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+
+ <!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
+ <string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
index 4845425..087f61e 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
@@ -452,7 +452,7 @@
boolean pctOpaque = false;
float pctX = 0, pctY = 0;
String pctText = null;
- if (!mPluggedIn && level > mCriticalLevel && mShowPercent) {
+ if (!mPluggedIn && !mPowerSaveEnabled && level > mCriticalLevel && mShowPercent) {
mTextPaint.setColor(getColorForLevel(level));
mTextPaint.setTextSize(height *
(SINGLE_DIGIT_PERCENT ? 0.75f
@@ -480,7 +480,7 @@
mShapePath.op(mClipPath, Path.Op.INTERSECT);
c.drawPath(mShapePath, mBatteryPaint);
- if (!mPluggedIn) {
+ if (!mPluggedIn && !mPowerSaveEnabled) {
if (level <= mCriticalLevel) {
// draw the warning text
final float x = mWidth * 0.5f;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 522d533..109a456 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -183,14 +183,16 @@
return;
}
+ boolean isPowerSaver = mPowerManager.isPowerSaveMode();
if (!plugged
+ && !isPowerSaver
&& (bucket < oldBucket || oldPlugged)
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& bucket < 0) {
// only play SFX when the dialog comes up or the bucket changes
final boolean playSound = bucket != oldBucket || oldPlugged;
mWarnings.showLowBatteryWarning(playSound);
- } else if (plugged || (bucket > oldBucket && bucket > 0)) {
+ } else if (isPowerSaver || plugged || (bucket > oldBucket && bucket > 0)) {
mWarnings.dismissLowBatteryWarning();
} else {
mWarnings.updateLowBatteryWarning();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
index 1200266..ba07bf4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
@@ -1,86 +1,219 @@
package com.android.systemui.qs;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.util.AttributeSet;
-import android.view.Gravity;
+import android.util.Log;
import android.view.View;
-import android.widget.LinearLayout;
-
+import android.view.ViewGroup;
+import android.widget.ImageView;
import com.android.systemui.R;
-public class PageIndicator extends LinearLayout {
+import java.util.ArrayList;
- private final int mPageIndicatorSize;
+public class PageIndicator extends ViewGroup {
+
+ private static final String TAG = "PageIndicator";
+ private static final boolean DEBUG = false;
+
+ private static final long ANIMATION_DURATION = 250;
+
+ // The size of a single dot in relation to the whole animation.
+ private static final float SINGLE_SCALE = .4f;
+
+ private static final float MINOR_ALPHA = .3f;
+
+ private final ArrayList<Integer> mQueuedPositions = new ArrayList<>();
+
+ private final int mPageIndicatorWidth;
+ private final int mPageIndicatorHeight;
+ private final int mPageDotWidth;
+
+ private int mPosition = -1;
+ private boolean mAnimating;
public PageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
- setGravity(Gravity.CENTER);
- mPageIndicatorSize =
- (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_size);
+ mPageIndicatorWidth =
+ (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_width);
+ mPageIndicatorHeight =
+ (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_height);
+ mPageDotWidth = (int) (mPageIndicatorWidth * SINGLE_SCALE);
}
public void setNumPages(int numPages) {
+ setVisibility(numPages > 1 ? View.VISIBLE : View.INVISIBLE);
+ if (mAnimating) {
+ Log.w(TAG, "setNumPages during animation");
+ }
while (numPages < getChildCount()) {
removeViewAt(getChildCount() - 1);
}
while (numPages > getChildCount()) {
- SinglePageIndicator v = new SinglePageIndicator(mContext);
- v.setAmount(0);
- addView(v, new LayoutParams(mPageIndicatorSize, mPageIndicatorSize));
+ ImageView v = new ImageView(mContext);
+ v.setImageResource(R.drawable.minor_a_b);
+ addView(v, new LayoutParams(mPageIndicatorWidth, mPageIndicatorHeight));
}
+ // Refresh state.
+ setIndex(mPosition >> 1);
}
public void setLocation(float location) {
int index = (int) location;
- location -= index;
+ int position = index << 1 | ((location != index) ? 1 : 0);
+ if (DEBUG) Log.d(TAG, "setLocation " + location + " " + index + " " + position);
+ int lastPosition = mPosition;
+ if (mQueuedPositions.size() != 0) {
+ lastPosition = mQueuedPositions.get(mQueuedPositions.size() - 1);
+ }
+ if (position == lastPosition) return;
+ if (mAnimating) {
+ if (DEBUG) Log.d(TAG, "Queueing transition to " + Integer.toHexString(position));
+ mQueuedPositions.add(position);
+ return;
+ }
+
+ setPosition(position);
+ }
+
+ private void setPosition(int position) {
+ if (isVisibleToUser() && Math.abs(mPosition - position) == 1) {
+ animate(mPosition, position);
+ } else {
+ if (DEBUG) Log.d(TAG, "Skipping animation " + isVisibleToUser() + " " + mPosition
+ + " " + position);
+ setIndex(position >> 1);
+ }
+ mPosition = position;
+ }
+
+ private void setIndex(int index) {
final int N = getChildCount();
for (int i = 0; i < N; i++) {
- float amount = 0;
- if (i == index) {
- amount = 1 - location;
- } else if (i == index + 1) {
- amount = location;
+ ImageView v = (ImageView) getChildAt(i);
+ // Clear out any animation positioning.
+ v.setTranslationX(0);
+ v.setImageResource(R.drawable.major_a_b);
+ v.setAlpha(getAlpha(i == index));
+ }
+ }
+
+ private void animate(int from, int to) {
+ if (DEBUG) Log.d(TAG, "Animating from " + Integer.toHexString(from) + " to "
+ + Integer.toHexString(to));
+ int fromIndex = from >> 1;
+ int toIndex = to >> 1;
+
+ // Set the position of everything, then we will manually control the two views involved
+ // in the animation.
+ setIndex(fromIndex);
+
+ boolean fromTransition = (from & 1) != 0;
+ boolean isAState = fromTransition ? from > to : from < to;
+ int firstIndex = Math.min(fromIndex, toIndex);
+ int secondIndex = Math.max(fromIndex, toIndex);
+ if (secondIndex == firstIndex) {
+ secondIndex++;
+ }
+ ImageView first = (ImageView) getChildAt(firstIndex);
+ ImageView second = (ImageView) getChildAt(secondIndex);
+ // Lay the two views on top of each other.
+ second.setTranslationX(first.getX() - second.getX());
+
+ playAnimation(first, getTransition(fromTransition, isAState, false));
+ first.setAlpha(getAlpha(false));
+
+ playAnimation(second, getTransition(fromTransition, isAState, true));
+ second.setAlpha(getAlpha(true));
+
+ mAnimating = true;
+ }
+
+ private float getAlpha(boolean isMajor) {
+ return isMajor ? 1 : MINOR_ALPHA;
+ }
+
+ private void playAnimation(ImageView imageView, int res) {
+ final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getContext().getDrawable(res);
+ imageView.setImageDrawable(avd);
+ avd.forceAnimationOnUI();
+ avd.start();
+ // TODO: Figure out how to user an AVD animation callback instead, which doesn't
+ // seem to be working right now...
+ postDelayed(mAnimationDone, ANIMATION_DURATION);
+ }
+
+ private int getTransition(boolean fromB, boolean isMajorAState, boolean isMajor) {
+ if (isMajor) {
+ if (fromB) {
+ if (isMajorAState) {
+ return R.drawable.major_b_a_animation;
+ } else {
+ return R.drawable.major_b_c_animation;
+ }
+ } else {
+ if (isMajorAState) {
+ return R.drawable.major_a_b_animation;
+ } else {
+ return R.drawable.major_c_b_animation;
+ }
}
- ((SinglePageIndicator) getChildAt(i)).setAmount(amount);
+ } else {
+ if (fromB) {
+ if (isMajorAState) {
+ return R.drawable.minor_b_c_animation;
+ } else {
+ return R.drawable.minor_b_a_animation;
+ }
+ } else {
+ if (isMajorAState) {
+ return R.drawable.minor_c_b_animation;
+ } else {
+ return R.drawable.minor_a_b_animation;
+ }
+ }
}
}
- // This could be done with a circle drawable and an ImageView, but this seems
- // easier for now.
- public static class SinglePageIndicator extends View {
- private static final int MIN_ALPHA = 0x4d;
- private static final int MAX_ALPHA = 0xff;
-
- private static final float MIN_SIZE = .55f;
- private static final float MAX_SIZE = .7f;
-
- private final Paint mPaint;
- private float mSize;
-
- public SinglePageIndicator(Context context) {
- super(context);
- mPaint = new Paint();
- mPaint.setColor(0xffffffff);
- mPaint.setAlpha(MAX_ALPHA);
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int N = getChildCount();
+ if (N == 0) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
}
-
- public void setAmount(float amount) {
- mSize = amount * (MAX_SIZE - MIN_SIZE) + MIN_SIZE;
- int alpha = (int) (amount * (MAX_ALPHA - MIN_ALPHA)) + MIN_ALPHA;
- mPaint.setAlpha(alpha);
- postInvalidate();
+ final int widthChildSpec = MeasureSpec.makeMeasureSpec(mPageIndicatorWidth,
+ MeasureSpec.EXACTLY);
+ final int heightChildSpec = MeasureSpec.makeMeasureSpec(mPageIndicatorHeight,
+ MeasureSpec.EXACTLY);
+ for (int i = 0; i < N; i++) {
+ getChildAt(i).measure(widthChildSpec, heightChildSpec);
}
+ int width = (mPageIndicatorWidth - mPageDotWidth) * N + mPageDotWidth;
+ setMeasuredDimension(width, mPageIndicatorHeight);
+ }
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int N = getChildCount();
+ if (N == 0) {
+ return;
+ }
+ for (int i = 0; i < N; i++) {
+ int left = (mPageIndicatorWidth - mPageDotWidth) * i;
+ getChildAt(i).layout(left, 0, mPageIndicatorWidth + left, mPageIndicatorHeight);
+ }
+ }
+
+ private final Runnable mAnimationDone = new Runnable() {
@Override
- public void draw(Canvas canvas) {
- int minDimen = Math.min(getWidth(), getHeight()) / 2;
- float radius = mSize * minDimen;
- float x = getWidth() / 2f;
- float y = getHeight() / 2f;
- canvas.drawCircle(x, y, radius, mPaint);
+ public void run() {
+ if (DEBUG) Log.d(TAG, "onAnimationEnd - queued: " + mQueuedPositions.size());
+ mAnimating = false;
+ if (mQueuedPositions.size() != 0) {
+ setPosition(mQueuedPositions.remove(0));
+ }
}
- }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 24b45cc..fd43aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -36,7 +36,6 @@
@Override
public void onPageSelected(int position) {
if (mPageIndicator == null) return;
- mPageIndicator.setLocation(position);
if (mPageListener != null) {
mPageListener.onPageChanged(position == 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 815c679..0b6eaba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -41,7 +41,7 @@
private static final String MOVE_FULL_ROWS = "sysui_qs_move_whole_rows";
public static final float EXPANDED_TILE_DELAY = .7f;
- private static final float LAST_ROW_EXPANDED_DELAY = .84f;
+ private static final float LAST_ROW_EXPANDED_DELAY = .86f;
private final ArrayList<View> mAllViews = new ArrayList<>();
private final ArrayList<View> mTopFiveQs = new ArrayList<>();
@@ -139,7 +139,9 @@
int count = 0;
int[] loc1 = new int[2];
int[] loc2 = new int[2];
+ int lastXDiff = 0;
int lastYDiff = 0;
+ int lastX = 0;
clearAnimationState();
mAllViews.clear();
@@ -155,10 +157,12 @@
// Quick tiles.
QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile);
+ lastX = loc1[0];
getRelativePosition(loc1, quickTileView.getIcon(), mQsContainer);
getRelativePosition(loc2, tileIcon, mQsContainer);
final int xDiff = loc2[0] - loc1[0];
final int yDiff = loc2[1] - loc1[1];
+ lastXDiff = loc1[0] - lastX;
lastYDiff = yDiff;
// Move the quick tile right from its location to the new one.
translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff);
@@ -177,9 +181,20 @@
mAllViews.add(tileIcon);
mAllViews.add(quickTileView);
} else if (mFullRows && isIconInAnimatedRow(count)) {
+ // TODO: Refactor some of this, it shares a lot with the above block.
+ // Move the last tile position over by the last difference between quick tiles.
+ // This makes the extra icons seems as if they are coming from positions in the
+ // quick panel.
+ loc1[0] += lastXDiff;
+ getRelativePosition(loc2, tileIcon, mQsContainer);
+ final int xDiff = loc2[0] - loc1[0];
+ final int yDiff = loc2[1] - loc1[1];
+
firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0);
- translationYBuilder.addFloat(label, "translationY", -lastYDiff, 0);
- translationYBuilder.addFloat(tileIcon, "translationY", -lastYDiff, 0);
+ translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0);
+ translationYBuilder.addFloat(label, "translationY", -yDiff, 0);
+ translationYBuilder.addFloat(tileIcon, "translationY", -yDiff, 0);
+
mAllViews.add(tileIcon);
} else {
lastRowBuilder.addFloat(tileView, "alpha", 0, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 5b05e84..43ebe04 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -140,6 +140,8 @@
public void notifyCustomizeChanged() {
// The customize state changed, so our height changed.
updateBottom();
+ mQSPanel.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
+ mHeader.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
// Let the panel know the position changed and it needs to update where notifications
// and whatnot are.
mPanelView.onQsHeightChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 42e98aa..1659888 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -294,6 +294,8 @@
}
}
+ public abstract CharSequence getTileLabel();
+
protected final class H extends Handler {
private static final int ADD_CALLBACK = 1;
private static final int CLICK = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 03c2a0b..353c6b6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -14,7 +14,10 @@
package com.android.systemui.qs.customize;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
import android.content.Context;
+import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
@@ -27,7 +30,10 @@
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.systemui.R;
@@ -37,6 +43,7 @@
import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
import com.android.systemui.statusbar.phone.QSTileHost;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
import java.util.ArrayList;
import java.util.List;
@@ -49,21 +56,27 @@
private static final int TYPE_TILE = 0;
private static final int TYPE_EDIT = 1;
+ private static final int TYPE_ACCESSIBLE_DROP = 2;
private final Context mContext;
private final Handler mHandler = new Handler();
private final List<TileInfo> mTiles = new ArrayList<>();
private final ItemTouchHelper mItemTouchHelper;
+ private final AccessibilityManager mAccessibilityManager;
private int mDividerIndex;
+ private boolean mNeedsFocus;
private List<String> mCurrentSpecs;
private List<TileInfo> mOtherTiles;
private List<TileInfo> mAllTiles;
private Holder mCurrentDrag;
+ private boolean mAccessibilityMoving;
+ private int mAccessibilityFromIndex;
public TileAdapter(Context context) {
mContext = context;
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mItemTouchHelper = new ItemTouchHelper(mCallbacks);
setHasStableIds(true);
}
@@ -130,6 +143,9 @@
@Override
public int getItemViewType(int position) {
+ if (mAccessibilityMoving && position == mDividerIndex - 1) {
+ return TYPE_ACCESSIBLE_DROP;
+ }
if (mTiles.get(position) == null) {
return TYPE_EDIT;
}
@@ -140,7 +156,7 @@
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
final Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
- if (viewType == 1) {
+ if (viewType == TYPE_EDIT) {
return new Holder(inflater.inflate(R.layout.qs_customize_divider, parent, false));
}
FrameLayout frame = (FrameLayout) inflater.inflate(R.layout.qs_customize_tile_frame, parent,
@@ -155,22 +171,157 @@
}
@Override
- public void onBindViewHolder(final Holder holder, int position) {
+ public void onBindViewHolder(final Holder holder, final int position) {
if (holder.getItemViewType() == TYPE_EDIT) {
((TextView) holder.itemView.findViewById(android.R.id.title)).setText(
mCurrentDrag != null ? R.string.drag_to_remove_tiles
: R.string.drag_to_add_tiles);
return;
}
+ if (holder.getItemViewType() == TYPE_ACCESSIBLE_DROP) {
+ holder.mTileView.setClickable(true);
+ holder.mTileView.setFocusable(true);
+ holder.mTileView.setFocusableInTouchMode(true);
+ holder.mTileView.setVisibility(View.VISIBLE);
+ holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ holder.mTileView.setContentDescription(mContext.getString(
+ R.string.accessibility_qs_edit_position_label, position + 1));
+ holder.mTileView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ selectPosition(position, v);
+ }
+ });
+ if (mNeedsFocus) {
+ // Wait for this to get laid out then set its focus.
+ holder.mTileView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ holder.mTileView.removeOnLayoutChangeListener(this);
+ holder.mTileView.requestFocus();
+ }
+ });
+ mNeedsFocus = false;
+ }
+ return;
+ }
TileInfo info = mTiles.get(position);
+
+ if (position > mDividerIndex) {
+ info.state.contentDescription = mContext.getString(
+ R.string.accessibility_qs_edit_add_tile_label, info.state.label);
+ } else if (mAccessibilityMoving) {
+ info.state.contentDescription = mContext.getString(
+ R.string.accessibility_qs_edit_position_label, position + 1);
+ } else {
+ info.state.contentDescription = mContext.getString(
+ R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
+ }
holder.mTileView.onStateChanged(info.state);
+
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
+ final boolean selectable = !mAccessibilityMoving || position < mDividerIndex;
+ holder.mTileView.setClickable(selectable);
+ holder.mTileView.setFocusable(selectable);
+ holder.mTileView.setImportantForAccessibility(selectable
+ ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+ if (selectable) {
+ holder.mTileView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mAccessibilityMoving) {
+ selectPosition(position, v);
+ } else {
+ if (position < mDividerIndex) {
+ showAccessibilityDialog(position, v);
+ } else {
+ startAccessibleDrag(position);
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private void selectPosition(int position, View v) {
+ // Remove the placeholder.
+ mTiles.remove(mDividerIndex--);
+ mAccessibilityMoving = false;
+ move(mAccessibilityFromIndex, position, v);
+ notifyDataSetChanged();
+ }
+
+ private void showAccessibilityDialog(final int position, final View v) {
+ TileInfo info = mTiles.get(position);
+ CharSequence[] options = new CharSequence[] {
+ mContext.getString(R.string.accessibility_qs_edit_move_tile, info.state.label),
+ mContext.getString(R.string.accessibility_qs_edit_remove_tile, info.state.label),
+ };
+ AlertDialog dialog = new Builder(mContext)
+ .setItems(options, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == 0) {
+ startAccessibleDrag(position);
+ } else {
+ move(position, mDividerIndex, v);
+ }
+ }
+ }).setNegativeButton(android.R.string.cancel, null)
+ .create();
+ SystemUIDialog.setShowForAllUsers(dialog, true);
+ SystemUIDialog.applyFlags(dialog);
+ dialog.show();
+ }
+
+ private void startAccessibleDrag(int position) {
+ mAccessibilityMoving = true;
+ mNeedsFocus = true;
+ mAccessibilityFromIndex = position;
+ // Add placeholder for last slot.
+ mTiles.add(mDividerIndex++, null);
+ notifyDataSetChanged();
}
public SpanSizeLookup getSizeLookup() {
return mSizeLookup;
}
+ private boolean move(int from, int to, View v) {
+ if (to > mDividerIndex) {
+ if (from >= mDividerIndex) {
+ return false;
+ }
+ }
+ CharSequence fromLabel = mTiles.get(from).state.label;
+ move(from, to, mTiles);
+ mDividerIndex = mTiles.indexOf(null);
+ notifyItemChanged(from);
+ notifyItemMoved(from, to);
+ CharSequence announcement;
+ if (to >= mDividerIndex) {
+ announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed,
+ fromLabel);
+ } else if (from >= mDividerIndex) {
+ announcement = mContext.getString(R.string.accessibility_qs_edit_tile_added,
+ fromLabel, (to + 1));
+ } else {
+ announcement = mContext.getString(R.string.accessibility_qs_edit_tile_moved,
+ fromLabel, (to + 1));
+ }
+ v.announceForAccessibility(announcement);
+ return true;
+ }
+
+ private <T> void move(int from, int to, List<T> list) {
+ list.add(from > to ? to : to + 1, list.get(from));
+ list.remove(from > to ? from + 1 : from);
+ }
+
public class Holder extends ViewHolder {
private QSTileView mTileView;
@@ -286,20 +437,7 @@
public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
- if (to > mDividerIndex) {
- if (from >= mDividerIndex) {
- return false;
- }
- }
- move(from, to, mTiles);
- mDividerIndex = mTiles.indexOf(null);
- notifyItemMoved(from, to);
- return true;
- }
-
- private <T> void move(int from, int to, List<T> list) {
- list.add(from > to ? to : to + 1, list.get(from));
- list.remove(from > to ? from + 1 : from);
+ return move(from, to, target.itemView);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index d95d3ef..bbc8856 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -33,7 +33,6 @@
import com.android.systemui.qs.QSTile.DrawableIcon;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.statusbar.phone.QSTileHost;
-import com.android.systemui.tuner.TunerService;
import java.util.ArrayList;
import java.util.Collection;
@@ -75,6 +74,8 @@
public void run() {
final QSTile.State state = tile.newTileState();
tile.getState().copyTo(state);
+ // Ignore the current state and get the generic label instead.
+ state.label = tile.getTileLabel();
mainHandler.post(new Runnable() {
@Override
public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 9156f3a..6114573 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -221,6 +221,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return getState().label;
+ }
+
+ @Override
protected void handleUpdateState(State state, Object arg) {
Drawable drawable = mTile.getIcon().loadDrawable(mContext);
int tileState = mTile.getState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 89f1985b..5f5a87e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -76,6 +76,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.airplane_mode);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
final boolean airplaneMode = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 2e87525..6ddd46e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -106,6 +106,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.battery);
+ }
+
+ @Override
protected void handleUpdateState(State state, Object arg) {
int level = (arg != null) ? (Integer) arg : mLevel;
String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 80f667c..1fef8f1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -96,6 +96,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_bluetooth_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final boolean enabled = mController.isBluetoothEnabled();
final boolean connected = mController.isBluetoothConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index e0ad002..bea1e15 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -108,6 +108,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_cast_title);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_cast_title);
state.value = false;
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 5f87741..55b00b5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -101,6 +101,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_cellular_detail_title);
+ }
+
+ @Override
protected void handleUpdateState(SignalState state, Object arg) {
CallbackInfo cb = (CallbackInfo) arg;
if (cb == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index a608316..416132e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -85,6 +85,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_inversion_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
final boolean enabled = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 74b3fdc..35aff21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -57,6 +57,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.data_saver);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.value = arg instanceof Boolean ? (Boolean) arg
: mDataSaverController.isDataSaverEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 8b22868..11efd56 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -128,6 +128,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_dnd_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
final boolean newValue = zen != Global.ZEN_MODE_OFF;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index a01a9a5..69e71bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -87,6 +87,16 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_flashlight_label);
+ }
+
+ @Override
+ protected void handleLongClick() {
+ handleClick();
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
if (!mFlashlightController.isAvailable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index da93120..bf5b22c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -74,6 +74,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_hotspot_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index bb5ff8e..2a2cc46 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -119,6 +119,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return getState().label;
+ }
+
+ @Override
protected void handleUpdateState(State state, Object arg) {
Intent intent = (Intent) arg;
if (intent == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index b1d1c77..6286f5e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -89,6 +89,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_location_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
final boolean locationEnabled = mController.isLocationEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index d80ca10..38b3706 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -80,6 +80,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return getState().label;
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
if (mController == null) return;
final boolean rotationLocked = arg != null ? (Boolean) arg
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index f1066c1..5b4279c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -73,6 +73,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return getState().label;
+ }
+
+ @Override
protected void handleUpdateState(State state, Object arg) {
final Pair<String, Drawable> p = arg != null ? (Pair<String, Drawable>) arg : mLastUpdate;
if (p != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7ee795f..65154f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -119,6 +119,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_wifi_label);
+ }
+
+ @Override
protected void handleUpdateState(SignalState state, Object arg) {
if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
CallbackInfo cb = (CallbackInfo) arg;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 421a2cf..2c5f7d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -82,6 +82,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_work_mode_label);
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
if (arg instanceof Boolean) {
state.value = (Boolean) arg;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 9cba93b..b89c2f6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -73,6 +73,7 @@
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.AnimationProps;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -285,6 +286,9 @@
registerReceiver(mSystemBroadcastReceiver, filter);
getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
+
+ // Reload the stack view
+ reloadStackView();
}
@Override
@@ -297,15 +301,17 @@
}
@Override
- public void onEnterAnimationComplete() {
- super.onEnterAnimationComplete();
- EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+
+ // Reload the stack view
+ reloadStackView();
}
- @Override
- protected void onResume() {
- super.onResume();
-
+ /**
+ * Reloads the stack views upon launching Recents.
+ */
+ private void reloadStackView() {
// If the Recents component has preloaded a load plan, then use that to prevent
// reconstructing the task stack
RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -328,38 +334,21 @@
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
loader.loadTasks(this, loadPlan, loadOpts);
TaskStack stack = loadPlan.getTaskStack();
- mRecentsView.onResume(mIsVisible, false /* multiWindowChange */, stack);
+ mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
+ mRecentsView.updateStack(stack);
- // Animate the SystemUI scrims into view
- Task launchTarget = stack.getLaunchTarget();
- int taskCount = stack.getTaskCount();
- int launchTaskIndexInStack = launchTarget != null
- ? stack.indexOfStackTask(launchTarget)
- : 0;
- boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
- boolean animateNavBarScrim = !launchState.launchedWhileDocking;
- mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+ // Update the nav bar scrim, but defer the animation until the enter-window event
+ boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
+ updateNavBarScrim(animateNavBarScrim, null);
- // If this is a new instance from a configuration change, then we have to manually trigger
- // the enter animation state, or if recents was relaunched by AM, without going through
- // the normal mechanisms
+ // If this is a new instance relaunched by AM, without going through the normal mechanisms,
+ // then we have to manually trigger the enter animation state
boolean wasLaunchedByAm = !launchState.launchedFromHome &&
!launchState.launchedFromApp;
- if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+ if (wasLaunchedByAm) {
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
- mRecentsView.getViewTreeObserver().addOnPreDrawListener(
- new ViewTreeObserver.OnPreDrawListener() {
-
- @Override
- public boolean onPreDraw() {
- mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
- EventBus.getDefault().post(new RecentsDrawnEvent());
- return true;
- }
- });
-
// Keep track of whether we launched from the nav bar button or via alt-tab
if (launchState.launchedWithAltTab) {
MetricsLogger.count(this, "overview_trigger_alttab", 1);
@@ -369,6 +358,10 @@
// Keep track of whether we launched from an app or from home
if (launchState.launchedFromApp) {
+ Task launchTarget = stack.getLaunchTarget();
+ int launchTaskIndexInStack = launchTarget != null
+ ? stack.indexOfStackTask(launchTarget)
+ : 0;
MetricsLogger.count(this, "overview_source_app", 1);
// If from an app, track the stack index of the app in the stack (for affiliated tasks)
MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
@@ -377,6 +370,7 @@
}
// Keep track of the total stack task count
+ int taskCount = mRecentsView.getStack().getTaskCount();
MetricsLogger.histogram(this, "overview_task_count", taskCount);
// After we have resumed, set the visible state until the next onStop() call
@@ -384,6 +378,29 @@
}
@Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // Notify of the next draw
+ mRecentsView.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+
+ @Override
+ public boolean onPreDraw() {
+ mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+ EventBus.getDefault().post(new RecentsDrawnEvent());
+ return true;
+ }
+ });
+ }
+
+ @Override
protected void onPause() {
super.onPause();
@@ -395,7 +412,34 @@
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- EventBus.getDefault().send(new ConfigurationChangedEvent());
+ // Update the nav bar for the current orientation
+ updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
+
+ EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */));
+ }
+
+ @Override
+ public void onMultiWindowChanged(boolean inMultiWindow) {
+ super.onMultiWindowChanged(inMultiWindow);
+ EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */));
+
+ if (mRecentsView != null) {
+ // Reload the task stack completely
+ RecentsConfiguration config = Recents.getConfiguration();
+ RecentsActivityLaunchState launchState = config.getLaunchState();
+ RecentsTaskLoader loader = Recents.getTaskLoader();
+ RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
+ loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
+
+ RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
+ loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
+ loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
+ loader.loadTasks(this, loadPlan, loadOpts);
+
+ mRecentsView.updateStack(loadPlan.getTaskStack());
+ }
+
+ EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
}
@Override
@@ -454,28 +498,6 @@
}
@Override
- public void onMultiWindowChanged(boolean inMultiWindow) {
- super.onMultiWindowChanged(inMultiWindow);
- EventBus.getDefault().send(new ConfigurationChangedEvent());
-
- // Reload the task stack completely
- RecentsConfiguration config = Recents.getConfiguration();
- RecentsActivityLaunchState launchState = config.getLaunchState();
- RecentsTaskLoader loader = Recents.getTaskLoader();
- RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
- loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
-
- RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
- loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
- loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
- loader.loadTasks(this, loadPlan, loadOpts);
-
- mRecentsView.onResume(mIsVisible, true /* multiWindowChange */, loadPlan.getTaskStack());
-
- EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
- }
-
- @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_TAB: {
@@ -697,4 +719,18 @@
});
return true;
}
+
+ /**
+ * Updates the nav bar scrim.
+ */
+ private void updateNavBarScrim(boolean animateNavBarScrim, AnimationProps animation) {
+ // Animate the SystemUI scrims into view
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ int taskCount = mRecentsView.getStack().getTaskCount();
+ boolean hasNavBarScrim = (taskCount > 0) && !ssp.hasTransposedNavBar();
+ mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+ if (animateNavBarScrim && animation != null) {
+ mScrimViews.animateNavBarScrimVisibility(true, animation);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index ab3b79e..7161053 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -29,12 +29,9 @@
public boolean launchedWithAltTab;
public boolean launchedFromApp;
- public boolean launchedFromAppDocked;
public boolean launchedFromHome;
- public boolean launchedReuseTaskStackViews;
- public boolean launchedHasConfigurationChanged;
public boolean launchedViaDragGesture;
- public boolean launchedWhileDocking;
+ public boolean launchedViaDockGesture;
public int launchedToTaskId;
public int launchedNumVisibleTasks;
public int launchedNumVisibleThumbnails;
@@ -42,23 +39,10 @@
public void reset() {
launchedFromHome = false;
launchedFromApp = false;
- launchedFromAppDocked = false;
launchedToTaskId = -1;
launchedWithAltTab = false;
- launchedHasConfigurationChanged = false;
launchedViaDragGesture = false;
- launchedWhileDocking = false;
- }
-
- /** Called when the configuration has changed, and we want to reset any configuration specific
- * members. */
- public void updateOnConfigurationChange() {
- // Reset this flag on configuration change to ensure that we recreate new task views
- launchedReuseTaskStackViews = false;
- // Set this flag to indicate that the configuration has changed since Recents last launched
- launchedHasConfigurationChanged = true;
- launchedViaDragGesture = false;
- launchedWhileDocking = false;
+ launchedViaDockGesture = false;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 2afb09a..73c6e6e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -47,11 +47,6 @@
// Launch states
public RecentsActivityLaunchState mLaunchState = new RecentsActivityLaunchState();
- // TODO: Values determined by the current context, needs to be refactored into something that is
- // agnostic of the activity context, but still calculable from the Recents component for
- // the transition into recents
- public boolean hasTransposedNavBar;
-
// Since the positions in Recents has to be calculated globally (before the RecentsActivity
// starts), we need to calculate some resource values ourselves, instead of relying on framework
// resources.
@@ -79,25 +74,10 @@
}
/**
- * Updates the configuration based on the current state of the system
- */
- void update(Rect systemInsets) {
- hasTransposedNavBar = systemInsets.right > 0;
- }
-
- /**
* Returns the activity launch state.
* TODO: This will be refactored out of RecentsConfiguration.
*/
public RecentsActivityLaunchState getLaunchState() {
return mLaunchState;
}
-
- /**
- * Called when the configuration has changed, and we want to reset any configuration specific
- * members.
- */
- public void updateOnConfigurationChange() {
- mLaunchState.updateOnConfigurationChange();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index fce120a..ffc037d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -43,7 +43,6 @@
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.EventBus.Event;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.ForcedResizableEvent;
@@ -140,7 +139,6 @@
protected Context mContext;
protected Handler mHandler;
TaskStackListenerImpl mTaskStackListener;
- protected boolean mCanReuseTaskStackViews = true;
boolean mDraggingInRecents;
boolean mLaunchedWhileDocking;
@@ -209,9 +207,6 @@
public void onConfigurationChanged() {
reloadHeaderBarLayout();
updateHeaderBarLayout(null /* stack */);
- // Don't reuse task stack views if the configuration changes
- mCanReuseTaskStackViews = false;
- Recents.getConfiguration().updateOnConfigurationChange();
}
/**
@@ -441,7 +436,7 @@
}
// Launch the task
- ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.title, launchOpts);
+ ssp.startActivityFromRecents(mContext, toTask.key, toTask.title, launchOpts);
}
/**
@@ -513,7 +508,7 @@
MetricsLogger.count(mContext, "overview_affiliated_task_launch", 1);
// Launch the task
- ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.title, launchOpts);
+ ssp.startActivityFromRecents(mContext, toTask.key, toTask.title, launchOpts);
}
public void showNextAffiliatedTask() {
@@ -592,9 +587,6 @@
calculateWindowStableInsets(systemInsets, windowRect);
windowRect.offsetTo(0, 0);
- // Update the configuration for the current state
- Recents.getConfiguration().update(systemInsets);
-
TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
mTaskStackBounds);
@@ -605,8 +597,7 @@
if (stack != null) {
stackLayout.initialize(windowRect, taskStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
- mDummyStackView.setTasks(stack, false /* notifyStackChanges */,
- false /* relayoutTaskStack */, false /* multiWindowChange */);
+ mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
}
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
if (!taskViewBounds.equals(mLastTaskViewBounds)) {
@@ -715,7 +706,7 @@
TaskStackViewScroller stackScroller = stackView.getScroller();
stackView.updateLayoutAlgorithm(true /* boundScroll */);
- stackView.updateToInitialState();
+ stackView.updateToInitialState(true /* scrollToInitialState */);
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
@@ -782,7 +773,7 @@
// Get the transform for the running task
stackView.updateLayoutAlgorithm(true /* boundScroll */);
- stackView.updateToInitialState();
+ stackView.updateToInitialState(true /* scrollToInitialState */);
mTmpTransform = stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
stackView.getScroller().getStackScroll(), mTmpTransform, null);
return mTmpTransform;
@@ -859,15 +850,12 @@
// Update the launch state
launchState.launchedFromHome = false;
launchState.launchedFromApp = mLaunchedWhileDocking;
+ launchState.launchedViaDockGesture = mLaunchedWhileDocking;
launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
- launchState.launchedFromAppDocked = mLaunchedWhileDocking;
launchState.launchedWithAltTab = mTriggeredFromAltTab;
- launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
- launchState.launchedHasConfigurationChanged = false;
launchState.launchedViaDragGesture = mDraggingInRecents;
- launchState.launchedWhileDocking = mLaunchedWhileDocking;
if (!animate) {
startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1));
@@ -915,7 +903,6 @@
} else {
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
}
- mCanReuseTaskStackViews = true;
EventBus.getDefault().send(new RecentsActivityStartingEvent());
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
index 0ad4681..c234c34 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
@@ -22,5 +22,10 @@
* This is sent when the Recents activity configuration has changed.
*/
public class ConfigurationChangedEvent extends EventBus.AnimatedEvent {
- // Simple event
+
+ public final boolean fromMultiWindow;
+
+ public ConfigurationChangedEvent(boolean fromMultiWindow) {
+ this.fromMultiWindow = fromMultiWindow;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 1e624fd..1a4b40f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -18,6 +18,7 @@
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
@@ -77,6 +78,7 @@
import com.android.systemui.R;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.RecentsImpl;
+import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.tv.RecentsTvImpl;
import com.android.systemui.recents.model.ThumbnailData;
@@ -284,7 +286,7 @@
int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery,
ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
- ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS |
+ ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK |
ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS |
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
ActivityManager.RECENT_INCLUDE_PROFILES |
@@ -962,11 +964,20 @@
}
/** Starts an activity from recents. */
- public boolean startActivityFromRecents(Context context, int taskId, String taskName,
+ public boolean startActivityFromRecents(Context context, Task.TaskKey taskKey, String taskName,
ActivityOptions options) {
if (mIam != null) {
try {
- mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle());
+ if (taskKey.stackId == DOCKED_STACK_ID) {
+ // We show non-visible docked tasks in Recents, but we always want to launch
+ // them in the fullscreen stack.
+ if (options == null) {
+ options = ActivityOptions.makeBasic();
+ }
+ options.setLaunchStackId(FULLSCREEN_WORKSPACE_STACK_ID);
+ }
+ mIam.startActivityFromRecents(
+ taskKey.id, options == null ? null : options.toBundle());
return true;
} catch (Exception e) {
Log.e(TAG, context.getString(R.string.recents_launch_error_message, taskName), e);
@@ -1064,6 +1075,16 @@
}
}
+ /**
+ * Returns whether the device has a transposed nav bar (on the right of the screen) in the
+ * current display orientation.
+ */
+ public boolean hasTransposedNavBar() {
+ Rect insets = new Rect();
+ getStableInsets(insets);
+ return insets.right > 0;
+ }
+
private final class H extends Handler {
private static final int ON_TASK_STACK_CHANGED = 1;
private static final int ON_ACTIVITY_PINNED = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index dbb692c..82c81ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -274,7 +274,9 @@
new TaskKeyLruCache.EvictionCallback() {
@Override
public void onEntryEvicted(Task.TaskKey key) {
- mActivityInfoCache.remove(key.getComponent());
+ if (key != null) {
+ mActivityInfoCache.remove(key.getComponent());
+ }
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index a930791..5a2507d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -220,6 +220,11 @@
*/
void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
+
+ /**
+ * Notifies when tasks in the stack have been updated.
+ */
+ void onStackTasksUpdated(TaskStack stack);
}
/**
@@ -560,14 +565,19 @@
mStackTaskList.set(allTasks);
mRawTaskList = allTasks;
+ // Update the affiliated groupings
+ createAffiliatedGroupings(context);
+
// Only callback for the newly added tasks after this stack has been updated
int addedTaskCount = addedTasks.size();
for (int i = 0; i < addedTaskCount; i++) {
mCb.onStackTaskAdded(this, addedTasks.get(i));
}
- // Update the affiliated groupings
- createAffiliatedGroupings(context);
+ // Notify that the task stack has been updated
+ if (notifyStackChanges) {
+ mCb.onStackTasksUpdated(this);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 58d2da7..134b90c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -313,7 +313,7 @@
RecentsActivityLaunchState launchState = config.getLaunchState();
boolean wasLaunchedByAm = !launchState.launchedFromHome &&
!launchState.launchedFromApp;
- if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+ if (wasLaunchedByAm) {
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index aa27325..c1b47dc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -24,10 +24,13 @@
import android.graphics.Rect;
import android.os.SystemClock;
import android.os.UserHandle;
-import com.android.systemui.recents.*;
+
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsActivityLaunchState;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.tv.views.TaskCardView;
@@ -101,8 +104,6 @@
launchState.launchedFromApp = fromThumbnail;
launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
launchState.launchedWithAltTab = mTriggeredFromAltTab;
- launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
- launchState.launchedHasConfigurationChanged = false;
Intent intent = new Intent();
intent.setClassName(RECENTS_PACKAGE, RECENTS_TV_ACTIVITY);
@@ -115,7 +116,6 @@
} else {
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
}
- mCanReuseTaskStackViews = true;
EventBus.getDefault().send(new RecentsActivityStartingEvent());
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
index bd3143f..a69f8a2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
@@ -89,7 +89,7 @@
private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskCardView taskView,
ActivityOptions opts,final ActivityOptions.OnAnimationStartedListener animStartedListener) {
SystemServicesProxy ssp = Recents.getSystemServices();
- if (ssp.startActivityFromRecents(mContext, task.key.id, task.title, opts)) {
+ if (ssp.startActivityFromRecents(mContext, task.key, task.title, opts)) {
// Keep track of the index of the task launch
int taskIndexFromFront = 0;
int taskIndex = stack.indexOfStackTask(task);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index 3d5176f..d966614 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -109,7 +109,7 @@
Task task = mTaskStackHorizontalView.getFocusedTask();
if (task != null) {
SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key.id, task.title, null);
+ ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
return true;
}
}
@@ -123,7 +123,7 @@
Task task = stack.getLaunchTarget();
if (task != null) {
SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key.id, task.title, null);
+ ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
return true;
}
}
@@ -140,7 +140,7 @@
TaskCardView tv = taskViews.get(j);
if (tv.getTask() == task) {
SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key.id, task.title, null);
+ ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
return true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
index 22ade9f..3d0e75a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
@@ -156,4 +156,9 @@
}
}
}
+
+ @Override
+ public void onStackTasksUpdated(TaskStack stack) {
+ // Do nothing
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 7c5b441..9dc3fb1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -82,9 +82,9 @@
}
};
- public RecentsTransitionHelper(Context context, Handler handler) {
+ public RecentsTransitionHelper(Context context) {
mContext = context;
- mHandler = handler;
+ mHandler = new Handler();
}
/**
@@ -186,7 +186,7 @@
ActivityOptions opts, IAppTransitionAnimationSpecsFuture transitionFuture,
final ActivityOptions.OnAnimationStartedListener animStartedListener) {
SystemServicesProxy ssp = Recents.getSystemServices();
- if (ssp.startActivityFromRecents(mContext, task.key.id, task.title, opts)) {
+ if (ssp.startActivityFromRecents(mContext, task.key, task.title, opts)) {
// Keep track of the index of the task launch
int taskIndexFromFront = 0;
int taskIndex = stack.indexOfStackTask(task);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 28880df..b23b01f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -19,7 +19,6 @@
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.ActivityOptions.OnAnimationStartedListener;
import android.content.Context;
@@ -29,10 +28,6 @@
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.view.AppTransitionAnimationSpec;
@@ -44,11 +39,9 @@
import android.view.ViewOutlineProvider;
import android.view.ViewPropertyAnimator;
import android.view.WindowInsets;
-import android.view.WindowManagerGlobal;
import android.widget.FrameLayout;
import android.widget.TextView;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.Interpolators;
@@ -94,8 +87,6 @@
private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
- private final Handler mHandler;
-
private TaskStack mStack;
private TaskStackView mTaskStackView;
private TextView mStackActionButton;
@@ -133,18 +124,17 @@
setWillNotDraw(false);
SystemServicesProxy ssp = Recents.getSystemServices();
- mHandler = new Handler();
- mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler);
+ mTransitionHelper = new RecentsTransitionHelper(getContext());
mDividerSize = ssp.getDockedDividerSize(context);
mTouchHandler = new RecentsViewTouchHandler(this);
mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
- final float cornerRadius = context.getResources().getDimensionPixelSize(
- R.dimen.recents_task_view_rounded_corners_radius);
LayoutInflater inflater = LayoutInflater.from(context);
if (RecentsDebugFlags.Static.EnableStackActionButton) {
- mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button, this,
- false);
+ float cornerRadius = context.getResources().getDimensionPixelSize(
+ R.dimen.recents_task_view_rounded_corners_radius);
+ mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
+ this, false);
mStackActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -166,19 +156,17 @@
setBackground(mBackgroundScrim);
}
- /** Set/get the bsp root node */
- public void onResume(boolean isResumingFromVisible, boolean multiWindowChange,
- TaskStack stack) {
+ /**
+ * Called from RecentsActivity when it is relaunched.
+ */
+ public void onReload(boolean isResumingFromVisible, boolean isTaskStackEmpty) {
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
- if (!multiWindowChange &&
- (mTaskStackView == null || !launchState.launchedReuseTaskStackViews)) {
+ if (mTaskStackView == null) {
isResumingFromVisible = false;
- removeView(mTaskStackView);
mTaskStackView = new TaskStackView(getContext());
mTaskStackView.setSystemInsets(mSystemInsets);
- mStack = mTaskStackView.getStack();
addView(mTaskStackView);
}
@@ -187,9 +175,7 @@
mLastTaskLaunchedWasFreeform = false;
// Update the stack
- mTaskStackView.onResume(isResumingFromVisible);
- mTaskStackView.setTasks(stack, isResumingFromVisible /* notifyStackChanges */,
- true /* relayoutTaskStack */, multiWindowChange);
+ mTaskStackView.onReload(isResumingFromVisible);
if (isResumingFromVisible) {
// If we are already visible, then restore the background scrim
@@ -198,13 +184,21 @@
// If we are already occluded by the app, then set the final background scrim alpha now.
// Otherwise, defer until the enter animation completes to animate the scrim alpha with
// the tasks for the home animation.
- if (launchState.launchedWhileDocking || launchState.launchedFromApp
- || mStack.getTaskCount() == 0) {
+ if (launchState.launchedViaDockGesture || launchState.launchedFromApp
+ || isTaskStackEmpty) {
mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
} else {
mBackgroundScrim.setAlpha(0);
}
}
+ }
+
+ /**
+ * Called from RecentsActivity when the task stack is updated.
+ */
+ public void updateStack(TaskStack stack) {
+ mStack = stack;
+ mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
// Update the top level view's visibilities
if (stack.getTaskCount() > 0) {
@@ -215,6 +209,13 @@
}
/**
+ * Returns the current TaskStack.
+ */
+ public TaskStack getStack() {
+ return mStack;
+ }
+
+ /**
* Returns whether the last task launched was in the freeform stack or not.
*/
public boolean isLastTaskLaunchedFreeform() {
@@ -563,7 +564,7 @@
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
- if (!launchState.launchedWhileDocking && !launchState.launchedFromApp
+ if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
&& mStack.getTaskCount() > 0) {
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA,
TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index 6bdaaf9..9c8189a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -46,7 +46,7 @@
/**
* Prepares the scrim views for animating when entering Recents. This will be called before
- * the first draw.
+ * the first draw, unless we are updating the scrim on configuration change.
*/
public void prepareEnterRecentsAnimation(boolean hasNavBarScrim, boolean animateNavBarScrim) {
mHasNavBarScrim = hasNavBarScrim;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 4155dd2..8db81f7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -20,7 +20,6 @@
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.RectF;
import android.util.Log;
import android.view.View;
import android.view.animation.Interpolator;
@@ -152,32 +151,26 @@
if (hideTask) {
tv.setVisibility(View.INVISIBLE);
- } else if (launchState.launchedHasConfigurationChanged) {
- // Just load the views as-is
- } else if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
+ } else if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
if (task.isLaunchTarget) {
tv.onPrepareLaunchTargetForEnterAnimation();
} else if (currentTaskOccludesLaunchTarget) {
// Move the task view slightly lower so we can animate it in
- RectF bounds = new RectF(mTmpTransform.rect);
- bounds.offset(0, taskViewAffiliateGroupEnterOffset);
+ mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
+ mTmpTransform.alpha = 0f;
+ mStackView.updateTaskViewToTransform(tv, mTmpTransform,
+ AnimationProps.IMMEDIATE);
tv.setClipViewInStack(false);
- tv.setAlpha(0f);
- tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top,
- (int) bounds.right, (int) bounds.bottom);
}
} else if (launchState.launchedFromHome) {
// Move the task view off screen (below) so we can animate it in
- RectF bounds = new RectF(mTmpTransform.rect);
- bounds.offset(0, offscreenYOffset);
- tv.setAlpha(0f);
- tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right,
- (int) bounds.bottom);
- } else if (launchState.launchedWhileDocking) {
- RectF bounds = new RectF(mTmpTransform.rect);
- bounds.offset(0, launchedWhileDockingOffset);
- tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right,
- (int) bounds.bottom);
+ mTmpTransform.rect.offset(0, offscreenYOffset);
+ mTmpTransform.alpha = 0f;
+ mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
+ } else if (launchState.launchedViaDockGesture) {
+ mTmpTransform.rect.offset(0, launchedWhileDockingOffset);
+ mTmpTransform.alpha = 0f;
+ mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
}
}
}
@@ -225,7 +218,7 @@
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
null);
- if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
+ if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
if (task.isLaunchTarget) {
tv.onStartLaunchTargetEnterAnimation(mTmpTransform,
taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled,
@@ -264,7 +257,7 @@
if (i == taskViewCount - 1) {
tv.onStartFrontTaskEnterAnimation(mStackView.mScreenPinningEnabled);
}
- } else if (launchState.launchedWhileDocking) {
+ } else if (launchState.launchedViaDockGesture) {
// Animate the tasks up
AnimationProps taskAnimation = new AnimationProps()
.setDuration(AnimationProps.BOUNDS, (int) (ENTER_WHILE_DOCKING_DURATION +
@@ -354,6 +347,12 @@
if (tv == launchingTaskView) {
tv.setClipViewInStack(false);
+ postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+ @Override
+ public void run() {
+ tv.setClipViewInStack(true);
+ }
+ });
tv.onStartLaunchTargetLaunchAnimation(taskViewExitToAppDuration,
screenPinningRequested, postAnimationTrigger);
} else if (currentTaskOccludesLaunchTarget) {
@@ -386,7 +385,8 @@
int taskViewRemoveAnimTranslationXPx = res.getDimensionPixelSize(
R.dimen.recents_task_view_remove_anim_translation_x);
- // Disabling clipping with the stack while the view is animating away
+ // Disabling clipping with the stack while the view is animating away, this will get
+ // restored when the task is next picked up from the view pool
deleteTaskView.setClipViewInStack(false);
// Compose the new animation and transform and star the animation
@@ -395,9 +395,6 @@
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
-
- // Re-enable clipping with the stack (we will reuse this view)
- deleteTaskView.setClipViewInStack(true);
}
});
postAnimationTrigger.increment();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 83f8b7e..4b1faf3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -552,7 +552,7 @@
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
boolean scrollToFront = launchState.launchedFromHome ||
- launchState.launchedFromAppDocked;
+ launchState.launchedViaDockGesture;
if (scrollToFront) {
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
mInitialNormX = null;
@@ -852,7 +852,7 @@
// in screen space
float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
int centerYOffset = (mStackRect.top - mTaskRect.top) +
- (mStackRect.height() - mTaskRect.height()) / 2;
+ (mStackRect.height() - mSystemInsets.bottom - mTaskRect.height()) / 2;
y = centerYOffset + getYForDeltaP(tmpP, 0);
z = mMaxTranslationZ;
dimAlpha = 0f;
@@ -953,14 +953,8 @@
*/
public void getTaskStackBounds(Rect windowRect, int topInset, int rightInset,
Rect taskStackBounds) {
- RecentsConfiguration config = Recents.getConfiguration();
- if (config.hasTransposedNavBar) {
- taskStackBounds.set(windowRect.left, windowRect.top + topInset,
- windowRect.right - rightInset, windowRect.bottom);
- } else {
- taskStackBounds.set(windowRect.left, windowRect.top + topInset,
- windowRect.right - rightInset, windowRect.bottom);
- }
+ taskStackBounds.set(windowRect.left, windowRect.top + topInset,
+ windowRect.right - rightInset, windowRect.bottom);
// Ensure that the new width is at most the smaller display edge size
SystemServicesProxy ssp = Recents.getSystemServices();
@@ -1105,9 +1099,11 @@
private int getScaleForExtent(Rect instance, Rect other, int value, int minValue,
@Extent int extent) {
if (extent == WIDTH) {
- return Math.max(minValue, (int) (((float) instance.width() / other.width()) * value));
+ float scale = Utilities.clamp01((float) instance.width() / other.width());
+ return Math.max(minValue, (int) (scale * value));
} else if (extent == HEIGHT) {
- return Math.max(minValue, (int) (((float) instance.height() / other.height()) * value));
+ float scale = Utilities.clamp01((float) instance.height() / other.height());
+ return Math.max(minValue, (int) (scale * value));
}
return value;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index bea47f1..04f153f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -22,11 +22,13 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
@@ -59,8 +61,8 @@
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.EnterRecentsTaskStackAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
+import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
@@ -87,6 +89,8 @@
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -114,12 +118,23 @@
private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 216;
private static final int LAUNCH_NEXT_SCROLL_INCR_DURATION = 32;
- private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
+ // The actions to perform when resetting to initial state,
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({INITIAL_STATE_UPDATE_NONE, INITIAL_STATE_UPDATE_ALL, INITIAL_STATE_UPDATE_LAYOUT_ONLY})
+ public @interface InitialStateAction {}
+ /** Do not update the stack and layout to the initial state. */
+ private static final int INITIAL_STATE_UPDATE_NONE = 0;
+ /** Update both the stack and layout to the initial state. */
+ private static final int INITIAL_STATE_UPDATE_ALL = 1;
+ /** Update only the layout to the initial state. */
+ private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;
LayoutInflater mInflater;
TaskStack mStack = new TaskStack();
@ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
TaskStackLayoutAlgorithm mLayoutAlgorithm;
+ // The stable layout algorithm is only used to calculate the task rect with the stable bounds
+ TaskStackLayoutAlgorithm mStableLayoutAlgorithm;
@ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
TaskStackViewScroller mStackScroller;
@ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
@@ -148,6 +163,9 @@
@ViewDebug.ExportedProperty(category="recents")
boolean mAwaitingFirstLayout = true;
@ViewDebug.ExportedProperty(category="recents")
+ @InitialStateAction
+ int mInitialState = INITIAL_STATE_UPDATE_ALL;
+ @ViewDebug.ExportedProperty(category="recents")
boolean mInMeasureLayout = false;
@ViewDebug.ExportedProperty(category="recents")
boolean mEnterAnimationComplete = false;
@@ -223,6 +241,7 @@
mViewPool = new ViewPool<>(context, this);
mInflater = LayoutInflater.from(context);
mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
+ mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
mAnimationHelper = new TaskStackAnimationHelper(context, this);
@@ -255,41 +274,6 @@
}
}
- /**
- * Called only if we are resuming Recents.
- */
- void onResume(boolean isResumingFromVisible) {
- if (!isResumingFromVisible) {
- // Reset the focused task
- resetFocusedTask(getFocusedTask());
- }
-
- // Reset the state of each of the task views
- List<TaskView> taskViews = new ArrayList<>();
- taskViews.addAll(getTaskViews());
- taskViews.addAll(mViewPool.getViews());
- for (int i = taskViews.size() - 1; i >= 0; i--) {
- taskViews.get(i).onResume(isResumingFromVisible);
- }
-
- // Reset the stack state
- readSystemFlags();
- mTaskViewsClipDirty = true;
- mEnterAnimationComplete = false;
- mUIDozeTrigger.stopDozing();
- if (isResumingFromVisible) {
- // Animate in the freeform workspace
- int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
- animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
- Interpolators.FAST_OUT_SLOW_IN));
- } else {
- mStackScroller.reset();
- mLayoutAlgorithm.reset();
- mAwaitingFirstLayout = true;
- requestLayout();
- }
- }
-
@Override
protected void onAttachedToWindow() {
EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -304,34 +288,54 @@
}
/**
+ * Called from RecentsActivity when it is relaunched.
+ */
+ void onReload(boolean isResumingFromVisible) {
+ if (!isResumingFromVisible) {
+ // Reset the focused task
+ resetFocusedTask(getFocusedTask());
+ }
+
+ // Reset the state of each of the task views
+ List<TaskView> taskViews = new ArrayList<>();
+ taskViews.addAll(getTaskViews());
+ taskViews.addAll(mViewPool.getViews());
+ for (int i = taskViews.size() - 1; i >= 0; i--) {
+ taskViews.get(i).onReload(isResumingFromVisible);
+ }
+
+ // Reset the stack state
+ readSystemFlags();
+ mTaskViewsClipDirty = true;
+ mEnterAnimationComplete = false;
+ mUIDozeTrigger.stopDozing();
+ if (isResumingFromVisible) {
+ // Animate in the freeform workspace
+ int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
+ animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
+ Interpolators.FAST_OUT_SLOW_IN));
+ } else {
+ mStackScroller.reset();
+ mStableLayoutAlgorithm.reset();
+ mLayoutAlgorithm.reset();
+ }
+
+ // Since we always animate to the same place in (the initial state), always reset the stack
+ // to the initial state when resuming
+ mAwaitingFirstLayout = true;
+ mInitialState = INITIAL_STATE_UPDATE_ALL;
+ requestLayout();
+ }
+
+ /**
* Sets the stack tasks of this TaskStackView from the given TaskStack.
*/
- public void setTasks(TaskStack stack, boolean notifyStackChanges, boolean relayoutTaskStack,
- boolean multiWindowChange) {
+ public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
boolean isInitialized = mLayoutAlgorithm.isInitialized();
+ // Only notify if we are already initialized, otherwise, everything will pick up all the
+ // new and old tasks when we next layout
mStack.setTasks(getContext(), stack.computeAllTasksList(),
- notifyStackChanges && isInitialized);
- if (isInitialized) {
- // Only update the layout if we are notifying, otherwise, we will update it in the next
- // measure/layout pass
- updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
- if (!multiWindowChange) {
- updateToInitialState();
- }
-
- if (relayoutTaskStack) {
- relayoutTaskViews(AnimationProps.IMMEDIATE);
-
- // Rebind all the task views. This will not trigger new resources to be loaded
- // unless they have actually changed
- List<TaskView> taskViews = getTaskViews();
- int taskViewCount = taskViews.size();
- for (int i = 0; i < taskViewCount; i++) {
- TaskView tv = taskViews.get(i);
- bindTaskView(tv, tv.getTask());
- }
- }
- }
+ allowNotifyStackChanges && isInitialized);
}
/** Returns the task stack. */
@@ -342,8 +346,10 @@
/**
* Updates this TaskStackView to the initial state.
*/
- public void updateToInitialState() {
- mStackScroller.setStackScrollToInitialState();
+ public void updateToInitialState(boolean scrollToInitialState) {
+ if (scrollToInitialState) {
+ mStackScroller.setStackScrollToInitialState();
+ }
mLayoutAlgorithm.updateToInitialState(mStack.getStackTasks());
}
@@ -591,17 +597,14 @@
if (tv == null) {
tv = mViewPool.pickUpViewFromPool(task, task);
if (task.isFreeformTask()) {
- tv.updateViewPropertiesToTaskTransform(transform, AnimationProps.IMMEDIATE,
- mRequestUpdateClippingListener);
+ updateTaskViewToTransform(tv, transform, AnimationProps.IMMEDIATE);
} else {
if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
- tv.updateViewPropertiesToTaskTransform(
- mLayoutAlgorithm.getBackOfStackTransform(),
- AnimationProps.IMMEDIATE, mRequestUpdateClippingListener);
+ updateTaskViewToTransform(tv, mLayoutAlgorithm.getBackOfStackTransform(),
+ AnimationProps.IMMEDIATE);
} else {
- tv.updateViewPropertiesToTaskTransform(
- mLayoutAlgorithm.getFrontOfStackTransform(),
- AnimationProps.IMMEDIATE, mRequestUpdateClippingListener);
+ updateTaskViewToTransform(tv, mLayoutAlgorithm.getFrontOfStackTransform(),
+ AnimationProps.IMMEDIATE);
}
}
} else {
@@ -771,8 +774,6 @@
* Updates the clip for each of the task views from back to front.
*/
private void clipTaskViews() {
- RecentsConfiguration config = Recents.getConfiguration();
-
// Update the clip on each task child
List<TaskView> taskViews = getTaskViews();
TaskView tmpTv = null;
@@ -1177,6 +1178,7 @@
*/
public void setSystemInsets(Rect systemInsets) {
if (!systemInsets.equals(mLayoutAlgorithm.mSystemInsets)) {
+ mStableLayoutAlgorithm.setSystemInsets(systemInsets);
mLayoutAlgorithm.setSystemInsets(systemInsets);
requestLayout();
}
@@ -1205,21 +1207,21 @@
}
// Compute the rects in the stack algorithm
+ mStableLayoutAlgorithm.initialize(mStableWindowRect, mStableStackBounds,
+ TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
- updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
+ updateLayoutAlgorithm(false /* boundScroll */, mIgnoreTasks);
// If this is the first layout, then scroll to the front of the stack, then update the
// TaskViews with the stack so that we can lay them out
- // TODO: The second check is a workaround for wacky layouts that we get while docking via
- // long pressing the recents button
- if (mAwaitingFirstLayout ||
- (mStackScroller.getStackScroll() == mLayoutAlgorithm.mInitialScrollP)) {
- updateToInitialState();
+ if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE) {
+ updateToInitialState(mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY);
+ mInitialState = INITIAL_STATE_UPDATE_NONE;
}
// Rebind all the views, including the ignore ones
- bindVisibleTaskViews(mStackScroller.getStackScroll(), EMPTY_TASK_SET,
+ bindVisibleTaskViews(mStackScroller.getStackScroll(), mIgnoreTasks,
false /* ignoreTaskOverrides */);
// Measure each of the TaskViews
@@ -1244,12 +1246,11 @@
} else {
mTmpRect.setEmpty();
}
+ Rect taskRect = mStableLayoutAlgorithm.mTaskRect;
tv.measure(
- MeasureSpec.makeMeasureSpec(
- mLayoutAlgorithm.mTaskRect.width() + mTmpRect.left + mTmpRect.right,
+ MeasureSpec.makeMeasureSpec(taskRect.width() + mTmpRect.left + mTmpRect.right,
MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(
- mLayoutAlgorithm.mTaskRect.height() + mTmpRect.top + mTmpRect.bottom,
+ MeasureSpec.makeMeasureSpec(taskRect.height() + mTmpRect.top + mTmpRect.bottom,
MeasureSpec.EXACTLY));
}
@@ -1261,7 +1262,7 @@
mTmpTaskViews.addAll(mViewPool.getViews());
int taskViewCount = mTmpTaskViews.size();
for (int i = 0; i < taskViewCount; i++) {
- layoutTaskView(mTmpTaskViews.get(i));
+ layoutTaskView(changed, mTmpTaskViews.get(i));
}
if (changed) {
@@ -1269,8 +1270,9 @@
mStackScroller.boundScroll();
}
}
+
// Relayout all of the task views including the ignored ones
- relayoutTaskViews(AnimationProps.IMMEDIATE, EMPTY_TASK_SET);
+ relayoutTaskViews(AnimationProps.IMMEDIATE, mIgnoreTasks);
clipTaskViews();
if (mAwaitingFirstLayout || !mEnterAnimationComplete) {
@@ -1282,16 +1284,21 @@
/**
* Lays out a TaskView.
*/
- private void layoutTaskView(TaskView tv) {
- if (tv.getBackground() != null) {
- tv.getBackground().getPadding(mTmpRect);
+ private void layoutTaskView(boolean changed, TaskView tv) {
+ if (changed) {
+ if (tv.getBackground() != null) {
+ tv.getBackground().getPadding(mTmpRect);
+ } else {
+ mTmpRect.setEmpty();
+ }
+ Rect taskRect = mStableLayoutAlgorithm.mTaskRect;
+ tv.cancelTransformAnimation();
+ tv.layout(taskRect.left - mTmpRect.left, taskRect.top - mTmpRect.top,
+ taskRect.right + mTmpRect.right, taskRect.bottom + mTmpRect.bottom);
} else {
- mTmpRect.setEmpty();
+ // If the layout has not changed, then just lay it out again in-place
+ tv.layout(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
}
- Rect taskRect = mLayoutAlgorithm.mTaskRect;
- tv.cancelTransformAnimation();
- tv.layout(taskRect.left - mTmpRect.left, taskRect.top - mTmpRect.top,
- taskRect.right + mTmpRect.right, taskRect.bottom + mTmpRect.bottom);
}
/** Handler for the first layout. */
@@ -1439,6 +1446,22 @@
}
}
+ @Override
+ public void onStackTasksUpdated(TaskStack stack) {
+ // Update the layout and immediately layout
+ updateLayoutAlgorithm(false /* boundScroll */);
+ relayoutTaskViews(AnimationProps.IMMEDIATE);
+
+ // Rebind all the task views. This will not trigger new resources to be loaded
+ // unless they have actually changed
+ List<TaskView> taskViews = getTaskViews();
+ int taskViewCount = taskViews.size();
+ for (int i = 0; i < taskViewCount; i++) {
+ TaskView tv = taskViews.get(i);
+ bindTaskView(tv, tv.getTask());
+ }
+ }
+
/**** ViewPoolConsumer Implementation ****/
@Override
@@ -1488,7 +1511,7 @@
}
addViewInLayout(tv, insertIndex, params, true /* preventRequestLayout */);
measureTaskView(tv);
- layoutTaskView(tv);
+ layoutTaskView(true /* changed */, tv);
}
} else {
attachViewToParent(tv, insertIndex, tv.getLayoutParams());
@@ -1911,9 +1934,25 @@
}
public final void onBusEvent(ConfigurationChangedEvent event) {
+ mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
- mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
- TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+
+ // Notify the task views of the configuration change so they can reload their resources
+ if (!event.fromMultiWindow) {
+ mTmpTaskViews.clear();
+ mTmpTaskViews.addAll(getTaskViews());
+ mTmpTaskViews.addAll(mViewPool.getViews());
+ int taskViewCount = mTmpTaskViews.size();
+ for (int i = 0; i < taskViewCount; i++) {
+ mTmpTaskViews.get(i).onConfigurationChanged();
+ }
+ }
+
+ // Trigger a new layout and scroll to the initial state
+ mInitialState = event.fromMultiWindow
+ ? INITIAL_STATE_UPDATE_ALL
+ : INITIAL_STATE_UPDATE_LAYOUT_ONLY;
+ requestLayout();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 0c47b13..c085d80 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -24,6 +24,7 @@
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Paint;
@@ -191,15 +192,15 @@
mCb = cb;
}
- /** Resets this TaskView for reuse. */
- void onResume(boolean isResumingFromVisible) {
+ /**
+ * Called from RecentsActivity when it is relaunched.
+ */
+ void onReload(boolean isResumingFromVisible) {
resetNoUserInteractionState();
readSystemFlags();
if (!isResumingFromVisible) {
resetViewProperties();
- setClipViewInStack(false);
}
- setCallbacks(null);
}
/** Gets the task */
@@ -237,6 +238,13 @@
mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
}
+ /**
+ * Update the task view when the configuration changes.
+ */
+ void onConfigurationChanged() {
+ mHeaderView.onConfigurationChanged();
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 62995a6..ddea4d9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -250,6 +250,44 @@
mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
+ onConfigurationChanged();
+ }
+
+ /**
+ * Programmatically sets the layout params for a header bar layout. This is necessary because
+ * we can't get resources based on the current configuration, but instead need to get them
+ * based on the device configuration.
+ */
+ private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
+ setLayoutParams(lp);
+ lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
+ icon.setLayoutParams(lp);
+ lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
+ lp.setMarginStart(mHeaderBarHeight);
+ lp.rightMargin = mMoveTaskButton != null
+ ? 2 * mHeaderBarHeight
+ : mHeaderBarHeight;
+ title.setLayoutParams(lp);
+ if (secondaryButton != null) {
+ lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
+ lp.setMarginEnd(mHeaderBarHeight);
+ secondaryButton.setLayoutParams(lp);
+ secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
+ mHeaderButtonPadding, mHeaderButtonPadding);
+ }
+ lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
+ button.setLayoutParams(lp);
+ button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
+ mHeaderButtonPadding);
+ }
+
+ /**
+ * Update the header view when the configuration changes.
+ */
+ void onConfigurationChanged() {
// Update the dimensions of everything in the header. We do this because we need to use
// resources for the display, and not the current configuration.
Resources res = getResources();
@@ -269,37 +307,9 @@
R.dimen.recents_task_view_header_button_padding_tablet_land);
updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
mDismissButton);
- }
-
- /**
- * Programmatically sets the layout params for a header bar layout. This is necessary because
- * we can't get resources based on the current configuration, but instead need to get them
- * based on the device configuration.
- */
- private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
- setLayoutParams(lp);
- lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
- icon.setLayoutParams(lp);
- lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
- lp.leftMargin = mHeaderBarHeight;
- lp.rightMargin = mMoveTaskButton != null
- ? 2 * mHeaderBarHeight
- : mHeaderBarHeight;
- title.setLayoutParams(lp);
- if (secondaryButton != null) {
- lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
- lp.rightMargin = mHeaderBarHeight;
- secondaryButton.setLayoutParams(lp);
- secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
- mHeaderButtonPadding, mHeaderButtonPadding);
+ if (mAppOverlayView != null) {
+ updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
}
- lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
- button.setLayoutParams(lp);
- button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
- mHeaderButtonPadding);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index e9c09ac..3eeabc7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -243,11 +243,6 @@
public void updateThumbnailScale() {
mThumbnailScale = 1f;
if (mBitmapShader != null) {
-
- if (mThumbnailInfo != null) {
- System.out.println(mTask.title + " bounds: " + mThumbnailInfo.taskWidth + "x" + mThumbnailInfo.taskHeight + ", " + mThumbnailInfo.screenOrientation);
- }
-
// We consider this a stack task if it is not freeform (ie. has no bounds) or has been
// dragged into the stack from the freeform workspace
boolean isStackTask = !mTask.isFreeformTask() || mTask.bounds == null;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index bab6baa..7a933cd 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -83,6 +83,7 @@
private static final String TAG = "DividerView";
private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
+ private static final boolean SWAPPING_ENABLED = false;
/**
* How much the background gets scaled when we are in the minimized dock state.
@@ -170,6 +171,13 @@
}
};
+ private final Runnable mResetBackgroundRunnable = new Runnable() {
+ @Override
+ public void run() {
+ resetBackground();
+ }
+ };
+
public DividerView(Context context) {
super(context);
}
@@ -213,12 +221,14 @@
mGestureDetector = new GestureDetector(mContext, new SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
- updateDockSide();
- SystemServicesProxy ssp = Recents.getSystemServices();
- if (mDockSide != WindowManager.DOCKED_INVALID
- && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) {
- mWindowManagerProxy.swapTasks();
- return true;
+ if (SWAPPING_ENABLED) {
+ updateDockSide();
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ if (mDockSide != WindowManager.DOCKED_INVALID
+ && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) {
+ mWindowManagerProxy.swapTasks();
+ return true;
+ }
}
return false;
}
@@ -383,13 +393,6 @@
x = (int) event.getRawX();
y = (int) event.getRawY();
- if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
- int position = calculatePosition(x, y);
- SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(position,
- 0 /* velocity */, false /* hardDismiss */);
- resizeStack(calculatePosition(x, y), snapTarget.position, snapTarget);
- }
-
mVelocityTracker.computeCurrentVelocity(1000);
int position = calculatePosition(x, y);
stopDragging(position, isHorizontalDivision() ? mVelocityTracker.getYVelocity()
@@ -523,15 +526,17 @@
public void setMinimizedDockStack(boolean minimized) {
updateDockSide();
mHandle.setAlpha(minimized ? 0f : 1f);
- if (mDockSide == WindowManager.DOCKED_TOP) {
+ if (!minimized) {
+ resetBackground();
+ } else if (mDockSide == WindowManager.DOCKED_TOP) {
mBackground.setPivotY(0);
- mBackground.setScaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+ mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
} else if (mDockSide == WindowManager.DOCKED_LEFT
|| mDockSide == WindowManager.DOCKED_RIGHT) {
mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
? 0
: mBackground.getWidth());
- mBackground.setScaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+ mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
}
}
@@ -554,12 +559,22 @@
mBackground.animate()
.scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
}
+ if (!minimized) {
+ mBackground.animate().withEndAction(mResetBackgroundRunnable);
+ }
mBackground.animate()
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setDuration(animDuration)
.start();
}
+ private void resetBackground() {
+ mBackground.setPivotX(mBackground.getWidth() / 2);
+ mBackground.setPivotY(mBackground.getHeight() / 2);
+ mBackground.setScaleX(1f);
+ mBackground.setScaleY(1f);
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -734,21 +749,22 @@
mSnapAlgorithm.calculateDismissingFraction(position)));
SnapTarget dismissTarget = null;
SnapTarget splitTarget = null;
- if ((snapTarget.flag == SnapTarget.FLAG_DISMISS_START
- || snapTarget == mSnapAlgorithm.getFirstSplitTarget())
+ int start = 0;
+ if (position <= mSnapAlgorithm.getLastSplitTarget().position
&& dockSideTopLeft(dockSide)) {
dismissTarget = mSnapAlgorithm.getDismissStartTarget();
splitTarget = mSnapAlgorithm.getFirstSplitTarget();
- } else if ((snapTarget.flag == SnapTarget.FLAG_DISMISS_END
- || snapTarget == mSnapAlgorithm.getLastSplitTarget())
+ start = taskPosition;
+ } else if (position >= mSnapAlgorithm.getLastSplitTarget().position
&& dockSideBottomRight(dockSide)) {
dismissTarget = mSnapAlgorithm.getDismissEndTarget();
splitTarget = mSnapAlgorithm.getLastSplitTarget();
+ start = splitTarget.position;
}
if (dismissTarget != null && fraction > 0f
&& isDismissing(splitTarget, position, dockSide)) {
fraction = calculateParallaxDismissingFraction(fraction, dockSide);
- int offsetPosition = (int) (taskPosition +
+ int offsetPosition = (int) (start +
fraction * (dismissTarget.position - splitTarget.position));
int width = taskRect.width();
int height = taskRect.height();
@@ -796,11 +812,12 @@
}
private int getStackIdForDismissTarget(SnapTarget dismissTarget) {
- if (dismissTarget.flag == SnapTarget.FLAG_DISMISS_START &&
- (mDockSide == WindowManager.DOCKED_LEFT || mDockSide == WindowManager.DOCKED_TOP)) {
+ if ((dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
+ || (dismissTarget.flag == SnapTarget.FLAG_DISMISS_END
+ && dockSideBottomRight(mDockSide))) {
return StackId.DOCKED_STACK_ID;
} else {
- return StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+ return StackId.HOME_STACK_ID;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index d00e8ef..99b6397 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -92,37 +92,37 @@
* These methods are called back on the main thread.
*/
public interface Callbacks {
- public void setIcon(String slot, StatusBarIcon icon);
- public void removeIcon(String slot);
- public void disable(int state1, int state2, boolean animate);
- public void animateExpandNotificationsPanel();
- public void animateCollapsePanels(int flags);
- public void animateExpandSettingsPanel(String obj);
- public void setSystemUiVisibility(int vis, int fullscreenStackVis,
+ void setIcon(String slot, StatusBarIcon icon);
+ void removeIcon(String slot);
+ void disable(int state1, int state2, boolean animate);
+ void animateExpandNotificationsPanel();
+ void animateCollapsePanels(int flags);
+ void animateExpandSettingsPanel(String obj);
+ void setSystemUiVisibility(int vis, int fullscreenStackVis,
int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds);
- public void topAppWindowChanged(boolean visible);
- public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
+ void topAppWindowChanged(boolean visible);
+ void setImeWindowStatus(IBinder token, int vis, int backDisposition,
boolean showImeSwitcher);
- public void showRecentApps(boolean triggeredFromAltTab);
- public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
- public void toggleRecentApps();
- public void toggleSplitScreen();
- public void preloadRecentApps();
- public void toggleKeyboardShortcutsMenu(int deviceId);
- public void cancelPreloadRecentApps();
- public void setWindowState(int window, int state);
- public void buzzBeepBlinked();
- public void notificationLightOff();
- public void notificationLightPulse(int argb, int onMillis, int offMillis);
- public void showScreenPinningRequest();
- public void appTransitionPending();
- public void appTransitionCancelled();
- public void appTransitionStarting(long startTime, long duration);
- public void appTransitionFinished();
- public void showAssistDisclosure();
- public void startAssist(Bundle args);
- public void onCameraLaunchGestureDetected(int source);
- public void requestTvPictureInPicture();
+ void showRecentApps(boolean triggeredFromAltTab);
+ void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
+ void toggleRecentApps();
+ void toggleSplitScreen();
+ void preloadRecentApps();
+ void toggleKeyboardShortcutsMenu(int deviceId);
+ void cancelPreloadRecentApps();
+ void setWindowState(int window, int state);
+ void buzzBeepBlinked();
+ void notificationLightOff();
+ void notificationLightPulse(int argb, int onMillis, int offMillis);
+ void showScreenPinningRequest();
+ void appTransitionPending();
+ void appTransitionCancelled();
+ void appTransitionStarting(long startTime, long duration);
+ void appTransitionFinished();
+ void showAssistDisclosure();
+ void startAssist(Bundle args);
+ void onCameraLaunchGestureDetected(int source);
+ void requestTvPictureInPicture();
void addQsTile(ComponentName tile);
void remQsTile(ComponentName tile);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutKeysLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutKeysLayout.java
index ba3e774..6746a67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutKeysLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutKeysLayout.java
@@ -29,13 +29,16 @@
*/
public final class KeyboardShortcutKeysLayout extends ViewGroup {
private int mLineHeight;
+ private final Context mContext;
public KeyboardShortcutKeysLayout(Context context) {
super(context);
+ this.mContext = context;
}
public KeyboardShortcutKeysLayout(Context context, AttributeSet attrs) {
super(context, attrs);
+ this.mContext = context;
}
@Override
@@ -104,7 +107,9 @@
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int fullRowWidth = r - l;
- int xPos = getPaddingLeft();
+ int xPos = isRTL()
+ ? fullRowWidth - getPaddingRight()
+ : getPaddingLeft();
int yPos = getPaddingTop();
int lastHorizontalSpacing = 0;
// The index of the child which starts the current row.
@@ -117,18 +122,25 @@
int currentChildWidth = currentChild.getMeasuredWidth();
LayoutParams lp = (LayoutParams) currentChild.getLayoutParams();
- // If the current child does not fit on this row.
- if (xPos + currentChildWidth > fullRowWidth) {
+ boolean childDoesNotFitOnRow = isRTL()
+ ? xPos - getPaddingLeft() - currentChildWidth < 0
+ : xPos + currentChildWidth > fullRowWidth;
+
+ if (childDoesNotFitOnRow) {
// Layout all the children on this row but the current one.
layoutChildrenOnRow(rowStartIdx, i, fullRowWidth, xPos, yPos,
lastHorizontalSpacing);
// Update the positions for starting on the new row.
- xPos = getPaddingLeft();
+ xPos = isRTL()
+ ? fullRowWidth - getPaddingRight()
+ : getPaddingLeft();
yPos += mLineHeight;
rowStartIdx = i;
}
- xPos += currentChildWidth + lp.mHorizontalSpacing;
+ xPos = isRTL()
+ ? xPos - currentChildWidth - lp.mHorizontalSpacing
+ : xPos + currentChildWidth + lp.mHorizontalSpacing;
lastHorizontalSpacing = lp.mHorizontalSpacing;
}
}
@@ -148,21 +160,41 @@
private void layoutChildrenOnRow(int startIndex, int endIndex, int fullRowWidth, int xPos,
int yPos, int lastHorizontalSpacing) {
- int freeSpace = fullRowWidth - xPos + lastHorizontalSpacing;
- xPos = getPaddingLeft() + freeSpace;
+ if (!isRTL()) {
+ xPos = getPaddingLeft() + fullRowWidth - xPos + lastHorizontalSpacing;
+ }
for (int j = startIndex; j < endIndex; ++j) {
View currentChild = getChildAt(j);
+ int currentChildWidth = currentChild.getMeasuredWidth();
+ LayoutParams lp = (LayoutParams) currentChild.getLayoutParams();
+ if (isRTL() && j == startIndex) {
+ xPos = fullRowWidth - xPos - getPaddingRight() - currentChildWidth
+ - lp.mHorizontalSpacing;
+ }
+
currentChild.layout(
xPos,
yPos,
- xPos + currentChild.getMeasuredWidth(),
+ xPos + currentChildWidth,
yPos + currentChild.getMeasuredHeight());
- xPos += currentChild.getMeasuredWidth()
- + ((LayoutParams) currentChild.getLayoutParams()).mHorizontalSpacing;
+
+ if (isRTL()) {
+ int nextChildWidth = j < endIndex - 1
+ ? getChildAt(j + 1).getMeasuredWidth()
+ : 0;
+ xPos -= nextChildWidth + lp.mHorizontalSpacing;
+ } else {
+ xPos += currentChildWidth + lp.mHorizontalSpacing;
+ }
}
}
+ private boolean isRTL() {
+ return mContext.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_RTL;
+ }
+
public static class LayoutParams extends ViewGroup.LayoutParams {
public final int mHorizontalSpacing;
public final int mVerticalSpacing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
index bb43899..d9bf539 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
@@ -106,7 +106,7 @@
String category = getPackageCategory(packageName);
if (mFacetCategoryMap.containsKey(category)) {
- int index = mFacetCategoryMap.get(packageName);
+ int index = mFacetCategoryMap.get(category);
mFacetHasMultipleAppsCache.put(index, facetHasMultiplePackages(index));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index d9a0f43..023c4d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -136,7 +136,7 @@
private boolean mStackScrollerOverscrolling;
private boolean mQsExpansionFromOverscroll;
private float mLastOverscroll;
- private boolean mQsExpansionEnabled = true;
+ protected boolean mQsExpansionEnabled = true;
private ValueAnimator mQsExpansionAnimator;
private FlingAnimationUtils mFlingAnimationUtils;
private int mStatusBarMinHeight;
@@ -789,8 +789,9 @@
}
private boolean isInQsArea(float x, float y) {
- return (x >= mQsContainer.getX() && x <= mQsContainer.getX() + mQsContainer.getWidth()) &&
- (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
+ return (x >= mQsDensityContainer.getX()
+ && x <= mQsDensityContainer.getX() + mQsDensityContainer.getWidth())
+ && (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
|| y <= mQsContainer.getY() + mQsContainer.getHeight());
}
@@ -1208,7 +1209,9 @@
}
private String getKeyguardOrLockScreenString() {
- if (mStatusBarState == StatusBarState.KEYGUARD) {
+ if (mQsContainer.isCustomizing()) {
+ return getContext().getString(R.string.accessibility_desc_quick_settings_edit);
+ } else if (mStatusBarState == StatusBarState.KEYGUARD) {
return getContext().getString(R.string.accessibility_desc_lock_screen);
} else {
return getContext().getString(R.string.accessibility_desc_notification_shade);
@@ -1335,7 +1338,8 @@
return false;
}
View header = mKeyguardShowing ? mKeyguardStatusBar : mQsContainer.getHeader();
- boolean onHeader = x >= header.getX() && x <= header.getX() + header.getWidth()
+ boolean onHeader = x >= mQsDensityContainer.getX()
+ && x <= mQsDensityContainer.getX() + mQsDensityContainer.getWidth()
&& y >= header.getTop() && y <= header.getBottom();
if (mQsExpanded) {
return onHeader || (yDiff < 0 && isInQsArea(x, y));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7ae87e7..bb77c5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -284,7 +284,7 @@
HotspotControllerImpl mHotspotController;
RotationLockControllerImpl mRotationLockController;
UserInfoController mUserInfoController;
- ZenModeController mZenModeController;
+ protected ZenModeController mZenModeController;
CastControllerImpl mCastController;
VolumeComponent mVolumeComponent;
KeyguardUserSwitcher mKeyguardUserSwitcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 0442ac3..2783ec5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -37,22 +37,14 @@
super(context, theme);
mContext = context;
- getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+ applyFlags(this);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle(getClass().getSimpleName());
getWindow().setAttributes(attrs);
}
public void setShowForAllUsers(boolean show) {
- if (show) {
- getWindow().getAttributes().privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- } else {
- getWindow().getAttributes().privateFlags &=
- ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- }
+ setShowForAllUsers(this, show);
}
public void setMessage(int resId) {
@@ -66,4 +58,20 @@
public void setNegativeButton(int resId, OnClickListener onClick) {
setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
}
+
+ public static void setShowForAllUsers(AlertDialog dialog, boolean show) {
+ if (show) {
+ dialog.getWindow().getAttributes().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ } else {
+ dialog.getWindow().getAttributes().privateFlags &=
+ ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ }
+ }
+
+ public static void applyFlags(AlertDialog dialog) {
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
index 26e1d46..fe44502 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
@@ -15,10 +15,7 @@
*/
package com.android.systemui.tuner;
-import android.app.ActivityManager;
import android.content.Intent;
-import android.provider.Settings;
-
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.Prefs.Key;
@@ -26,8 +23,6 @@
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.NightModeController;
-import java.util.Objects;
-
public class NightModeTile extends QSTile<QSTile.State> implements NightModeController.Listener {
@@ -81,6 +76,11 @@
}
@Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.night_mode);
+ }
+
+ @Override
protected void handleUpdateState(State state, Object arg) {
// TODO: Right now this is just a dropper, needs an actual night icon.
boolean enabled = mNightModeController.isEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
index 0e64dcd..15ad1f1 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
@@ -143,7 +143,9 @@
@Override
public void onClick(View v) {
mPipManager.closePip();
- mListener.onClosed();
+ if (mListener != null) {
+ mListener.onClosed();
+ }
}
});
mCloseButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 6976c0b..e3ed92c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -86,7 +86,7 @@
= new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
private final Context mContext;
- private final LayoutInflater mInflater;
+ protected final LayoutInflater mInflater;
private final H mHandler = new H();
private final ZenPrefs mPrefs;
private final TransitionHelper mTransitionHelper = new TransitionHelper();
@@ -95,12 +95,12 @@
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
- private SegmentedButtons mZenButtons;
+ protected SegmentedButtons mZenButtons;
private View mZenIntroduction;
private TextView mZenIntroductionMessage;
private View mZenIntroductionConfirm;
private TextView mZenIntroductionCustomize;
- private LinearLayout mZenConditions;
+ protected LinearLayout mZenConditions;
private TextView mZenAlarmWarning;
private Callback mCallback;
@@ -148,10 +148,7 @@
mTransitionHelper.dump(fd, pw, args);
}
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
+ protected void createZenButtons() {
mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
mZenButtons.addButton(R.string.interruption_level_none_twoline,
R.string.interruption_level_none_with_warning,
@@ -163,7 +160,12 @@
R.string.interruption_level_priority,
Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
mZenButtons.setCallback(mZenButtonsCallback);
+ }
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ createZenButtons();
mZenIntroduction = findViewById(R.id.zen_introduction);
mZenIntroductionMessage = (TextView) findViewById(R.id.zen_introduction_message);
mSpTexts.add(mZenIntroductionMessage);
@@ -302,14 +304,18 @@
}
}
+ protected void addZenConditions(int count) {
+ for (int i = 0; i < count; i++) {
+ mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
+ }
+ }
+
public void init(ZenModeController controller) {
mController = controller;
mCountdownConditionSupported = mController.isCountdownConditionSupported();
final int countdownDelta = mCountdownConditionSupported ? COUNTDOWN_CONDITION_COUNT : 0;
final int minConditions = 1 /*forever*/ + countdownDelta;
- for (int i = 0; i < minConditions; i++) {
- mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
- }
+ addZenConditions(minConditions);
mSessionZen = getSelectedZen(-1);
handleUpdateManualRule(mController.getManualRule());
if (DEBUG) Log.d(mTag, "init mExitCondition=" + mExitCondition);
@@ -917,7 +923,7 @@
}
}
- private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
+ protected final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
@Override
public void onSelected(final Object value, boolean fromClick) {
if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index fc92966..f2ef065 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -142,7 +142,10 @@
}
return Element.DataType.FLOAT_64;
}
- return null;
+
+ throw new RSIllegalArgumentException("Parameter of type " + cmp.getSimpleName() +
+ "[] is not compatible with data type " + mType.mElement.mType.name() +
+ " of allocation");
}
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index a093d92..e15b785 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -111,12 +111,18 @@
public void register() {
mScreenStateObserver.register();
mWindowStateObserver.register();
+
+ // Obtain initial state.
+ mWindowStateObserver.getRegions(mMagnifiedRegion, mAvailableRegion);
+ mMagnifiedRegion.getBounds(mMagnifiedBounds);
}
/**
* Unregisters magnification-related observers.
*/
public void unregister() {
+ mSpecAnimationBridge.cancel();
+
mScreenStateObserver.unregister();
mWindowStateObserver.unregister();
}
@@ -149,8 +155,10 @@
final float offsetY = sentSpec.offsetY;
// Compute the new center and update spec as needed.
- final float centerX = (mMagnifiedBounds.width() / 2.0f - offsetX) / scale;
- final float centerY = (mMagnifiedBounds.height() / 2.0f - offsetY) / scale;
+ final float centerX = (mMagnifiedBounds.width() / 2.0f
+ + mMagnifiedBounds.left - offsetX) / scale;
+ final float centerY = (mMagnifiedBounds.height() / 2.0f
+ + mMagnifiedBounds.top - offsetY) / scale;
if (updateSpec) {
setScaleAndCenter(scale, centerX, centerY, false);
} else {
@@ -246,7 +254,8 @@
*/
public float getCenterX() {
synchronized (mLock) {
- return (mMagnifiedBounds.width() / 2.0f - getOffsetX()) / getScale();
+ return (mMagnifiedBounds.width() / 2.0f
+ + mMagnifiedBounds.left - getOffsetX()) / getScale();
}
}
@@ -268,7 +277,8 @@
*/
public float getCenterY() {
synchronized (mLock) {
- return (mMagnifiedBounds.height() / 2.0f - getOffsetY()) / getScale();
+ return (mMagnifiedBounds.height() / 2.0f
+ + mMagnifiedBounds.top - getOffsetY()) / getScale();
}
}
@@ -471,18 +481,25 @@
* otherwise
*/
private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
+ // Handle defaults.
+ if (Float.isNaN(centerX)) {
+ centerX = getCenterX();
+ }
+ if (Float.isNaN(centerY)) {
+ centerY = getCenterY();
+ }
+ if (Float.isNaN(scale)) {
+ scale = getScale();
+ }
+
+ // Ensure requested center is within the available region.
if (!availableRegionContains(centerX, centerY)) {
return false;
}
- boolean changed = false;
-
+ // Compute changes.
final MagnificationSpec currSpec = mCurrentMagnificationSpec;
-
- // Handle scale.
- if (Float.isNaN(scale)) {
- scale = getScale();
- }
+ boolean changed = false;
final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
if (Float.compare(currSpec.scale, normScale) != 0) {
@@ -490,24 +507,16 @@
changed = true;
}
- // Handle X offset.
- if (Float.isNaN(centerX)) {
- centerX = getCenterX();
- }
-
- final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f - centerX * scale;
+ final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f
+ + mMagnifiedBounds.left - centerX * scale;
final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
if (Float.compare(currSpec.offsetX, offsetX) != 0) {
currSpec.offsetX = offsetX;
changed = true;
}
- // Handle Y offset.
- if (Float.isNaN(centerY)) {
- centerY = getCenterY();
- }
-
- final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f - centerY * scale;
+ final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f
+ + mMagnifiedBounds.top - centerY * scale;
final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
if (Float.compare(currSpec.offsetY, offsetY) != 0) {
currSpec.offsetY = offsetY;
@@ -661,6 +670,12 @@
mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
}
+ public void cancel() {
+ if (mTransformationAnimator != null && mTransformationAnimator.isRunning()) {
+ mTransformationAnimator.cancel();
+ }
+ }
+
public void updateSentSpec(MagnificationSpec spec, boolean animate) {
if (Thread.currentThread().getId() == mMainThreadId) {
// Already on the main thread, don't bother proxying.
@@ -811,9 +826,6 @@
private static final int MESSAGE_ON_USER_CONTEXT_CHANGED = 3;
private static final int MESSAGE_ON_ROTATION_CHANGED = 4;
- private final Rect mTempRect = new Rect();
- private final Rect mTempRect1 = new Rect();
-
private final MagnificationController mController;
private final WindowManagerInternal mWindowManager;
private final Handler mHandler;
@@ -884,6 +896,10 @@
mController.resetIfNeeded(true);
}
+ public void getRegions(@NonNull Region outMagnified, @NonNull Region outAvailable) {
+ mWindowManager.getMagnificationRegions(outMagnified, outAvailable);
+ }
+
private class CallbackHandler extends Handler {
public CallbackHandler(Context context) {
super(context.getMainLooper());
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index b737ae2..6288b56 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1818,7 +1818,7 @@
File initSentinel = new File(stateDir, INIT_SENTINEL_FILE_NAME);
if (initSentinel.exists()) {
synchronized (mQueueLock) {
- mPendingInits.add(transportName);
+ mPendingInits.add(name);
// TODO: pick a better starting time than now + 1 minute
long delay = 1000 * 60; // one minute, in milliseconds
@@ -2316,6 +2316,25 @@
}
}
+ // What name is this transport registered under...?
+ private String getTransportName(IBackupTransport transport) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Searching for transport name of " + transport);
+ }
+ synchronized (mTransports) {
+ final int N = mTransports.size();
+ for (int i = 0; i < N; i++) {
+ if (mTransports.valueAt(i).equals(transport)) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, " Name found: " + mTransports.keyAt(i));
+ }
+ return mTransports.keyAt(i);
+ }
+ }
+ }
+ return null;
+ }
+
// fire off a backup agent, blocking until it attaches or times out
IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
IBackupAgent agent = null;
@@ -2921,7 +2940,15 @@
if (MORE_DEBUG) Slog.d(TAG, "Server requires init; rerunning");
addBackupTrace("init required; rerunning");
try {
- mPendingInits.add(mTransport.transportDirName());
+ final String name = getTransportName(mTransport);
+ if (name != null) {
+ mPendingInits.add(name);
+ } else {
+ if (DEBUG) {
+ Slog.w(TAG, "Couldn't find name of transport " + mTransport
+ + " for init");
+ }
+ }
} catch (Exception e) {
Slog.w(TAG, "Failed to query transport name heading for init", e);
// swallow it and proceed; we don't rely on this
@@ -7590,77 +7617,6 @@
// ----- Restore handling -----
- // new style: we only store the SHA-1 hashes of each sig, not the full block
- static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
- if (target == null) {
- return false;
- }
-
- // If the target resides on the system partition, we allow it to restore
- // data from the like-named package in a restore set even if the signatures
- // do not match. (Unlike general applications, those flashed to the system
- // partition will be signed with the device's platform certificate, so on
- // different phones the same system app will have different signatures.)
- if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- if (MORE_DEBUG) Slog.v(TAG, "System app " + target.packageName + " - skipping sig check");
- return true;
- }
-
- // Allow unsigned apps, but not signed on one device and unsigned on the other
- // !!! TODO: is this the right policy?
- Signature[] deviceSigs = target.signatures;
- if (MORE_DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes
- + " device=" + deviceSigs);
- if ((storedSigHashes == null || storedSigHashes.size() == 0)
- && (deviceSigs == null || deviceSigs.length == 0)) {
- return true;
- }
- if (storedSigHashes == null || deviceSigs == null) {
- return false;
- }
-
- // !!! TODO: this demands that every stored signature match one
- // that is present on device, and does not demand the converse.
- // Is this this right policy?
- final int nStored = storedSigHashes.size();
- final int nDevice = deviceSigs.length;
-
- // hash each on-device signature
- ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
- for (int i = 0; i < nDevice; i++) {
- deviceHashes.add(hashSignature(deviceSigs[i]));
- }
-
- // now ensure that each stored sig (hash) matches an on-device sig (hash)
- for (int n = 0; n < nStored; n++) {
- boolean match = false;
- final byte[] storedHash = storedSigHashes.get(n);
- for (int i = 0; i < nDevice; i++) {
- if (Arrays.equals(storedHash, deviceHashes.get(i))) {
- match = true;
- break;
- }
- }
- // match is false when no on-device sig matched one of the stored ones
- if (!match) {
- return false;
- }
- }
-
- return true;
- }
-
- static byte[] hashSignature(Signature sig) {
- try {
- MessageDigest digest = MessageDigest.getInstance("SHA-256");
- digest.update(sig.toByteArray());
- return digest.digest();
- } catch (NoSuchAlgorithmException e) {
- Slog.w(TAG, "No SHA-256 algorithm found!");
- }
- return null;
- }
-
// Old style: directly match the stored vs on device signature blocks
static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) {
if (target == null) {
@@ -8173,7 +8129,7 @@
}
Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName);
- if (!signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
+ if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
Slog.w(TAG, "Signature mismatch restoring " + packageName);
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
"Signature mismatch");
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index f197c1e..09f240f 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -205,7 +205,7 @@
PackageManager.GET_SIGNATURES);
homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
homeVersion = homeInfo.versionCode;
- homeSigHashes = hashSignatureArray(homeInfo.signatures);
+ homeSigHashes = BackupUtils.hashSignatureArray(homeInfo.signatures);
} catch (NameNotFoundException e) {
Slog.w(TAG, "Can't access preferred home info");
// proceed as though there were no preferred home set
@@ -222,7 +222,7 @@
final boolean needHomeBackup = (homeVersion != mStoredHomeVersion)
|| !Objects.equals(home, mStoredHomeComponent)
|| (home != null
- && !BackupManagerService.signaturesMatch(mStoredHomeSigHashes, homeInfo));
+ && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo));
if (needHomeBackup) {
if (DEBUG) {
Slog.i(TAG, "Home preference changed; backing up new state " + home);
@@ -309,7 +309,7 @@
outputBuffer.reset();
outputBufferStream.writeInt(info.versionCode);
writeSignatureHashArray(outputBufferStream,
- hashSignatureArray(info.signatures));
+ BackupUtils.hashSignatureArray(info.signatures));
if (DEBUG) {
Slog.v(TAG, "+ writing metadata for " + packName
@@ -432,18 +432,6 @@
mRestoredSignatures = sigMap;
}
- private static ArrayList<byte[]> hashSignatureArray(Signature[] sigs) {
- if (sigs == null) {
- return null;
- }
-
- ArrayList<byte[]> hashes = new ArrayList<byte[]>(sigs.length);
- for (Signature s : sigs) {
- hashes.add(BackupManagerService.hashSignature(s));
- }
- return hashes;
- }
-
private static void writeSignatureHashArray(DataOutputStream out, ArrayList<byte[]> hashes)
throws IOException {
// the number of entries in the array
@@ -492,13 +480,8 @@
}
if (nonHashFound) {
- ArrayList<byte[]> hashes =
- new ArrayList<byte[]>(sigs.size());
- for (int i = 0; i < sigs.size(); i++) {
- Signature s = new Signature(sigs.get(i));
- hashes.add(BackupManagerService.hashSignature(s));
- }
- sigs = hashes;
+ // Replace with the hashes.
+ sigs = BackupUtils.hashSignatureArray(sigs);
}
return sigs;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index e7db2a8..57ba1b9 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -25,7 +25,6 @@
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -1645,7 +1644,9 @@
int userId = UserHandle.USER_SYSTEM;
String packageName;
String opStr;
+ String modeStr;
int op;
+ int mode;
int packageUid;
Shell(IAppOpsService iface, AppOpsService internal) {
@@ -1681,6 +1682,59 @@
}
}
+ int strModeToMode(String modeStr, PrintWriter err) {
+ switch (modeStr) {
+ case "allow":
+ return AppOpsManager.MODE_ALLOWED;
+ case "deny":
+ return AppOpsManager.MODE_ERRORED;
+ case "ignore":
+ return AppOpsManager.MODE_IGNORED;
+ case "default":
+ return AppOpsManager.MODE_DEFAULT;
+ }
+ try {
+ return Integer.parseInt(modeStr);
+ } catch (NumberFormatException e) {
+ }
+ err.println("Error: Mode " + modeStr + " is not valid");
+ return -1;
+ }
+
+ int parseUserOpMode(int defMode, PrintWriter err) throws RemoteException {
+ userId = UserHandle.USER_CURRENT;
+ opStr = null;
+ modeStr = null;
+ for (String argument; (argument = getNextArg()) != null;) {
+ if ("--user".equals(argument)) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ if (opStr == null) {
+ opStr = argument;
+ } else if (modeStr == null) {
+ modeStr = argument;
+ break;
+ }
+ }
+ }
+ if (opStr == null) {
+ err.println("Error: Operation not specified.");
+ return -1;
+ }
+ op = strOpToOp(opStr, err);
+ if (op < 0) {
+ return -1;
+ }
+ if (modeStr != null) {
+ if ((mode=strModeToMode(modeStr, err)) < 0) {
+ return -1;
+ }
+ } else {
+ mode = defMode;
+ }
+ return 0;
+ }
+
int parseUserPackageOp(boolean reqOp, PrintWriter err) throws RemoteException {
userId = UserHandle.USER_CURRENT;
packageName = null;
@@ -1742,6 +1796,8 @@
pw.println(" Set the mode for a particular application and operation.");
pw.println(" get [--user <USER_ID>] <PACKAGE> [<OP>]");
pw.println(" Return the mode for a particular application and optional operation.");
+ pw.println(" query-op [--user <USER_ID>] <OP> [<MODE>]");
+ pw.println(" Print all packages that currently have the given op in the given mode.");
pw.println(" reset [--user <USER_ID>] [<PACKAGE>]");
pw.println(" Reset the given application or all applications to default modes.");
pw.println(" write-settings");
@@ -1775,23 +1831,9 @@
return -1;
}
- final int mode;
- switch (modeStr) {
- case "allow":
- mode = AppOpsManager.MODE_ALLOWED;
- break;
- case "deny":
- mode = AppOpsManager.MODE_ERRORED;
- break;
- case "ignore":
- mode = AppOpsManager.MODE_IGNORED;
- break;
- case "default":
- mode = AppOpsManager.MODE_DEFAULT;
- break;
- default:
- err.println("Error: Mode " + modeStr + " is not valid,");
- return -1;
+ final int mode = shell.strModeToMode(modeStr, err);
+ if (mode < 0) {
+ return -1;
}
shell.mInterface.setMode(shell.op, shell.packageUid, shell.packageName, mode);
@@ -1856,6 +1898,34 @@
}
return 0;
}
+ case "query-op": {
+ int res = shell.parseUserOpMode(AppOpsManager.MODE_IGNORED, err);
+ if (res < 0) {
+ return res;
+ }
+ List<AppOpsManager.PackageOps> ops = shell.mInterface.getPackagesForOps(
+ new int[] {shell.op});
+ if (ops == null || ops.size() <= 0) {
+ pw.println("No operations.");
+ return 0;
+ }
+ for (int i=0; i<ops.size(); i++) {
+ final AppOpsManager.PackageOps pkg = ops.get(i);
+ boolean hasMatch = false;
+ final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
+ for (int j=0; j<entries.size(); j++) {
+ AppOpsManager.OpEntry ent = entries.get(j);
+ if (ent.getOp() == shell.op && ent.getMode() == shell.mode) {
+ hasMatch = true;
+ break;
+ }
+ }
+ if (hasMatch) {
+ pw.println(pkg.getPackageName());
+ }
+ }
+ return 0;
+ }
case "reset": {
String packageName = null;
int userId = UserHandle.USER_CURRENT;
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6fb0671..ed16af51 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -42,7 +42,10 @@
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.Parcel;
import android.os.RemoteException;
import android.os.storage.IMountService;
import android.os.ServiceManager;
@@ -56,6 +59,7 @@
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
@@ -70,6 +74,8 @@
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Keeps the lock pattern/password data and related settings for each user.
@@ -590,11 +596,37 @@
}
private void unlockUser(int userId, byte[] token, byte[] secret) {
+ // TODO: make this method fully async so we can update UI with progress strings
+ final CountDownLatch latch = new CountDownLatch(1);
+ final IProgressListener listener = new IProgressListener.Stub() {
+ @Override
+ public void onStarted(int id, Bundle extras) throws RemoteException {
+ // Ignored
+ }
+
+ @Override
+ public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
+ // Ignored
+ }
+
+ @Override
+ public void onFinished(int id, Bundle extras) throws RemoteException {
+ Log.d(TAG, "unlockUser finished!");
+ latch.countDown();
+ }
+ };
+
try {
- ActivityManagerNative.getDefault().unlockUser(userId, token, secret);
+ ActivityManagerNative.getDefault().unlockUser(userId, token, secret, listener);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
+
+ try {
+ latch.await(15, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
}
private byte[] getCurrentHandle(int userId) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index ccca5ba..45008dc 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -2912,36 +2912,57 @@
@Override
public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
final int userId = UserHandle.getUserId(uid);
+
final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;
+ final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0;
+ final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0;
- boolean reportUnmounted = false;
- boolean foundPrimary = false;
-
- final long identity = Binder.clearCallingIdentity();
+ final boolean userKeyUnlocked;
+ final boolean storagePermission;
+ final long token = Binder.clearCallingIdentity();
try {
- if (!mMountServiceInternal.hasExternalStorage(uid, packageName)) {
- reportUnmounted = true;
- }
- if (!isUserKeyUnlocked(userId)) {
- reportUnmounted = true;
- }
+ userKeyUnlocked = isUserKeyUnlocked(userId);
+ storagePermission = mMountServiceInternal.hasExternalStorage(uid, packageName);
} finally {
- Binder.restoreCallingIdentity(identity);
+ Binder.restoreCallingIdentity(token);
}
+ boolean foundPrimary = false;
+
final ArrayList<StorageVolume> res = new ArrayList<>();
synchronized (mLock) {
for (int i = 0; i < mVolumes.size(); i++) {
final VolumeInfo vol = mVolumes.valueAt(i);
- if (forWrite ? vol.isVisibleForWrite(userId) : vol.isVisibleForRead(userId)) {
- final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
- reportUnmounted);
- if (vol.isPrimary()) {
- res.add(0, userVol);
- foundPrimary = true;
- } else {
- res.add(userVol);
- }
+ switch (vol.getType()) {
+ case VolumeInfo.TYPE_PUBLIC:
+ case VolumeInfo.TYPE_EMULATED:
+ break;
+ default:
+ continue;
+ }
+
+ boolean match = false;
+ if (forWrite) {
+ match = vol.isVisibleForWrite(userId);
+ } else {
+ match = vol.isVisibleForRead(userId) || includeInvisible;
+ }
+ if (!match) continue;
+
+ boolean reportUnmounted = false;
+ if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
+ reportUnmounted = true;
+ } else if (!storagePermission && !realState) {
+ reportUnmounted = true;
+ }
+
+ final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
+ reportUnmounted);
+ if (vol.isPrimary()) {
+ res.add(0, userVol);
+ foundPrimary = true;
+ } else {
+ res.add(userVol);
}
}
}
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/RecoverySystemService.java
index d284d07..276687f 100644
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ b/services/core/java/com/android/server/RecoverySystemService.java
@@ -79,7 +79,7 @@
uncryptFile.write(filename + "\n");
} catch (IOException e) {
Slog.e(TAG, "IOException when writing \"" + RecoverySystem.UNCRYPT_PACKAGE_FILE +
- "\": " + e.getMessage());
+ "\": ", e);
return false;
}
@@ -94,8 +94,11 @@
}
// Read the status from the socket.
- try (DataInputStream dis = new DataInputStream(socket.getInputStream());
- DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
+ DataInputStream dis = null;
+ DataOutputStream dos = null;
+ try {
+ dis = new DataInputStream(socket.getInputStream());
+ dos = new DataOutputStream(socket.getOutputStream());
int lastStatus = Integer.MIN_VALUE;
while (true) {
int status = dis.readInt();
@@ -111,7 +114,7 @@
if (listener != null) {
try {
listener.onProgress(status);
- } catch (RemoteException unused) {
+ } catch (RemoteException ignored) {
Slog.w(TAG, "RemoteException when posting progress");
}
}
@@ -121,7 +124,6 @@
// waits for the ack so the socket won't be
// destroyed before we receive the code.
dos.writeInt(0);
- dos.flush();
break;
}
} else {
@@ -131,14 +133,15 @@
// for the ack so the socket won't be destroyed before
// we receive the code.
dos.writeInt(0);
- dos.flush();
return false;
}
}
} catch (IOException e) {
- Slog.e(TAG, "IOException when reading status: " + e);
+ Slog.e(TAG, "IOException when reading status: ", e);
return false;
} finally {
+ IoUtils.closeQuietly(dis);
+ IoUtils.closeQuietly(dos);
IoUtils.closeQuietly(socket);
}
@@ -169,11 +172,11 @@
LocalSocketAddress.Namespace.RESERVED));
done = true;
break;
- } catch (IOException unused) {
+ } catch (IOException ignored) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
- Slog.w(TAG, "Interrupted: " + e);
+ Slog.w(TAG, "Interrupted: ", e);
}
}
}
@@ -200,8 +203,12 @@
return false;
}
- try (DataInputStream dis = new DataInputStream(socket.getInputStream());
- DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
+ DataInputStream dis = null;
+ DataOutputStream dos = null;
+ try {
+ dis = new DataInputStream(socket.getInputStream());
+ dos = new DataOutputStream(socket.getOutputStream());
+
// Send the BCB commands if it's to setup BCB.
if (isSetup) {
dos.writeInt(command.length());
@@ -215,7 +222,6 @@
// Ack receipt of the status code. uncrypt waits for the ack so
// the socket won't be destroyed before we receive the code.
dos.writeInt(0);
- dos.flush();
if (status == 100) {
Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear") +
@@ -226,9 +232,11 @@
return false;
}
} catch (IOException e) {
- Slog.e(TAG, "IOException when getting output stream: " + e);
+ Slog.e(TAG, "IOException when communicating with uncrypt: ", e);
return false;
} finally {
+ IoUtils.closeQuietly(dis);
+ IoUtils.closeQuietly(dos);
IoUtils.closeQuietly(socket);
}
diff --git a/services/core/java/com/android/server/ThermalObserver.java b/services/core/java/com/android/server/ThermalObserver.java
deleted file mode 100644
index aee28fb..0000000
--- a/services/core/java/com/android/server/ThermalObserver.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.UEventObserver;
-import android.os.UserHandle;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * ThermalObserver for monitoring temperature changes.
- */
-public class ThermalObserver extends SystemService {
- private static final String TAG = "ThermalObserver";
-
- private static final String CALLSTATE_UEVENT_MATCH =
- "DEVPATH=/devices/virtual/switch/thermalstate";
-
- private static final int MSG_THERMAL_STATE_CHANGED = 0;
-
- private static final int SWITCH_STATE_NORMAL = 0;
- private static final int SWITCH_STATE_WARNING = 1;
- private static final int SWITCH_STATE_EXCEEDED = 2;
-
- private final PowerManager mPowerManager;
- private final PowerManager.WakeLock mWakeLock;
-
- private final Object mLock = new Object();
- private Integer mLastState;
-
- private final UEventObserver mThermalWarningObserver = new UEventObserver() {
- @Override
- public void onUEvent(UEventObserver.UEvent event) {
- updateLocked(Integer.parseInt(event.get("SWITCH_STATE")));
- }
- };
-
- private final Handler mHandler = new Handler(true /*async*/) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_THERMAL_STATE_CHANGED:
- handleThermalStateChange(msg.arg1);
- mWakeLock.release();
- break;
- }
- }
- };
-
- public ThermalObserver(Context context) {
- super(context);
- mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
-
- mThermalWarningObserver.startObserving(CALLSTATE_UEVENT_MATCH);
- }
-
- private void updateLocked(int state) {
- Message message = new Message();
- message.what = MSG_THERMAL_STATE_CHANGED;
- message.arg1 = state;
-
- mWakeLock.acquire();
- mHandler.sendMessage(message);
- }
-
- private void handleThermalStateChange(int state) {
- synchronized (mLock) {
- mLastState = state;
- Intent intent = new Intent(Intent.ACTION_THERMAL_EVENT);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-
- final int thermalState;
-
- switch (state) {
- case SWITCH_STATE_WARNING:
- thermalState = Intent.EXTRA_THERMAL_STATE_WARNING;
- break;
- case SWITCH_STATE_EXCEEDED:
- thermalState = Intent.EXTRA_THERMAL_STATE_EXCEEDED;
- break;
- case SWITCH_STATE_NORMAL:
- default:
- thermalState = Intent.EXTRA_THERMAL_STATE_NORMAL;
- break;
- }
-
- intent.putExtra(Intent.EXTRA_THERMAL_STATE, thermalState);
-
- getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
- }
- }
-
- @Override
- public void onStart() {
- publishBinderService(TAG, new BinderService());
- }
-
- private final class BinderService extends Binder {
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump thermal observer service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- if (args == null || args.length == 0 || "-a".equals(args[0])) {
- pw.println("Current Thermal Observer Service state:");
- pw.println(" last state change: "
- + (mLastState != null ? mLastState : "none"));
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f51fb6c..f99caba 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -43,7 +43,8 @@
import android.util.ArrayMap;
import android.util.ArraySet;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ServiceState;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastPrintWriter;
@@ -61,7 +62,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -480,7 +480,7 @@
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
- ProcessStats.ServiceState stracker = r.getTracker();
+ ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
@@ -932,7 +932,7 @@
s.lastActivity = SystemClock.uptimeMillis();
if (!s.hasAutoCreateConnections()) {
// This is the first binding, let the tracker know.
- ProcessStats.ServiceState stracker = s.getTracker();
+ ServiceState stracker = s.getTracker();
if (stracker != null) {
stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
s.lastActivity);
@@ -1279,7 +1279,7 @@
// Before going further -- if this app is not allowed to run in the
// background, then at this point we aren't going to let it period.
final int allowed = mAm.checkAllowBackgroundLocked(
- sInfo.applicationInfo.uid, sInfo.packageName, callingPid);
+ sInfo.applicationInfo.uid, sInfo.packageName, callingPid, true);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
Slog.w(TAG, "Background execution not allowed: service "
+ service + " to " + name.flattenToShortString()
@@ -1365,7 +1365,7 @@
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0) {
r.executeFg = fg;
- ProcessStats.ServiceState stracker = r.getTracker();
+ ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3d13715..cd4d472 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -26,8 +26,8 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.ProcessMap;
-import com.android.internal.app.ProcessStats;
import com.android.internal.app.SystemUserHomeActivity;
+import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.IResultReceiver;
@@ -40,6 +40,7 @@
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.ProgressReporter;
import com.android.server.AppOpsService;
import com.android.server.AttributeCache;
import com.android.server.DeviceIdleController;
@@ -165,6 +166,7 @@
import android.os.IBinder;
import android.os.IPermissionController;
import android.os.IProcessInfoService;
+import android.os.IProgressListener;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
@@ -214,10 +216,6 @@
import android.view.View;
import android.view.WindowManager;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -363,9 +361,6 @@
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
- // File that stores last updated system version and called preboot receivers
- static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
-
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
@@ -500,8 +495,6 @@
static final int ALLOW_NON_FULL_IN_PROFILE = 1;
static final int ALLOW_FULL_ONLY = 2;
- static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
-
// Delay in notifying task stack change listeners (in millis)
static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -1112,8 +1105,6 @@
boolean mBooting = false;
boolean mCallFinishBooting = false;
boolean mBootAnimationComplete = false;
- boolean mWaitingUpdate = false;
- boolean mDidUpdate = false;
boolean mOnBattery = false;
boolean mLaunchWarningShown = false;
@@ -1497,7 +1488,6 @@
final ServiceThread mHandlerThread;
final MainHandler mHandler;
final UiHandler mUiHandler;
- final ProcessStartLogger mProcessStartLogger;
PackageManagerInternal mPackageManagerInt;
@@ -2469,8 +2459,6 @@
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
- mProcessStartLogger = new ProcessStartLogger();
-
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
@@ -3603,7 +3591,12 @@
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
- mProcessStartLogger.logIfNeededLocked(app, startResult);
+ try {
+ AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
+ app.info.seinfo, app.info.sourceDir, startResult.pid);
+ } catch (RemoteException ex) {
+ // Ignore
+ }
if (app.persistent) {
Watchdog.getInstance().processStarted(app.processName, startResult.pid);
@@ -6228,6 +6221,7 @@
app.debugging = false;
app.cached = false;
app.killedByAm = false;
+ app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
@@ -6545,8 +6539,6 @@
}
}, dumpheapFilter);
- mProcessStartLogger.registerListener(mContext);
-
// Let system services know.
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
@@ -7543,14 +7535,15 @@
public int getAppStartMode(int uid, String packageName) {
synchronized (this) {
- return checkAllowBackgroundLocked(uid, packageName, -1);
+ return checkAllowBackgroundLocked(uid, packageName, -1, true);
}
}
- int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
+ int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
+ boolean allowWhenForeground) {
UidRecord uidRec = mActiveUids.get(uid);
if (!mLenientBackgroundCheck) {
- if (uidRec == null
+ if (!allowWhenForeground || uidRec == null
|| uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
packageName) != AppOpsManager.MODE_ALLOWED) {
@@ -8853,10 +8846,11 @@
continue;
}
}
- if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
- if (tr.stack != null && tr.stack.isDockedStack()) {
+ if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
+ final ActivityStack stack = tr.stack;
+ if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, docked stack task: " + tr);
+ "Skipping, top task in docked stack: " + tr);
continue;
}
}
@@ -10351,7 +10345,7 @@
}
checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
- if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
+ if (!mProcessesReady
&& !cpi.processName.equals("system")) {
// If this content provider does not run in the system
// process, and the system is not yet ready to run other
@@ -10942,7 +10936,7 @@
final int NA = apps.size();
for (int ia = 0; ia < NA; ia++) {
final ProcessRecord app = apps.valueAt(ia);
- if (app.userId != userId || app.thread == null) continue;
+ if (app.userId != userId || app.thread == null || app.unlocked) continue;
final int NG = app.pkgList.size();
for (int ig = 0; ig < NG; ig++) {
@@ -12574,187 +12568,6 @@
return mSystemReady;
}
- private static File getCalledPreBootReceiversFile() {
- File dataDir = Environment.getDataDirectory();
- File systemDir = new File(dataDir, "system");
- File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
- return fname;
- }
-
- private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
- ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
- File file = getCalledPreBootReceiversFile();
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(file);
- DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
- int fvers = dis.readInt();
- if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
- String vers = dis.readUTF();
- String codename = dis.readUTF();
- String build = dis.readUTF();
- if (android.os.Build.VERSION.RELEASE.equals(vers)
- && android.os.Build.VERSION.CODENAME.equals(codename)
- && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
- int num = dis.readInt();
- while (num > 0) {
- num--;
- String pkg = dis.readUTF();
- String cls = dis.readUTF();
- lastDoneReceivers.add(new ComponentName(pkg, cls));
- }
- }
- }
- } catch (FileNotFoundException e) {
- } catch (IOException e) {
- Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- }
- }
- }
- return lastDoneReceivers;
- }
-
- private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
- File file = getCalledPreBootReceiversFile();
- FileOutputStream fos = null;
- DataOutputStream dos = null;
- try {
- fos = new FileOutputStream(file);
- dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
- dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
- dos.writeUTF(android.os.Build.VERSION.RELEASE);
- dos.writeUTF(android.os.Build.VERSION.CODENAME);
- dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
- dos.writeInt(list.size());
- for (int i=0; i<list.size(); i++) {
- dos.writeUTF(list.get(i).getPackageName());
- dos.writeUTF(list.get(i).getClassName());
- }
- } catch (IOException e) {
- Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
- file.delete();
- } finally {
- FileUtils.sync(fos);
- if (dos != null) {
- try {
- dos.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
-
- final class PreBootContinuation extends IIntentReceiver.Stub {
- final Intent intent;
- final Runnable onFinishCallback;
- final ArrayList<ComponentName> doneReceivers;
- final List<ResolveInfo> ris;
- final int[] users;
- int lastRi = -1;
- int curRi = 0;
- int curUser = 0;
-
- PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
- ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
- intent = _intent;
- onFinishCallback = _onFinishCallback;
- doneReceivers = _doneReceivers;
- ris = _ris;
- users = _users;
- }
-
- void go() {
- if (lastRi != curRi) {
- ActivityInfo ai = ris.get(curRi).activityInfo;
- ComponentName comp = new ComponentName(ai.packageName, ai.name);
- intent.setComponent(comp);
- doneReceivers.add(comp);
- lastRi = curRi;
- CharSequence label = ai.loadLabel(mContext.getPackageManager());
- showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
- }
- Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
- + " for user " + users[curUser]);
- EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
- broadcastIntentLocked(null, null, intent, null, this,
- 0, null, null, null, AppOpsManager.OP_NONE,
- null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
- }
-
- public void performReceive(Intent intent, int resultCode,
- String data, Bundle extras, boolean ordered,
- boolean sticky, int sendingUser) {
- curUser++;
- if (curUser >= users.length) {
- curUser = 0;
- curRi++;
- if (curRi >= ris.size()) {
- // All done sending broadcasts!
- if (onFinishCallback != null) {
- // The raw IIntentReceiver interface is called
- // with the AM lock held, so redispatch to
- // execute our code without the lock.
- mHandler.post(onFinishCallback);
- }
- return;
- }
- }
- go();
- }
- }
-
- private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
- ArrayList<ComponentName> doneReceivers) {
- Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
- List<ResolveInfo> ris = null;
- try {
- ris = AppGlobals.getPackageManager().queryIntentReceivers(
- intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
- } catch (RemoteException e) {
- }
- if (ris == null) {
- return false;
- }
- intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
-
- ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
- for (int i=0; i<ris.size(); i++) {
- ActivityInfo ai = ris.get(i).activityInfo;
- ComponentName comp = new ComponentName(ai.packageName, ai.name);
- if (lastDoneReceivers.contains(comp)) {
- // We already did the pre boot receiver for this app with the current
- // platform version, so don't do it again...
- ris.remove(i);
- i--;
- // ...however, do keep it as one that has been done, so we don't
- // forget about it when rewriting the file of last done receivers.
- doneReceivers.add(comp);
- }
- }
-
- if (ris.size() <= 0) {
- return false;
- }
-
- // TODO: can we still do this with per user encryption?
- final int[] users = mUserController.getUsers();
- if (users.length <= 0) {
- return false;
- }
-
- PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
- ris, users);
- cont.go();
- return true;
- }
-
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
@@ -12771,33 +12584,7 @@
// Make sure we have the current profile info, since it is needed for security checks.
mUserController.onSystemReady();
-
mRecentTasks.onSystemReadyLocked();
- // Check to see if there are any update receivers to run.
- if (!mDidUpdate) {
- if (mWaitingUpdate) {
- return;
- }
- final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
- mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
- public void run() {
- synchronized (ActivityManagerService.this) {
- mDidUpdate = true;
- }
- showBootMessage(mContext.getText(
- R.string.android_upgrading_complete),
- false);
- writeLastDonePreBootReceivers(doneReceivers);
- systemReady(goingCallback);
- }
- }, doneReceivers);
-
- if (mWaitingUpdate) {
- return;
- }
- mDidUpdate = true;
- }
-
mAppOpsService.systemReady();
mSystemReady = true;
}
@@ -18577,9 +18364,14 @@
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.app != app) {
- Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
- + app + "?!? Using " + r.app + " instead.");
- continue;
+ Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
+ + " instead of expected " + app);
+ if (r.app == null || (r.app.uid == app.uid)) {
+ // Only fix things up when they look sane
+ r.app = app;
+ } else {
+ continue;
+ }
}
if (r.visible) {
// App has a visible activity; only upgrade adjustment.
@@ -20725,8 +20517,8 @@
}
@Override
- public boolean unlockUser(int userId, byte[] token, byte[] secret) {
- return mUserController.unlockUser(userId, token, secret);
+ public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
+ return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ee406da..a9ef1d6 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1871,7 +1871,6 @@
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
- mStackSupervisor.mWaitingVisibleActivities.remove(r);
} catch (Exception e) {
// Just skip on any failure; we'll make it
// visible when it next restarts.
@@ -3090,10 +3089,14 @@
return false;
}
- if (stack.isHomeStack()) {
+ final ActivityRecord top = stack.topRunningActivityLocked();
+
+ if (stack.isHomeStack() && (top == null || !top.visible)) {
+ // If we will be focusing on the home stack next and its current top activity isn't
+ // visible, then use the task return to value to determine the home task to display next.
return mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, reason);
}
- return mService.setFocusedActivityLocked(stack.topRunningActivityLocked(), myReason);
+ return mService.setFocusedActivityLocked(top, myReason);
}
final void stopActivityLocked(ActivityRecord r) {
@@ -4784,6 +4787,8 @@
" Task id #" + task.taskId + "\n" +
" mFullscreen=" + task.mFullscreen + "\n" +
" mBounds=" + task.mBounds + "\n" +
+ " mMinimalWidth=" + task.mMinimalWidth + "\n" +
+ " mMinimalHeight=" + task.mMinimalHeight + "\n" +
" mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
if (printed) {
header = null;
@@ -4932,18 +4937,18 @@
// add the task to stack first, mTaskPositioner might need the stack association
addTask(task, toTop, "createTaskRecord");
final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN;
- if (!layoutTaskInStack(task, info.layout) && mBounds != null && task.isResizeable()
+ if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
&& !isLockscreenShown) {
task.updateOverrideConfiguration(mBounds);
}
return task;
}
- boolean layoutTaskInStack(TaskRecord task, ActivityInfo.Layout layout) {
+ boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) {
if (mTaskPositioner == null) {
return false;
}
- mTaskPositioner.updateDefaultBounds(task, mTaskHistory, layout);
+ mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout);
return true;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 0e6d174..950320e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1798,7 +1798,7 @@
// WM resizeTask must be done after the task is moved to the correct stack,
// because Task's setBounds() also updates dim layer's bounds, but that has
// dependency on the stack.
- mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig,
+ mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig,
false /* relayout */, false /* forced */);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index e3ca3ea..3bbc452 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -947,8 +947,6 @@
// We didn't do anything... but it was needed (a.k.a., client don't use that
// intent!) And for paranoia, make sure we have correctly resumed the top activity.
resumeTargetStackIfNeeded();
- mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
- preferredLaunchStackId, mTargetStack.mStackId);
return START_TASK_TO_FRONT;
}
}
@@ -989,7 +987,7 @@
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
- preferredLaunchStackId, mTargetStack.mStackId);
+ preferredLaunchStackId, topStack.mStackId);
return START_DELIVERED_TO_TOP;
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index ffa3b5b..3d42047 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1224,7 +1224,8 @@
// WiFi keeps an accumulated total of stats, unlike Bluetooth.
// Keep the last WiFi stats so we can compute a delta.
@GuardedBy("mExternalStatsLock")
- private WifiActivityEnergyInfo mLastInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
+ private WifiActivityEnergyInfo mLastInfo =
+ new WifiActivityEnergyInfo(0, 0, 0, new long[]{0}, 0, 0, 0);
@GuardedBy("mExternalStatsLock")
private WifiActivityEnergyInfo pullWifiEnergyInfoLocked() {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 45e3a76..37c7765 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -50,7 +50,6 @@
import android.util.Slog;
import android.util.TimeUtils;
import com.android.server.DeviceIdleController;
-import com.android.server.LocalServices;
import static com.android.server.am.ActivityManagerDebugConfig.*;
@@ -563,7 +562,7 @@
}
if (!skip) {
final int allowed = mService.checkAllowBackgroundLocked(filter.receiverList.uid,
- filter.packageName, -1);
+ filter.packageName, -1, true);
if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
Slog.w(TAG, "Background execution not allowed: receiving "
+ r.intent
@@ -1102,21 +1101,21 @@
if (!skip) {
final int allowed = mService.checkAllowBackgroundLocked(
- info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, -1);
+ info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, -1,
+ false);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
// We won't allow this receiver to be launched if the app has been
- // completely disabled from launches, or it is delayed and the broadcast
- // was not explicitly sent to it and this would result in a new process
- // for it being created.
+ // completely disabled from launches, or it was not explicitly sent
+ // to it and the app is in a state that should not receive it
+ // (depending on how checkAllowBackgroundLocked has determined that).
if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
Slog.w(TAG, "Background execution disabled: receiving "
+ r.intent + " to "
+ component.flattenToShortString());
skip = true;
- }
- if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
+ } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
|| (r.intent.getComponent() == null
- && r.intent.getPackage() == null && app == null
+ && r.intent.getPackage() == null
&& ((r.intent.getFlags()
& Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0))) {
Slog.w(TAG, "Background execution not allowed: receiving "
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 4ba1d0d..d652341 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -109,22 +109,22 @@
*
* @param task Task for which we want to find bounds that won't collide with other.
* @param tasks Existing tasks with which we don't want to collide.
- * @param layout Optional information from the client about how it would like to be sized
+ * @param windowLayout Optional information from the client about how it would like to be sized
* and positioned.
*/
void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
- @Nullable ActivityInfo.Layout layout) {
+ @Nullable ActivityInfo.WindowLayout windowLayout) {
if (!mDefaultStartBoundsConfigurationSet) {
return;
}
- if (layout == null) {
+ if (windowLayout == null) {
positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
return;
}
- int width = getFinalWidth(layout);
- int height = getFinalHeight(layout);
- int verticalGravity = layout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
- int horizontalGravity = layout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ int width = getFinalWidth(windowLayout);
+ int height = getFinalHeight(windowLayout);
+ int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
+ int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if (verticalGravity == Gravity.TOP) {
if (horizontalGravity == Gravity.RIGHT) {
positionTopRight(task, tasks, width, height);
@@ -140,30 +140,30 @@
} else {
// Some fancy gravity setting that we don't support yet. We just put the activity in the
// center.
- Slog.w(TAG, "Received unsupported gravity: " + layout.gravity
+ Slog.w(TAG, "Received unsupported gravity: " + windowLayout.gravity
+ ", positioning in the center instead.");
positionCenter(task, tasks, width, height);
}
}
- private int getFinalWidth(ActivityInfo.Layout layout) {
+ private int getFinalWidth(ActivityInfo.WindowLayout windowLayout) {
int width = mDefaultFreeformWidth;
- if (layout.width > 0) {
- width = layout.width;
+ if (windowLayout.width > 0) {
+ width = windowLayout.width;
}
- if (layout.widthFraction > 0) {
- width = (int) (mAvailableRect.width() * layout.widthFraction);
+ if (windowLayout.widthFraction > 0) {
+ width = (int) (mAvailableRect.width() * windowLayout.widthFraction);
}
return width;
}
- private int getFinalHeight(ActivityInfo.Layout layout) {
+ private int getFinalHeight(ActivityInfo.WindowLayout windowLayout) {
int height = mDefaultFreeformHeight;
- if (layout.height > 0) {
- height = layout.height;
+ if (windowLayout.height > 0) {
+ height = windowLayout.height;
}
- if (layout.heightFraction > 0) {
- height = (int) (mAvailableRect.height() * layout.heightFraction);
+ if (windowLayout.heightFraction > 0) {
+ height = (int) (mAvailableRect.height() * windowLayout.heightFraction);
}
return height;
}
diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java
new file mode 100644
index 0000000..1825c88
--- /dev/null
+++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.util.ProgressReporter;
+
+import java.util.List;
+
+/**
+ * Simple broadcaster that sends {@link Intent#ACTION_PRE_BOOT_COMPLETED} to all
+ * system apps that register for it. Override {@link #onFinished()} to handle
+ * when all broadcasts are finished.
+ */
+public abstract class PreBootBroadcaster extends IIntentReceiver.Stub {
+ private static final String TAG = "PreBootBroadcaster";
+
+ private final ActivityManagerService mService;
+ private final int mUserId;
+ private final ProgressReporter mProgress;
+
+ private final Intent mIntent;
+ private final List<ResolveInfo> mTargets;
+
+ private int mIndex = 0;
+
+ public PreBootBroadcaster(ActivityManagerService service, int userId,
+ ProgressReporter progress) {
+ mService = service;
+ mUserId = userId;
+ mProgress = progress;
+
+ mIntent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
+ mIntent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
+
+ mTargets = mService.mContext.getPackageManager().queryBroadcastReceiversAsUser(mIntent,
+ MATCH_SYSTEM_ONLY, UserHandle.of(userId));
+ }
+
+ public void sendNext() {
+ if (mIndex >= mTargets.size()) {
+ onFinished();
+ return;
+ }
+
+ final ResolveInfo ri = mTargets.get(mIndex++);
+ final ComponentName componentName = ri.activityInfo.getComponentName();
+
+ final CharSequence label = ri.activityInfo.loadLabel(mService.mContext.getPackageManager());
+ mProgress.setProgress(mIndex, mTargets.size(),
+ mService.mContext.getString(R.string.android_preparing_apk, label));
+
+ Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
+ EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());
+
+ mIntent.setComponent(componentName);
+ mService.broadcastIntentLocked(null, null, mIntent, null, this, 0, null, null, null,
+ AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
+ Process.SYSTEM_UID, mUserId);
+ }
+
+ @Override
+ public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
+ boolean ordered, boolean sticky, int sendingUser) {
+ sendNext();
+ }
+
+ public abstract void onFinished();
+}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 5407d28..0993ce6 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -24,7 +24,8 @@
import android.util.DebugUtils;
import android.util.EventLog;
import android.util.Slog;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ProcessState;
import com.android.internal.os.BatteryStatsImpl;
import android.app.ActivityManager;
@@ -69,7 +70,7 @@
IApplicationThread thread; // the actual proc... may be null only if
// 'persistent' is true (in which case we
// are in the process of launching the app)
- ProcessStats.ProcessState baseProcessTracker;
+ ProcessState baseProcessTracker;
BatteryStatsImpl.Uid.Proc curProcBatteryStats;
int pid; // The process of this application; 0 if none
int[] gids; // The gids this process was launched with
@@ -116,6 +117,7 @@
boolean killed; // True once we know the process has been killed
boolean procStateChanged; // Keep track of whether we changed 'setAdj'.
boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
+ boolean unlocked; // True when proc was started in user unlocked state
long interactionEventTime; // The time we sent the last interaction event
long fgInteractionTime; // When we became foreground for interaction purposes
String waitingToKill; // Process is waiting to be killed when in the bg, and reason
@@ -443,7 +445,7 @@
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
if (thread == null) {
- final ProcessStats.ProcessState origBase = baseProcessTracker;
+ final ProcessState origBase = baseProcessTracker;
if (origBase != null) {
origBase.setState(ProcessStats.STATE_NOTHING,
tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList);
@@ -469,7 +471,7 @@
public void makeInactive(ProcessStatsService tracker) {
thread = null;
- final ProcessStats.ProcessState origBase = baseProcessTracker;
+ final ProcessState origBase = baseProcessTracker;
if (origBase != null) {
if (origBase != null) {
origBase.setState(ProcessStats.STATE_NOTHING,
@@ -695,7 +697,7 @@
}
pkgList.clear();
- ProcessStats.ProcessState ps = tracker.getProcessStateLocked(
+ ProcessState ps = tracker.getProcessStateLocked(
info.packageName, uid, info.versionCode, processName);
ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
info.versionCode);
diff --git a/services/core/java/com/android/server/am/ProcessStartLogger.java b/services/core/java/com/android/server/am/ProcessStartLogger.java
deleted file mode 100644
index 39fbeb5..0000000
--- a/services/core/java/com/android/server/am/ProcessStartLogger.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.android.server.am;
-
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-
-import android.app.AppGlobals;
-import android.app.admin.SecurityLog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.Process.ProcessStartResult;
-import android.util.Slog;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.HashMap;
-
-/**
- * A class that logs process start information (including APK hash) to the security log.
- */
-class ProcessStartLogger {
- private static final String CLASS_NAME = "ProcessStartLogger";
- private static final String TAG = TAG_WITH_CLASS_NAME ? CLASS_NAME : TAG_AM;
-
- final HandlerThread mHandlerProcessLoggingThread;
- Handler mHandlerProcessLogging;
- // Should only access in mHandlerProcessLoggingThread
- final HashMap<String, String> mProcessLoggingApkHashes;
-
- ProcessStartLogger() {
- mHandlerProcessLoggingThread = new HandlerThread(CLASS_NAME,
- Process.THREAD_PRIORITY_BACKGROUND);
- mProcessLoggingApkHashes = new HashMap();
- }
-
- void logIfNeededLocked(ProcessRecord app, ProcessStartResult startResult) {
- if (!SecurityLog.isLoggingEnabled()) {
- return;
- }
- if (!mHandlerProcessLoggingThread.isAlive()) {
- mHandlerProcessLoggingThread.start();
- mHandlerProcessLogging = new Handler(mHandlerProcessLoggingThread.getLooper());
- }
- mHandlerProcessLogging.post(new ProcessLoggingRunnable(app, startResult,
- System.currentTimeMillis()));
- }
-
- void registerListener(Context context) {
- IntentFilter packageChangedFilter = new IntentFilter();
- packageChangedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- packageChangedFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- context.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
- || Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
- int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- getSendingUserId());
- String packageName = intent.getData().getSchemeSpecificPart();
- try {
- ApplicationInfo info = AppGlobals.getPackageManager().getApplicationInfo(
- packageName, 0, userHandle);
- invaildateCache(info.sourceDir);
- } catch (RemoteException e) {
- }
- }
- }
- }, packageChangedFilter);
- }
-
- private void invaildateCache(final String apkPath) {
- if (mHandlerProcessLogging != null) {
- mHandlerProcessLogging.post(new Runnable() {
- @Override
- public void run() {
- mProcessLoggingApkHashes.remove(apkPath);
- }
- });
- }
- }
-
- private class ProcessLoggingRunnable implements Runnable {
-
- private final ProcessRecord app;
- private final Process.ProcessStartResult startResult;
- private final long startTimestamp;
-
- public ProcessLoggingRunnable(ProcessRecord app, Process.ProcessStartResult startResult,
- long startTimestamp){
- this.app = app;
- this.startResult = startResult;
- this.startTimestamp = startTimestamp;
- }
-
- @Override
- public void run() {
- String apkHash = computeStringHashOfApk(app);
- SecurityLog.writeEvent(SecurityLog.TAG_APP_PROCESS_START,
- app.processName,
- startTimestamp,
- app.uid,
- startResult.pid,
- app.info.seinfo,
- apkHash);
- }
-
- private String computeStringHashOfApk(ProcessRecord app){
- final String apkFile = app.info.sourceDir;
- if(apkFile == null) {
- return "No APK";
- }
- String apkHash = mProcessLoggingApkHashes.get(apkFile);
- if (apkHash == null) {
- try {
- byte[] hash = computeHashOfApkFile(apkFile);
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < hash.length; i++) {
- sb.append(String.format("%02x", hash[i]));
- }
- apkHash = sb.toString();
- mProcessLoggingApkHashes.put(apkFile, apkHash);
- } catch (IOException | NoSuchAlgorithmException e) {
- Slog.w(TAG, "computeStringHashOfApk() failed", e);
- }
- }
- return apkHash != null ? apkHash : "Failed to count APK hash";
- }
-
- private byte[] computeHashOfApkFile(String packageArchiveLocation)
- throws IOException, NoSuchAlgorithmException {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- FileInputStream input = new FileInputStream(new File(packageArchiveLocation));
- byte[] buffer = new byte[65536];
- int size;
- while((size = input.read(buffer)) > 0) {
- md.update(buffer, 0, size);
- }
- input.close();
- return md.digest();
- }
- }
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 9634dff..8d2b1c2 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -28,8 +28,11 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
-import com.android.internal.app.IProcessStats;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.DumpUtils;
+import com.android.internal.app.procstats.IProcessStats;
+import com.android.internal.app.procstats.ProcessState;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ServiceState;
import com.android.internal.os.BackgroundThread;
import java.io.File;
@@ -107,12 +110,12 @@
}
}
- public ProcessStats.ProcessState getProcessStateLocked(String packageName,
+ public ProcessState getProcessStateLocked(String packageName,
int uid, int versionCode, String processName) {
return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
}
- public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
+ public ServiceState getServiceStateLocked(String packageName, int uid,
int versionCode, String processName, String className) {
return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
className);
@@ -143,22 +146,10 @@
final SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
for (int iver=vers.size()-1; iver>=0; iver--) {
final ProcessStats.PackageState pkg = vers.valueAt(iver);
- final ArrayMap<String, ProcessStats.ServiceState> services = pkg.mServices;
+ final ArrayMap<String, ServiceState> services = pkg.mServices;
for (int isvc=services.size()-1; isvc>=0; isvc--) {
- final ProcessStats.ServiceState service = services.valueAt(isvc);
- if (service.isRestarting()) {
- service.setRestarting(true, memFactor, now);
- } else if (service.isInUse()) {
- if (service.mStartedState != ProcessStats.STATE_NOTHING) {
- service.setStarted(true, memFactor, now);
- }
- if (service.mBoundState != ProcessStats.STATE_NOTHING) {
- service.setBound(true, memFactor, now);
- }
- if (service.mExecState != ProcessStats.STATE_NOTHING) {
- service.setExecuting(true, memFactor, now);
- }
- }
+ final ServiceState service = services.valueAt(isvc);
+ service.setMemFactor(memFactor, now);
}
}
}
@@ -294,12 +285,11 @@
if (stats.mReadError != null) {
Slog.w(TAG, "Ignoring existing stats; " + stats.mReadError);
if (DEBUG) {
- ArrayMap<String, SparseArray<ProcessStats.ProcessState>> procMap
- = stats.mProcesses.getMap();
+ ArrayMap<String, SparseArray<ProcessState>> procMap = stats.mProcesses.getMap();
final int NPROC = procMap.size();
for (int ip=0; ip<NPROC; ip++) {
Slog.w(TAG, "Process: " + procMap.keyAt(ip));
- SparseArray<ProcessStats.ProcessState> uids = procMap.valueAt(ip);
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
final int NUID = uids.size();
for (int iu=0; iu<NUID; iu++) {
Slog.w(TAG, " Uid " + uids.keyAt(iu) + ": " + uids.valueAt(iu));
@@ -387,13 +377,13 @@
boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
boolean sepProcStates, int[] procStates, long now, String reqPackage) {
- ArrayList<ProcessStats.ProcessState> procs = mProcessStats.collectProcessesLocked(
+ ArrayList<ProcessState> procs = mProcessStats.collectProcessesLocked(
screenStates, memStates, procStates, procStates, now, reqPackage, false);
if (procs.size() > 0) {
if (header != null) {
pw.println(header);
}
- ProcessStats.dumpProcessListCsv(pw, procs, sepScreenStates, screenStates,
+ DumpUtils.dumpProcessListCsv(pw, procs, sepScreenStates, screenStates,
sepMemStates, memStates, sepProcStates, procStates, now);
return true;
}
@@ -668,8 +658,8 @@
}
boolean[] sep = new boolean[1];
String[] error = new String[1];
- csvScreenStats = parseStateList(ProcessStats.ADJ_SCREEN_NAMES_CSV, ProcessStats.ADJ_SCREEN_MOD,
- args[i], sep, error);
+ csvScreenStats = parseStateList(DumpUtils.ADJ_SCREEN_NAMES_CSV,
+ ProcessStats.ADJ_SCREEN_MOD, args[i], sep, error);
if (csvScreenStats == null) {
pw.println("Error in \"" + args[i] + "\": " + error[0]);
dumpHelp(pw);
@@ -685,7 +675,8 @@
}
boolean[] sep = new boolean[1];
String[] error = new String[1];
- csvMemStats = parseStateList(ProcessStats.ADJ_MEM_NAMES_CSV, 1, args[i], sep, error);
+ csvMemStats = parseStateList(DumpUtils.ADJ_MEM_NAMES_CSV, 1, args[i],
+ sep, error);
if (csvMemStats == null) {
pw.println("Error in \"" + args[i] + "\": " + error[0]);
dumpHelp(pw);
@@ -701,7 +692,8 @@
}
boolean[] sep = new boolean[1];
String[] error = new String[1];
- csvProcStats = parseStateList(ProcessStats.STATE_NAMES_CSV, 1, args[i], sep, error);
+ csvProcStats = parseStateList(DumpUtils.STATE_NAMES_CSV, 1, args[i],
+ sep, error);
if (csvProcStats == null) {
pw.println("Error in \"" + args[i] + "\": " + error[0]);
dumpHelp(pw);
@@ -839,19 +831,19 @@
if (!csvSepScreenStats) {
for (int i=0; i<csvScreenStats.length; i++) {
pw.print(" ");
- ProcessStats.printScreenLabelCsv(pw, csvScreenStats[i]);
+ DumpUtils.printScreenLabelCsv(pw, csvScreenStats[i]);
}
}
if (!csvSepMemStats) {
for (int i=0; i<csvMemStats.length; i++) {
pw.print(" ");
- ProcessStats.printMemLabelCsv(pw, csvMemStats[i]);
+ DumpUtils.printMemLabelCsv(pw, csvMemStats[i]);
}
}
if (!csvSepProcStats) {
for (int i=0; i<csvProcStats.length; i++) {
pw.print(" ");
- pw.print(ProcessStats.STATE_NAMES_CSV[csvProcStats[i]]);
+ pw.print(DumpUtils.STATE_NAMES_CSV[csvProcStats[i]]);
}
}
pw.println();
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 87cb40e..5075c3a 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -16,7 +16,7 @@
package com.android.server.am;
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ServiceState;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.LocalServices;
import com.android.server.notification.NotificationManagerInternal;
@@ -88,8 +88,8 @@
ProcessRecord app; // where this service is running or null.
ProcessRecord isolatedProc; // keep track of isolated process, if requested
- ProcessStats.ServiceState tracker; // tracking service execution, may be null
- ProcessStats.ServiceState restartTracker; // tracking service restart
+ ServiceState tracker; // tracking service execution, may be null
+ ServiceState restartTracker; // tracking service restart
boolean delayed; // are we waiting to start this service in the background?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
@@ -326,7 +326,7 @@
createdFromFg = callerIsFg;
}
- public ProcessStats.ServiceState getTracker() {
+ public ServiceState getTracker() {
if (tracker != null) {
return tracker;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 4eae45c..0f1ebeb 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -72,8 +72,6 @@
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -128,10 +126,14 @@
private static final String ATTR_RESIZE_MODE = "resize_mode";
private static final String ATTR_PRIVILEGED = "privileged";
private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
+ private static final String ATTR_MINIMAL_WIDTH = "minimal_width";
+ private static final String ATTR_MINIMAL_HEIGHT = "minimal_height";
+
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
static final int INVALID_TASK_ID = -1;
+ static final int INVALID_MINIMAL_SIZE = -1;
final int taskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
@@ -254,9 +256,10 @@
// The information is persisted and used to determine the appropriate stack to launch the
// task into on restore.
Rect mLastNonFullscreenBounds = null;
- // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
- // default minimal size.
- final int mMinimalSize;
+ // Minimal width and height of this task when it's resizeable. -1 means it should use the
+ // default minimal width/height.
+ int mMinimalWidth;
+ int mMinimalHeight;
// Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
// This number will be assigned when we evaluate OOM scores for all visible tasks.
@@ -281,7 +284,7 @@
mCallingUid = info.applicationInfo.uid;
mCallingPackage = info.packageName;
setIntent(_intent, info);
- mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
+ setMinDimensions(info);
}
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -301,6 +304,7 @@
mCallingUid = info.applicationInfo.uid;
mCallingPackage = info.packageName;
setIntent(_intent, info);
+ setMinDimensions(info);
taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
isPersistable = true;
@@ -311,7 +315,6 @@
taskType = APPLICATION_ACTIVITY_TYPE;
mTaskToReturnTo = HOME_ACTIVITY_TYPE;
lastTaskDescription = _taskDescription;
- mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
}
private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
@@ -324,7 +327,7 @@
TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
int resizeMode, boolean privileged, boolean _realActivitySuspended,
- boolean userSetupComplete) {
+ boolean userSetupComplete, int minimalWidth, int minimalHeight) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -364,8 +367,8 @@
mCallingPackage = callingPackage;
mResizeMode = resizeMode;
mPrivileged = privileged;
- ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
- mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
+ mMinimalWidth = minimalWidth;
+ mMinimalHeight = minimalHeight;
}
void touchActiveTime() {
@@ -471,6 +474,17 @@
setLockTaskAuth();
}
+ /** Sets the original minimal width and height. */
+ private void setMinDimensions(ActivityInfo info) {
+ if (info != null && info.windowLayout != null) {
+ mMinimalWidth = info.windowLayout.minimalWidth;
+ mMinimalHeight = info.windowLayout.minimalHeight;
+ } else {
+ mMinimalWidth = INVALID_MINIMAL_SIZE;
+ mMinimalHeight = INVALID_MINIMAL_SIZE;
+ }
+ }
+
/**
* Return true if the input activity has the same intent resolution as the intent this task
* record is based on (normally the root activity intent).
@@ -1136,6 +1150,8 @@
out.attribute(
null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
}
+ out.attribute(null, ATTR_MINIMAL_WIDTH, String.valueOf(mMinimalWidth));
+ out.attribute(null, ATTR_MINIMAL_HEIGHT, String.valueOf(mMinimalHeight));
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
@@ -1200,6 +1216,8 @@
int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
boolean privileged = false;
Rect bounds = null;
+ int minimalWidth = INVALID_MINIMAL_SIZE;
+ int minimalHeight = INVALID_MINIMAL_SIZE;
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -1267,6 +1285,10 @@
privileged = Boolean.valueOf(attrValue);
} else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
bounds = Rect.unflattenFromString(attrValue);
+ } else if (ATTR_MINIMAL_WIDTH.equals(attrName)) {
+ minimalWidth = Integer.valueOf(attrValue);
+ } else if (ATTR_MINIMAL_HEIGHT.equals(attrName)) {
+ minimalHeight = Integer.valueOf(attrValue);
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -1327,7 +1349,7 @@
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
taskAffiliationColor, callingUid, callingPackage, resizeMode, privileged,
- realActivitySuspended, userSetupComplete);
+ realActivitySuspended, userSetupComplete, minimalWidth, minimalHeight);
task.updateOverrideConfiguration(bounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
@@ -1342,35 +1364,41 @@
if (bounds == null) {
return;
}
- int minimalSize = mMinimalSize;
+ int minimalWidth = mMinimalWidth;
+ int minimalHeight = mMinimalHeight;
// If the task has no requested minimal size, we'd like to enforce a minimal size
// so that the user can not render the task too small to manipulate. We don't need
// to do this for the pinned stack as the bounds are controlled by the system.
- if (minimalSize == -1 && stack.mStackId != PINNED_STACK_ID) {
- minimalSize = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+ if (stack.mStackId != PINNED_STACK_ID) {
+ if (minimalWidth == INVALID_MINIMAL_SIZE) {
+ minimalWidth = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+ }
+ if (minimalHeight == INVALID_MINIMAL_SIZE) {
+ minimalHeight = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+ }
}
- final boolean adjustWidth = minimalSize > bounds.width();
- final boolean adjustHeight = minimalSize > bounds.height();
+ final boolean adjustWidth = minimalWidth > bounds.width();
+ final boolean adjustHeight = minimalHeight > bounds.height();
if (!(adjustWidth || adjustHeight)) {
return;
}
if (adjustWidth) {
if (mBounds != null && bounds.right == mBounds.right) {
- bounds.left = bounds.right - minimalSize;
+ bounds.left = bounds.right - minimalWidth;
} else {
// Either left bounds match, or neither match, or the previous bounds were
// fullscreen and we default to keeping left.
- bounds.right = bounds.left + minimalSize;
+ bounds.right = bounds.left + minimalWidth;
}
}
if (adjustHeight) {
if (mBounds != null && bounds.bottom == mBounds.bottom) {
- bounds.top = bounds.bottom - minimalSize;
+ bounds.top = bounds.bottom - minimalHeight;
} else {
// Either top bounds match, or neither match, or the previous bounds were
// fullscreen and we default to keeping top.
- bounds.bottom = bounds.top + minimalSize;
+ bounds.bottom = bounds.top + minimalHeight;
}
}
}
@@ -1502,6 +1530,9 @@
Rect updateOverrideConfigurationFromLaunchBounds() {
final Rect bounds = validateBounds(getLaunchBounds());
updateOverrideConfiguration(bounds);
+ if (bounds != null) {
+ bounds.set(mBounds);
+ }
return bounds;
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5baba52..c59591e9 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -24,6 +24,7 @@
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.os.Process.SYSTEM_UID;
+
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -37,6 +38,10 @@
import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
+import static com.android.server.am.UserState.STATE_BOOTING;
+import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
+import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
+import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -53,6 +58,7 @@
import android.content.pm.UserInfo;
import android.os.BatteryStats;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -77,6 +83,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.ProgressReporter;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerService;
@@ -86,6 +93,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -219,9 +227,7 @@
// consistent developer events. We step into RUNNING_LOCKED here,
// but we might immediately step into RUNNING below if the user
// storage is already unlocked.
- if (uss.state == UserState.STATE_BOOTING) {
- uss.setState(UserState.STATE_RUNNING_LOCKED);
-
+ if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
@@ -236,11 +242,10 @@
}
/**
- * Consider stepping from {@link UserState#STATE_RUNNING_LOCKED} into
- * {@link UserState#STATE_RUNNING}, which only occurs if the user storage is
- * actually unlocked.
+ * Step from {@link UserState#STATE_RUNNING_LOCKED} to
+ * {@link UserState#STATE_RUNNING_UNLOCKING}.
*/
- void finishUserUnlock(UserState uss) {
+ void finishUserUnlocking(final UserState uss, final ProgressReporter progress) {
final int userId = uss.mHandle.getIdentifier();
synchronized (mService) {
// Bail if we ended up with a stale user
@@ -249,14 +254,58 @@
// Only keep marching forward if user is actually unlocked
if (!isUserKeyUnlocked(userId)) return;
- if (uss.state == UserState.STATE_RUNNING_LOCKED) {
- uss.setState(UserState.STATE_RUNNING);
-
- // Give user manager a chance to prepare app storage
+ if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
+ // Prepare app storage before we go any further
+ progress.setProgress(5, mService.mContext.getString(R.string.android_start_title));
mUserManager.onBeforeUnlockUser(userId);
+ progress.setProgress(20);
+ // Send PRE_BOOT broadcasts if fingerprint changed
+ final UserInfo info = getUserInfo(userId);
+ if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
+ progress.startSegment(80);
+ new PreBootBroadcaster(mService, userId, progress) {
+ @Override
+ public void onFinished() {
+ finishUserUnlocked(uss, progress);
+ }
+ }.sendNext();
+ } else {
+ finishUserUnlocked(uss, progress);
+ }
+ }
+ }
+ }
+
+ /**
+ * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
+ * {@link UserState#STATE_RUNNING_UNLOCKED}.
+ */
+ void finishUserUnlocked(UserState uss, ProgressReporter progress) {
+ try {
+ finishUserUnlockedInternal(uss);
+ } finally {
+ progress.finish();
+ }
+ }
+
+ void finishUserUnlockedInternal(UserState uss) {
+ final int userId = uss.mHandle.getIdentifier();
+ synchronized (mService) {
+ // Bail if we ended up with a stale user
+ if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
+
+ // Only keep marching forward if user is actually unlocked
+ if (!isUserKeyUnlocked(userId)) return;
+
+ if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
+ // Remember that we logged in
+ mUserManager.onUserLoggedIn(userId);
+
+ // Dispatch unlocked to system services
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
+ // Dispatch unlocked to external apps
final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
unlockedIntent.addFlags(
@@ -769,7 +818,7 @@
return result;
}
- boolean unlockUser(final int userId, byte[] token, byte[] secret) {
+ boolean unlockUser(final int userId, byte[] token, byte[] secret, ProgressReporter progress) {
if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: unlockUser() from pid="
@@ -782,7 +831,7 @@
final long binderToken = Binder.clearCallingIdentity();
try {
- return unlockUserCleared(userId, token, secret);
+ return unlockUserCleared(userId, token, secret, progress);
} finally {
Binder.restoreCallingIdentity(binderToken);
}
@@ -796,14 +845,20 @@
*/
boolean maybeUnlockUser(final int userId) {
// Try unlocking storage using empty token
- return unlockUserCleared(userId, null, null);
+ return unlockUserCleared(userId, null, null, ProgressReporter.NO_OP);
}
- boolean unlockUserCleared(final int userId, byte[] token, byte[] secret) {
+ boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
+ ProgressReporter progress) {
synchronized (mService) {
// Bail if already running unlocked
final UserState uss = mStartedUsers.get(userId);
- if (uss.state == UserState.STATE_RUNNING) return true;
+ switch (uss.state) {
+ case STATE_RUNNING_UNLOCKING:
+ case STATE_RUNNING_UNLOCKED:
+ progress.finish();
+ return true;
+ }
}
if (!isUserKeyUnlocked(userId)) {
@@ -813,13 +868,14 @@
mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
} catch (RemoteException | RuntimeException e) {
Slog.w(TAG, "Failed to unlock: " + e.getMessage());
+ progress.finish();
return false;
}
}
synchronized (mService) {
final UserState uss = mStartedUsers.get(userId);
- finishUserUnlock(uss);
+ finishUserUnlocking(uss, progress);
}
return true;
@@ -971,7 +1027,6 @@
mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
EventLogTags.writeAmSwitchUser(newUserId);
- getUserManager().onUserForeground(newUserId);
sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
}
@@ -1219,7 +1274,8 @@
unlocked = false;
break;
- case UserState.STATE_RUNNING:
+ case UserState.STATE_RUNNING_UNLOCKING:
+ case UserState.STATE_RUNNING_UNLOCKED:
unlocked = true;
break;
}
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 7b18a17..6e2342b 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -33,14 +33,16 @@
// User is first coming up.
public final static int STATE_BOOTING = 0;
- // User is in the locked running state.
+ // User is in the locked state.
public final static int STATE_RUNNING_LOCKED = 1;
- // User is in the normal running state.
- public final static int STATE_RUNNING = 2;
+ // User is in the unlocking state.
+ public final static int STATE_RUNNING_UNLOCKING = 2;
+ // User is in the running state.
+ public final static int STATE_RUNNING_UNLOCKED = 3;
// User is in the initial process of being stopped.
- public final static int STATE_STOPPING = 3;
+ public final static int STATE_STOPPING = 4;
// User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.
- public final static int STATE_SHUTDOWN = 4;
+ public final static int STATE_SHUTDOWN = 5;
public final UserHandle mHandle;
public final ArrayList<IStopUserCallback> mStopCallbacks
@@ -61,6 +63,17 @@
mHandle = handle;
}
+ public boolean setState(int oldState, int newState) {
+ if (state == oldState) {
+ setState(newState);
+ return true;
+ } else {
+ Slog.w(TAG, "Expected user " + mHandle.getIdentifier() + " in state "
+ + stateToString(oldState) + " but was in state " + stateToString(state));
+ return false;
+ }
+ }
+
public void setState(int newState) {
if (DEBUG_MU) {
Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
@@ -74,7 +87,8 @@
switch (state) {
case STATE_BOOTING: return "BOOTING";
case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
- case STATE_RUNNING: return "RUNNING";
+ case STATE_RUNNING_UNLOCKING: return "RUNNING_UNLOCKING";
+ case STATE_RUNNING_UNLOCKED: return "RUNNING_UNLOCKED";
case STATE_STOPPING: return "STOPPING";
case STATE_SHUTDOWN: return "SHUTDOWN";
default: return Integer.toString(state);
@@ -84,7 +98,6 @@
void dump(String prefix, PrintWriter pw) {
pw.print(prefix);
pw.print("state="); pw.print(stateToString(state));
- pw.print(" lastState="); pw.print(stateToString(lastState));
if (switching) pw.print(" SWITCHING");
if (initializing) pw.print(" INITIALIZING");
pw.println();
diff --git a/services/core/java/com/android/server/backup/BackupUtils.java b/services/core/java/com/android/server/backup/BackupUtils.java
new file mode 100644
index 0000000..e5d564d
--- /dev/null
+++ b/services/core/java/com/android/server/backup/BackupUtils.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.util.Slog;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class BackupUtils {
+ private static final String TAG = "BackupUtils";
+
+ private static final boolean DEBUG = false; // STOPSHIP if true
+
+ public static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
+ if (target == null) {
+ return false;
+ }
+
+ // If the target resides on the system partition, we allow it to restore
+ // data from the like-named package in a restore set even if the signatures
+ // do not match. (Unlike general applications, those flashed to the system
+ // partition will be signed with the device's platform certificate, so on
+ // different phones the same system app will have different signatures.)
+ if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if (DEBUG) Slog.v(TAG, "System app " + target.packageName + " - skipping sig check");
+ return true;
+ }
+
+ // Allow unsigned apps, but not signed on one device and unsigned on the other
+ // !!! TODO: is this the right policy?
+ Signature[] deviceSigs = target.signatures;
+ if (DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes
+ + " device=" + deviceSigs);
+ if ((storedSigHashes == null || storedSigHashes.size() == 0)
+ && (deviceSigs == null || deviceSigs.length == 0)) {
+ return true;
+ }
+ if (storedSigHashes == null || deviceSigs == null) {
+ return false;
+ }
+
+ // !!! TODO: this demands that every stored signature match one
+ // that is present on device, and does not demand the converse.
+ // Is this this right policy?
+ final int nStored = storedSigHashes.size();
+ final int nDevice = deviceSigs.length;
+
+ // hash each on-device signature
+ ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
+ for (int i = 0; i < nDevice; i++) {
+ deviceHashes.add(hashSignature(deviceSigs[i]));
+ }
+
+ // now ensure that each stored sig (hash) matches an on-device sig (hash)
+ for (int n = 0; n < nStored; n++) {
+ boolean match = false;
+ final byte[] storedHash = storedSigHashes.get(n);
+ for (int i = 0; i < nDevice; i++) {
+ if (Arrays.equals(storedHash, deviceHashes.get(i))) {
+ match = true;
+ break;
+ }
+ }
+ // match is false when no on-device sig matched one of the stored ones
+ if (!match) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static byte[] hashSignature(byte[] signature) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ digest.update(signature);
+ return digest.digest();
+ } catch (NoSuchAlgorithmException e) {
+ Slog.w(TAG, "No SHA-256 algorithm found!");
+ }
+ return null;
+ }
+
+ public static byte[] hashSignature(Signature signature) {
+ return hashSignature(signature.toByteArray());
+ }
+
+ public static ArrayList<byte[]> hashSignatureArray(Signature[] sigs) {
+ if (sigs == null) {
+ return null;
+ }
+
+ ArrayList<byte[]> hashes = new ArrayList<>(sigs.length);
+ for (Signature s : sigs) {
+ hashes.add(hashSignature(s));
+ }
+ return hashes;
+ }
+
+ public static ArrayList<byte[]> hashSignatureArray(List<byte[]> sigs) {
+ if (sigs == null) {
+ return null;
+ }
+
+ ArrayList<byte[]> hashes = new ArrayList<>(sigs.size());
+ for (byte[] s : sigs) {
+ hashes.add(hashSignature(s));
+ }
+ return hashes;
+ }
+}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 6b00f5f..fa8620f 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -58,8 +58,8 @@
import android.util.TimeUtils;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.app.ProcessStats;
import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.android.server.job.JobStore.JobStatusFunctor;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 9b92e4f..c75e287 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -687,7 +687,7 @@
// global background data policy
if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
synchronized (mRulesLock) {
- updateRestrictDataRulesForUidLocked(uid);
+ updateRestrictionRulesForUidLocked(uid);
}
}
}
@@ -705,7 +705,7 @@
if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
synchronized (mRulesLock) {
mUidPolicy.delete(uid);
- updateRestrictDataRulesForUidLocked(uid);
+ updateRuleForRestrictBackgroundLocked(uid);
writePolicyLocked();
}
}
@@ -1678,7 +1678,7 @@
mUidPolicy.put(uid, policy);
// uid policy changed, recompute rules and persist policy.
- updateRestrictDataRulesForUidLocked(uid);
+ updateRuleForRestrictBackgroundLocked(uid);
if (persist) {
writePolicyLocked();
}
@@ -1897,7 +1897,7 @@
maybeRefreshTrustedTime();
synchronized (mRulesLock) {
mRestrictBackground = restrictBackground;
- updateRulesForRestrictDataLocked();
+ updateRulesForRestrictBackgroundLocked();
updateNotificationsLocked();
writePolicyLocked();
}
@@ -2272,7 +2272,7 @@
final int rule = mUidRules.get(uid, RULE_UNKNOWN);
fout.print(" rule=");
- fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
+ fout.print(ruleToString(rule));
fout.println();
}
@@ -2280,6 +2280,10 @@
}
}
+ private String ruleToString(int rule) {
+ return DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule);
+ }
+
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ResultReceiver resultReceiver) throws RemoteException {
@@ -2296,57 +2300,73 @@
}
}
- boolean isUidForegroundLocked(int uid) {
+ private boolean isUidForegroundLocked(int uid) {
+ return isUidStateForegroundLocked(
+ mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
+ }
+
+ private boolean isUidStateForegroundLocked(int state) {
// only really in foreground when screen is also on
- return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
- <= ActivityManager.PROCESS_STATE_TOP;
+ return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP;
}
/**
* Process state of UID changed; if needed, will trigger
* {@link #updateRestrictDataRulesForUidLocked(int)}.
*/
- void updateUidStateLocked(int uid, int uidState) {
+ private void updateUidStateLocked(int uid, int uidState) {
final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (oldUidState != uidState) {
// state changed, push updated rules
mUidState.put(uid, uidState);
- updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
+ updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState);
if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
!= isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
if (mDeviceIdleMode) {
updateRuleForDeviceIdleLocked(uid);
}
if (mRestrictPower) {
- updateRulesForRestrictPowerLocked(uid);
+ updateRuleForRestrictPowerLocked(uid);
}
}
+ updateNetworkStats(uid, isUidStateForegroundLocked(uidState));
}
}
- void removeUidStateLocked(int uid) {
+ private void removeUidStateLocked(int uid) {
final int index = mUidState.indexOfKey(uid);
if (index >= 0) {
final int oldUidState = mUidState.valueAt(index);
mUidState.removeAt(index);
if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
- updateRulesForUidStateChangeLocked(uid, oldUidState,
+ updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState,
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (mDeviceIdleMode) {
updateRuleForDeviceIdleLocked(uid);
}
if (mRestrictPower) {
- updateRulesForRestrictPowerLocked(uid);
+ updateRuleForRestrictPowerLocked(uid);
}
+ updateNetworkStats(uid, false);
}
}
}
- void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
+ // adjust stats accounting based on foreground status
+ private void updateNetworkStats(int uid, boolean uidForeground) {
+ try {
+ mNetworkStats.setUidForeground(uid, uidForeground);
+ } catch (RemoteException e) {
+ // ignored; service lives in system_server
+ }
+ }
+
+ private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState,
+ int newUidState) {
final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP;
final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP;
if (oldForeground != newForeground) {
- updateRestrictDataRulesForUidLocked(uid);
+ updateRuleForRestrictBackgroundLocked(uid);
}
}
@@ -2370,7 +2390,7 @@
for (int i = 0; i < size; i++) {
if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) {
final int uid = mUidState.keyAt(i);
- updateRestrictDataRulesForUidLocked(uid);
+ updateRestrictionRulesForUidLocked(uid);
}
}
}
@@ -2384,7 +2404,7 @@
mUidFirewallPowerSaveRules);
}
- void updateRulesForRestrictPowerLocked(int uid) {
+ void updateRuleForRestrictPowerLocked(int uid) {
updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
}
@@ -2397,8 +2417,8 @@
updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
}
- // NOTE: since both fw_dozable and fw_powersave uses the same map (mPowerSaveTempWhitelistAppIds)
- // for whitelisting, we can reuse their logic in this method.
+ // NOTE: since both fw_dozable and fw_powersave uses the same map
+ // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain,
SparseIntArray rules) {
if (enabled) {
@@ -2433,8 +2453,8 @@
enableFirewallChainLocked(chain, enabled);
}
- // NOTE: since both fw_dozable and fw_powersave uses the same map (mPowerSaveTempWhitelistAppIds)
- // for whitelisting, we can reuse their logic in this method.
+ // NOTE: since both fw_dozable and fw_powersave uses the same map
+ // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) {
if (enabled) {
int appId = UserHandle.getAppId(uid);
@@ -2452,7 +2472,6 @@
uidRules.clear();
// Fully update the app idle firewall chain.
- final IPackageManager ipm = AppGlobals.getPackageManager();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2499,7 +2518,7 @@
updateRulesForDeviceIdleLocked();
updateRulesForAppIdleLocked();
updateRulesForRestrictPowerLocked();
- updateRulesForRestrictDataLocked();
+ updateRulesForRestrictBackgroundLocked();
// If the set of restricted networks may have changed, re-evaluate those.
if (restrictedNetworksChanged) {
@@ -2513,7 +2532,7 @@
}
}
- private void updateRulesForRestrictDataLocked() {
+ private void updateRulesForRestrictBackgroundLocked() {
final PackageManager pm = mContext.getPackageManager();
// update rules for all installed applications
@@ -2530,13 +2549,13 @@
for (int j = 0; j < appsSize; j++) {
final ApplicationInfo app = apps.get(j);
final int uid = UserHandle.getUid(user.id, app.uid);
- updateRestrictDataRulesForUidLocked(uid);
+ updateRuleForRestrictBackgroundLocked(uid);
}
}
// limit data usage for some internal system services
- updateRestrictDataRulesForUidLocked(android.os.Process.MEDIA_UID);
- updateRestrictDataRulesForUidLocked(android.os.Process.DRM_UID);
+ updateRuleForRestrictBackgroundLocked(android.os.Process.MEDIA_UID);
+ updateRuleForRestrictBackgroundLocked(android.os.Process.DRM_UID);
}
private void updateRulesForTempWhitelistChangeLocked() {
@@ -2548,15 +2567,15 @@
int uid = UserHandle.getUid(user.id, appId);
updateRuleForAppIdleLocked(uid);
updateRuleForDeviceIdleLocked(uid);
- updateRulesForRestrictPowerLocked(uid);
+ updateRuleForRestrictPowerLocked(uid);
}
}
}
- private static boolean isUidValidForRules(int uid) {
- // allow rules on specific system services, and any apps
+ private boolean isUidValidForRules(int uid) {
+ // allow rules on specific system services, and any apps (that have network access)
if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
- || UserHandle.isApp(uid)) {
+ || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
return true;
}
@@ -2594,12 +2613,21 @@
}
/**
- * Applies network rules to bandwidth controllers based on uid policy.
+ * Applies network rules to bandwidth and firewall controllers based on uid policy.
*
- * @param uid The uid for which to apply the latest policy
+ * <p>There are currently 2 types of restriction rules:
+ * <ul>
+ * <li>Battery Saver Mode (also referred as power save).
+ * <li>Data Saver Mode (formerly known as restrict background data).
+ * </ul>
*/
- private void updateRestrictDataRulesForUidLocked(int uid) {
- if (!isUidValidForRules(uid) || !hasInternetPermissions(uid)) return;
+ private void updateRestrictionRulesForUidLocked(int uid) {
+ updateRuleForRestrictPowerLocked(uid);
+ updateRuleForRestrictBackgroundLocked(uid);
+ }
+
+ private void updateRuleForRestrictBackgroundLocked(int uid) {
+ if (!isUidValidForRules(uid)) return;
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
final boolean uidForeground = isUidForegroundLocked(uid);
@@ -2618,8 +2646,10 @@
}
final int oldRule = mUidRules.get(uid);
- if (LOGV) Log.v(TAG, "updateBandwithControllerRulesForUidLocked(" + uid + "): oldRule = "
- + oldRule + ", newRule = " + newRule);
+ if (LOGV) {
+ Log.v(TAG, "updateRulesForRestrictBackgroundLocked(" + uid + "): oldRule = "
+ + ruleToString(oldRule) + ", newRule = " + ruleToString(newRule));
+ }
if (newRule == RULE_ALLOW_ALL) {
mUidRules.delete(uid);
@@ -2627,20 +2657,14 @@
mUidRules.put(uid, newRule);
}
- final boolean rejectMetered = (newRule == RULE_REJECT_METERED);
- setUidNetworkRules(uid, rejectMetered);
-
- // dispatch changed rule to existing listeners
if (oldRule != newRule) {
+ final boolean rejectMetered = (newRule == RULE_REJECT_METERED);
+ setUidNetworkRules(uid, rejectMetered);
+
+ // dispatch changed rule to existing listeners
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newRule).sendToTarget();
}
- try {
- // adjust stats accounting based on foreground status
- mNetworkStats.setUidForeground(uid, uidForeground);
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- }
}
private class AppIdleStateChangeListener
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index c303ceb..7c71fbc 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -335,40 +335,40 @@
verifyCallingPackage(callingPackage);
ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
- if (!mShortcutServiceInternal.hasShortcutHostPermission(callingPackage,
- user.getIdentifier())) {
+ if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
+ callingPackage)) {
throw new SecurityException("Caller can't access shortcut information");
}
}
@Override
public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
- String packageName, ComponentName componentName, int flags, UserHandle user)
- throws RemoteException {
+ String packageName, ComponentName componentName, int flags, UserHandle user) {
ensureShortcutPermission(callingPackage, user);
return new ParceledListSlice<>(
- mShortcutServiceInternal.getShortcuts(callingPackage, changedSince, packageName,
- componentName, flags, user.getIdentifier()));
+ mShortcutServiceInternal.getShortcuts(getCallingUserId(),
+ callingPackage, changedSince, packageName,
+ componentName, flags, user.getIdentifier()));
}
@Override
public ParceledListSlice getShortcutInfo(String callingPackage, String packageName,
- List<String> ids, UserHandle user) throws RemoteException {
+ List<String> ids, UserHandle user) {
ensureShortcutPermission(callingPackage, user);
return new ParceledListSlice<>(
- mShortcutServiceInternal.getShortcutInfo(callingPackage, packageName,
- ids, user.getIdentifier()));
+ mShortcutServiceInternal.getShortcutInfo(getCallingUserId(),
+ callingPackage, packageName, ids, user.getIdentifier()));
}
@Override
public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
- UserHandle user) throws RemoteException {
+ UserHandle user) {
ensureShortcutPermission(callingPackage, user);
- mShortcutServiceInternal.pinShortcuts(callingPackage, packageName,
- ids, user.getIdentifier());
+ mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
+ callingPackage, packageName, ids, user.getIdentifier());
}
@Override
@@ -376,8 +376,8 @@
UserHandle user) {
ensureShortcutPermission(callingPackage, user);
- return mShortcutServiceInternal.getShortcutIconResId(callingPackage, shortcut,
- user.getIdentifier());
+ return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
+ callingPackage, shortcut, user.getIdentifier());
}
@Override
@@ -385,25 +385,31 @@
UserHandle user) {
ensureShortcutPermission(callingPackage, user);
- return mShortcutServiceInternal.getShortcutIconFd(callingPackage, shortcut,
- user.getIdentifier());
+ return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
+ callingPackage, shortcut, user.getIdentifier());
}
@Override
- public boolean hasShortcutHostPermission(String callingPackage) throws RemoteException {
+ public boolean hasShortcutHostPermission(String callingPackage) {
verifyCallingPackage(callingPackage);
- return mShortcutServiceInternal.hasShortcutHostPermission(callingPackage,
- getCallingUserId());
+ return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
+ callingPackage);
}
@Override
public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
- Rect sourceBounds, Bundle startActivityOptions, UserHandle user)
- throws RemoteException {
- ensureShortcutPermission(callingPackage, user);
+ Rect sourceBounds, Bundle startActivityOptions, UserHandle user) {
+ verifyCallingPackage(callingPackage);
+ ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
- final Intent intent = mShortcutServiceInternal.createShortcutIntent(callingPackage,
- packageName, shortcutId, user.getIdentifier());
+ // Even without the permission, pinned shortcuts are always launchable.
+ if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
+ callingPackage, packageName, shortcutId, user.getIdentifier())) {
+ ensureShortcutPermission(callingPackage, user);
+ }
+
+ final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(),
+ callingPackage, packageName, shortcutId, user.getIdentifier());
if (intent == null) {
return false;
}
@@ -713,9 +719,11 @@
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue;
+ final int launcherUserId = cookie.user.getIdentifier();
+
// Make sure the caller has the permission.
- if (!mShortcutServiceInternal.hasShortcutHostPermission(cookie.packageName,
- cookie.user.getIdentifier())) {
+ if (!mShortcutServiceInternal.hasShortcutHostPermission(
+ launcherUserId, cookie.packageName)) {
continue;
}
// Each launcher has a different set of pinned shortcuts, so we need to do a
@@ -723,8 +731,9 @@
// (As of now, only one launcher has the permission at a time, so it's bit
// moot, but we may change the permission model eventually.)
final List<ShortcutInfo> list =
- mShortcutServiceInternal.getShortcuts(cookie.packageName,
- /* changedSince= */ 0, packageName, /* component= */ null,
+ mShortcutServiceInternal.getShortcuts(launcherUserId,
+ cookie.packageName,
+ /* changedSince= */ 0, packageName, /* component= */ null,
ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
| ShortcutQuery.FLAG_GET_PINNED
| ShortcutQuery.FLAG_GET_DYNAMIC
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 5ceb65f..4ca615d 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -138,9 +138,8 @@
boolean isProfileGuidedFilter = DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter);
// If any part of the app is used by other apps, we cannot use profile-guided
// compilation.
- // TODO: This needs to be refactored to be also checked when the target mode is
- // profile-guided.
- if (isProfileGuidedFilter) {
+ // Skip the check for forward locked packages since they don't share their code.
+ if (isProfileGuidedFilter && !pkg.isForwardLocked()) {
for (String path : paths) {
if (isUsedByOtherApps(path)) {
checkProfiles = false;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 64f8c98..442643a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -106,6 +106,7 @@
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
+import android.app.admin.SecurityLog;
import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -444,13 +445,14 @@
}
// Compilation reasons.
- public static final int REASON_BOOT = 0;
- public static final int REASON_INSTALL = 1;
- public static final int REASON_BACKGROUND_DEXOPT = 2;
- public static final int REASON_AB_OTA = 3;
- public static final int REASON_NON_SYSTEM_LIBRARY = 4;
- public static final int REASON_SHARED_APK = 5;
- public static final int REASON_FORCED_DEXOPT = 6;
+ public static final int REASON_FIRST_BOOT = 0;
+ public static final int REASON_BOOT = 1;
+ public static final int REASON_INSTALL = 2;
+ public static final int REASON_BACKGROUND_DEXOPT = 3;
+ public static final int REASON_AB_OTA = 4;
+ public static final int REASON_NON_SYSTEM_LIBRARY = 5;
+ public static final int REASON_SHARED_APK = 6;
+ public static final int REASON_FORCED_DEXOPT = 7;
public static final int REASON_LAST = REASON_FORCED_DEXOPT;
@@ -458,6 +460,8 @@
final PackageHandler mHandler;
+ private final ProcessLoggingHandler mProcessLoggingHandler;
+
/**
* Messages for {@link #mHandler} that need to wait for system ready before
* being dispatched.
@@ -473,6 +477,7 @@
final int mDefParseFlags;
final String[] mSeparateProcesses;
final boolean mIsUpgrade;
+ final boolean mIsPreNUpgrade;
/** The location for ASEC container files on internal storage. */
final String mAsecInternalPath;
@@ -1710,6 +1715,8 @@
// Send installed broadcasts if the install/update is not ephemeral
if (!isEphemeral(res.pkg)) {
+ mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
+
// Send added for users that see the package for the first time
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
extras, 0 /*flags*/, null /*targetPackage*/,
@@ -2094,6 +2101,7 @@
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
+ mProcessLoggingHandler = new ProcessLoggingHandler();
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
File dataDir = Environment.getDataDirectory();
@@ -2206,6 +2214,7 @@
final VersionInfo ver = mSettings.getInternalVersion();
mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+
// when upgrading from pre-M, promote system app permissions from install to runtime
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
@@ -2222,6 +2231,11 @@
}
}
+ // When upgrading from pre-N, we need to handle package extraction like first boot,
+ // as there is no profiling data available.
+ mIsPreNUpgrade = !mSettings.isNWorkDone();
+ mSettings.setNWorkDone();
+
// Collect vendor overlay packages.
// (Do this before scanning any apps.)
// For security and version matching reason, only consider
@@ -2899,6 +2913,11 @@
throw new SecurityException("Package " + packageName + " was not found!");
}
+ if (!ps.getInstalled(userId)) {
+ throw new SecurityException(
+ "Package " + packageName + " was not installed for user " + userId + "!");
+ }
+
if (mSafeMode && !ps.isSystem()) {
throw new SecurityException("Package " + packageName + " not a system app!");
}
@@ -6910,10 +6929,18 @@
public void extractPackagesIfNeeded() {
enforceSystemOrRoot("Only the system can request package extraction");
- // Extract pacakges only if profile-guided compilation is enabled because
- // otherwise BackgroundDexOptService will not dexopt them later.
- boolean prunedCache = VMRuntime.didPruneDalvikCache();
- if (!isUpgrade() && !prunedCache) {
+ // We need to re-extract after an OTA.
+ boolean causeUpgrade = isUpgrade();
+
+ // First boot or factory reset.
+ // Note: we also handle devices that are upgrading to N right now as if it is their
+ // first boot, as they do not have profile data.
+ boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
+
+ // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
+ boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
+
+ if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
return;
}
@@ -6945,7 +6972,9 @@
// and would have to be patched (would be SELF_PATCHOAT, which is deprecated).
// Instead, force the extraction in this case.
performDexOpt(pkg.packageName, null /* instructionSet */,
- false /* checkProfiles */, REASON_BOOT, prunedCache);
+ false /* checkProfiles */,
+ causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
+ causePrunedCache);
}
}
}
@@ -13130,6 +13159,7 @@
final PackageParser.Package oldPackage;
final String pkgName = pkg.packageName;
final int[] allUsers;
+ final boolean weFroze;
// First find the old package info and check signatures
synchronized(mPackages) {
@@ -13162,8 +13192,32 @@
// In case of rollback, remember per-user/profile install state
allUsers = sUserManager.getUserIds();
+
+ // Mark the app as frozen to prevent launching during the upgrade
+ // process, and then kill all running instances
+ if (!ps.frozen) {
+ ps.frozen = true;
+ weFroze = true;
+ } else {
+ weFroze = false;
+ }
}
+ try {
+ replacePackageDirtyLI(pkg, oldPackage, parseFlags, scanFlags, user, allUsers,
+ installerPackageName, res);
+ } finally {
+ // Regardless of success or failure of upgrade steps above, always
+ // unfreeze the package if we froze it
+ if (weFroze) {
+ unfreezePackage(pkgName);
+ }
+ }
+ }
+
+ private void replacePackageDirtyLI(PackageParser.Package pkg, PackageParser.Package oldPackage,
+ int parseFlags, int scanFlags, UserHandle user, int[] allUsers,
+ String installerPackageName, PackageInstalledInfo res) {
// Update what is removed
res.removedInfo = new PackageRemovedInfo();
res.removedInfo.uid = oldPackage.applicationInfo.uid;
@@ -19410,4 +19464,26 @@
return new ArrayList<>(mPackages.values());
}
}
+
+ /**
+ * Logs process start information (including base APK hash) to the security log.
+ * @hide
+ */
+ public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
+ String apkFile, int pid) {
+ if (!SecurityLog.isLoggingEnabled()) {
+ return;
+ }
+ Bundle data = new Bundle();
+ data.putLong("startTimestamp", System.currentTimeMillis());
+ data.putString("processName", processName);
+ data.putInt("uid", uid);
+ data.putString("seinfo", seinfo);
+ data.putString("apkFile", apkFile);
+ data.putInt("pid", pid);
+ Message msg = mProcessLoggingHandler.obtainMessage(
+ ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
+ msg.setData(data);
+ mProcessLoggingHandler.sendMessage(msg);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 238e410..f1b7991 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,7 +26,8 @@
class PackageManagerServiceCompilerMapping {
// Names for compilation reasons.
static final String REASON_STRINGS[] = {
- "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", "forced-dexopt"
+ "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
+ "forced-dexopt"
};
// Static block to ensure the strings array is of the right length.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index bf44b0f..238ce95 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -44,6 +44,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ShellCommand;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.PrintWriterPrinter;
@@ -249,31 +250,34 @@
private int runCompile() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
- boolean useJitProfiles = false;
+ boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
boolean forceCompilation = false;
boolean allPackages = false;
boolean clearProfileData = false;
String compilerFilter = null;
String compilationReason = null;
+ String checkProfilesRaw = null;
if (peekNextArg() == null) {
// No arguments, show help.
pw.println("Usage: cmd package compile [-c] [-f] [--reset] [-m mode] " +
"[-r reason] [-a|pkg]");
pw.println();
- pw.println(" -c Clear profile data");
- pw.println(" -f Force compilation");
- pw.println(" --reset Reset package");
- pw.println(" -m mode Compilation mode, one of the dex2oat compiler filters");
- pw.println(" verify-none");
- pw.println(" verify-at-runtime");
- pw.println(" verify-profile");
- pw.println(" interpret-only");
- pw.println(" space-profile");
- pw.println(" space");
- pw.println(" speed-profile");
- pw.println(" speed");
- pw.println(" everything");
+ pw.println(" -c Clear profile data");
+ pw.println(" -f Force compilation");
+ pw.println(" --check-prof val Look at profiles when doing dexopt.");
+ pw.println(" Overrides dalvik.vm.usejitprofiles to true of false");
+ pw.println(" --reset Reset package");
+ pw.println(" -m mode Compilation mode, one of the dex2oat compiler filters");
+ pw.println(" verify-none");
+ pw.println(" verify-at-runtime");
+ pw.println(" verify-profile");
+ pw.println(" interpret-only");
+ pw.println(" space-profile");
+ pw.println(" space");
+ pw.println(" speed-profile");
+ pw.println(" speed");
+ pw.println(" everything");
pw.println(" -r reason Compiler reason, one of the package manager reasons");
for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
pw.println(" " +
@@ -301,6 +305,9 @@
case "-r":
compilationReason = getNextArgRequired();
break;
+ case "-check-prof":
+ checkProfilesRaw = getNextArgRequired();
+ break;
case "--reset":
forceCompilation = true;
clearProfileData = true;
@@ -312,6 +319,17 @@
}
}
+ if (checkProfilesRaw != null) {
+ if ("true".equals(checkProfilesRaw)) {
+ checkProfiles = true;
+ } else if ("false".equals(checkProfilesRaw)) {
+ checkProfiles = false;
+ } else {
+ pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
+ return 1;
+ }
+ }
+
if (compilerFilter != null && compilationReason != null) {
pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
"at the same time");
@@ -381,7 +399,7 @@
}
boolean result = mInterface.performDexOptMode(packageName, null /* instructionSet */,
- useJitProfiles, targetCompilerFilter, forceCompilation);
+ checkProfiles, targetCompilerFilter, forceCompilation);
if (!result) {
failedPackages.add(packageName);
}
diff --git a/services/core/java/com/android/server/pm/ProcessLoggingHandler.java b/services/core/java/com/android/server/pm/ProcessLoggingHandler.java
new file mode 100644
index 0000000..c47dda4
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ProcessLoggingHandler.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.app.admin.SecurityLog;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.os.BackgroundThread;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import android.util.Slog;
+
+public final class ProcessLoggingHandler extends Handler {
+
+ private static final String TAG = "ProcessLoggingHandler";
+ static final int LOG_APP_PROCESS_START_MSG = 1;
+ static final int INVALIDATE_BASE_APK_HASH_MSG = 2;
+
+ private final HashMap<String, String> mProcessLoggingBaseApkHashes = new HashMap();
+
+ ProcessLoggingHandler() {
+ super(BackgroundThread.getHandler().getLooper());
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case LOG_APP_PROCESS_START_MSG: {
+ Bundle bundle = msg.getData();
+ String processName = bundle.getString("processName");
+ int uid = bundle.getInt("uid");
+ String seinfo = bundle.getString("seinfo");
+ String apkFile = bundle.getString("apkFile");
+ int pid = bundle.getInt("pid");
+ long startTimestamp = bundle.getLong("startTimestamp");
+ String apkHash = computeStringHashOfApk(apkFile);
+ SecurityLog.writeEvent(SecurityLog.TAG_APP_PROCESS_START, processName,
+ startTimestamp, uid, pid, seinfo, apkHash);
+ break;
+ }
+ case INVALIDATE_BASE_APK_HASH_MSG: {
+ Bundle bundle = msg.getData();
+ mProcessLoggingBaseApkHashes.remove(bundle.getString("apkFile"));
+ break;
+ }
+ }
+ }
+
+ void invalidateProcessLoggingBaseApkHash(String apkPath) {
+ Bundle data = new Bundle();
+ data.putString("apkFile", apkPath);
+ Message msg = obtainMessage(INVALIDATE_BASE_APK_HASH_MSG);
+ msg.setData(data);
+ sendMessage(msg);
+ }
+
+ private String computeStringHashOfApk(String apkFile) {
+ if (apkFile == null) {
+ return "No APK";
+ }
+ String apkHash = mProcessLoggingBaseApkHashes.get(apkFile);
+ if (apkHash == null) {
+ try {
+ byte[] hash = computeHashOfApkFile(apkFile);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < hash.length; i++) {
+ sb.append(String.format("%02x", hash[i]));
+ }
+ apkHash = sb.toString();
+ mProcessLoggingBaseApkHashes.put(apkFile, apkHash);
+ } catch (IOException | NoSuchAlgorithmException e) {
+ Slog.w(TAG, "computeStringHashOfApk() failed", e);
+ }
+ }
+ return apkHash != null ? apkHash : "Failed to count APK hash";
+ }
+
+ private byte[] computeHashOfApkFile(String packageArchiveLocation)
+ throws IOException, NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ FileInputStream input = new FileInputStream(new File(packageArchiveLocation));
+ byte[] buffer = new byte[65536];
+ int size;
+ while ((size = input.read(buffer)) > 0) {
+ md.update(buffer, 0, size);
+ }
+ input.close();
+ return md.digest();
+ }
+}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index fa0eb46..3c3c576 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -190,6 +190,7 @@
"all-intent-filter-verifications";
private static final String TAG_DEFAULT_BROWSER = "default-browser";
private static final String TAG_VERSION = "version";
+ private static final String TAG_N_WORK = "n-work";
private static final String ATTR_NAME = "name";
private static final String ATTR_USER = "user";
@@ -214,6 +215,7 @@
private static final String ATTR_VOLUME_UUID = "volumeUuid";
private static final String ATTR_SDK_VERSION = "sdkVersion";
private static final String ATTR_DATABASE_VERSION = "databaseVersion";
+ private static final String ATTR_DONE = "done";
// Bookkeeping for restored permission grants
private static final String TAG_RESTORED_RUNTIME_PERMISSIONS = "restored-perms";
@@ -386,6 +388,17 @@
public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
+ /**
+ * Used to track whether N+ work has been done. This is similar to the file-system level
+ * and denotes that first-boot or upgrade-to-N work has been done.
+ *
+ * Note: the flag has been added to a) allow tracking while an API level check is impossible
+ * and b) to merge upgrade as well as first boot (because the flag is false, by default).
+ *
+ * STOPSHIP: b/27872764
+ */
+ private boolean mIsNWorkDone = false;
+
Settings(Object lock) {
this(Environment.getDataDirectory(), lock);
}
@@ -2327,6 +2340,10 @@
mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
+ serializer.startTag(null, TAG_N_WORK);
+ serializer.attribute(null, ATTR_DONE, Boolean.toString(mIsNWorkDone));
+ serializer.endTag(null, TAG_N_WORK);
+
serializer.endTag(null, "packages");
serializer.endDocument();
@@ -2860,7 +2877,8 @@
ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
-
+ } else if (TAG_N_WORK.equals(tagName)) {
+ mIsNWorkDone = XmlUtils.readBooleanAttribute(parser, ATTR_DONE, false);
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
+ parser.getName());
@@ -4140,6 +4158,14 @@
return res;
}
+ public boolean isNWorkDone() {
+ return mIsNWorkDone;
+ }
+
+ void setNWorkDone() {
+ mIsNWorkDone = true;
+ }
+
static void printFlags(PrintWriter pw, int val, Object[] spec) {
pw.print("[ ");
for (int i=0; i<spec.length; i+=2) {
diff --git a/services/core/java/com/android/server/pm/ShortcutBackupAgent.java b/services/core/java/com/android/server/pm/ShortcutBackupAgent.java
new file mode 100644
index 0000000..a0fbc37
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutBackupAgent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.app.backup.BlobBackupHelper;
+
+public class ShortcutBackupAgent extends BlobBackupHelper {
+ private static final String TAG = "ShortcutBackupAgent";
+ private static final int BLOB_VERSION = 1;
+
+ public ShortcutBackupAgent(int currentBlobVersion, String... keys) {
+ super(currentBlobVersion, keys);
+ }
+
+ @Override
+ protected byte[] getBackupPayload(String key) {
+ throw new RuntimeException("not implemented yet"); // todo
+ }
+
+ @Override
+ protected void applyRestoredPayload(String key, byte[] payload) {
+ throw new RuntimeException("not implemented yet"); // todo
+ }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index f1920c7..b759e16 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -32,7 +32,7 @@
/**
* Launcher information used by {@link ShortcutService}.
*/
-class ShortcutLauncher {
+class ShortcutLauncher implements ShortcutPackageItem {
private static final String TAG = ShortcutService.TAG;
static final String TAG_ROOT = "launcher-pins";
@@ -40,23 +40,44 @@
private static final String TAG_PACKAGE = "package";
private static final String TAG_PIN = "pin";
+ private static final String ATTR_LAUNCHER_USER_ID = "launcher-user";
private static final String ATTR_VALUE = "value";
private static final String ATTR_PACKAGE_NAME = "package-name";
@UserIdInt
- final int mUserId;
+ private final int mUserId;
@NonNull
- final String mPackageName;
+ private final String mPackageName;
+
+ @UserIdInt
+ private final int mLauncherUserId;
/**
* Package name -> IDs.
*/
final private ArrayMap<String, ArraySet<String>> mPinnedShortcuts = new ArrayMap<>();
- ShortcutLauncher(@UserIdInt int userId, @NonNull String packageName) {
+ ShortcutLauncher(@UserIdInt int userId, @NonNull String packageName,
+ @UserIdInt int launcherUserId) {
mUserId = userId;
mPackageName = packageName;
+ mLauncherUserId = launcherUserId;
+ }
+
+ @UserIdInt
+ public int getUserId() {
+ return mUserId;
+ }
+
+ @UserIdInt
+ public int getLauncherUserId() {
+ return mLauncherUserId;
+ }
+
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
}
public void pinShortcuts(@NonNull ShortcutService s, @NonNull String packageName,
@@ -103,15 +124,15 @@
/**
* Persist.
*/
- public void saveToXml(XmlSerializer out) throws IOException {
+ public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
final int size = mPinnedShortcuts.size();
if (size == 0) {
return; // Nothing to write.
}
out.startTag(null, TAG_ROOT);
- ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME,
- mPackageName);
+ ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, mPackageName);
+ ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, mLauncherUserId);
for (int i = 0; i < size; i++) {
out.startTag(null, TAG_PACKAGE);
@@ -132,12 +153,15 @@
/**
* Load.
*/
- public static ShortcutLauncher loadFromXml(XmlPullParser parser, int userId)
+ public static ShortcutLauncher loadFromXml(XmlPullParser parser, int ownerUserId)
throws IOException, XmlPullParserException {
final String launcherPackageName = ShortcutService.parseStringAttribute(parser,
ATTR_PACKAGE_NAME);
+ final int launcherUserId = ShortcutService.parseIntAttribute(parser,
+ ATTR_LAUNCHER_USER_ID, ownerUserId);
- final ShortcutLauncher ret = new ShortcutLauncher(userId, launcherPackageName);
+ final ShortcutLauncher ret = new ShortcutLauncher(launcherUserId, launcherPackageName,
+ launcherUserId);
ArraySet<String> ids = null;
final int outerDepth = parser.getDepth();
@@ -174,6 +198,8 @@
pw.print(prefix);
pw.print("Launcher: ");
pw.print(mPackageName);
+ pw.print(" UserId: ");
+ pw.print(mLauncherUserId);
pw.println();
final int size = mPinnedShortcuts.size();
@@ -190,7 +216,7 @@
for (int j = 0; j < idSize; j++) {
pw.print(prefix);
- pw.print(" ");
+ pw.print(" Pinned: ");
pw.print(ids.valueAt(j));
pw.println();
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d614251..e4d5787 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -41,7 +41,7 @@
/**
* Package information used by {@link ShortcutService}.
*/
-class ShortcutPackage {
+class ShortcutPackage implements ShortcutPackageItem {
private static final String TAG = ShortcutService.TAG;
static final String TAG_ROOT = "package";
@@ -64,10 +64,10 @@
private static final String ATTR_BITMAP_PATH = "bitmap-path";
@UserIdInt
- final int mUserId;
+ private final int mUserId;
@NonNull
- final String mPackageName;
+ private final String mPackageName;
/**
* All the shortcuts from the package, keyed on IDs.
@@ -94,6 +94,19 @@
mPackageName = packageName;
}
+ @UserIdInt
+ public int getUserId() {
+ return mUserId;
+ }
+
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * Note this does *not* provide a correct view to the calling launcher.
+ */
@Nullable
public ShortcutInfo findShortcutById(String id) {
return mShortcuts.get(id);
@@ -219,8 +232,8 @@
}
// Then, for the pinned set for each launcher, set the pin flag one by one.
- final ArrayMap<String, ShortcutLauncher> launchers =
- s.getUserShortcutsLocked(mUserId).getLaunchers();
+ final ArrayMap<ShortcutUser.PackageWithUser, ShortcutLauncher> launchers =
+ s.getUserShortcutsLocked(mUserId).getAllLaunchers();
for (int l = launchers.size() - 1; l >= 0; l--) {
final ShortcutLauncher launcherShortcuts = launchers.valueAt(l);
@@ -291,12 +304,24 @@
* Find all shortcuts that match {@code query}.
*/
public void findAll(@NonNull ShortcutService s, @NonNull List<ShortcutInfo> result,
+ @Nullable Predicate<ShortcutInfo> query, int cloneFlag) {
+ findAll(s, result, query, cloneFlag, null, 0);
+ }
+
+ /**
+ * Find all shortcuts that match {@code query}.
+ *
+ * This will also provide a "view" for each launcher -- a non-dynamic shortcut that's not pinned
+ * by the calling launcher will not be included in the result, and also "isPinned" will be
+ * adjusted for the caller too.
+ */
+ public void findAll(@NonNull ShortcutService s, @NonNull List<ShortcutInfo> result,
@Nullable Predicate<ShortcutInfo> query, int cloneFlag,
- @Nullable String callingLauncher) {
+ @Nullable String callingLauncher, int launcherUserId) {
// Set of pinned shortcuts by the calling launcher.
final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
- : s.getLauncherShortcuts(callingLauncher, mUserId)
+ : s.getLauncherShortcuts(callingLauncher, mUserId, launcherUserId)
.getPinnedShortcutIds(mPackageName);
for (int i = 0; i < mShortcuts.size(); i++) {
@@ -381,7 +406,8 @@
pw.println(")");
}
- public void saveToXml(@NonNull XmlSerializer out) throws IOException, XmlPullParserException {
+ public void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
+ throws IOException, XmlPullParserException {
final int size = mShortcuts.size();
if (size == 0 && mApiCallCount == 0) {
@@ -396,14 +422,19 @@
ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
for (int j = 0; j < size; j++) {
- saveShortcut(out, mShortcuts.valueAt(j));
+ saveShortcut(out, mShortcuts.valueAt(j), forBackup);
}
out.endTag(null, TAG_ROOT);
}
- private static void saveShortcut(XmlSerializer out, ShortcutInfo si)
+ private static void saveShortcut(XmlSerializer out, ShortcutInfo si, boolean forBackup)
throws IOException, XmlPullParserException {
+ if (forBackup) {
+ if (!si.isPinned()) {
+ return; // Backup only pinned icons.
+ }
+ }
out.startTag(null, TAG_SHORTCUT);
ShortcutService.writeAttr(out, ATTR_ID, si.getId());
// writeAttr(out, "package", si.getPackageName()); // not needed
@@ -414,9 +445,17 @@
ShortcutService.writeAttr(out, ATTR_WEIGHT, si.getWeight());
ShortcutService.writeAttr(out, ATTR_TIMESTAMP,
si.getLastChangedTimestamp());
- ShortcutService.writeAttr(out, ATTR_FLAGS, si.getFlags());
- ShortcutService.writeAttr(out, ATTR_ICON_RES, si.getIconResourceId());
- ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+ if (forBackup) {
+ // Don't write icon information. Also drop the dynamic flag.
+ ShortcutService.writeAttr(out, ATTR_FLAGS,
+ si.getFlags() &
+ ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
+ | ShortcutInfo.FLAG_DYNAMIC));
+ } else {
+ ShortcutService.writeAttr(out, ATTR_FLAGS, si.getFlags());
+ ShortcutService.writeAttr(out, ATTR_ICON_RES, si.getIconResourceId());
+ ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+ }
ShortcutService.writeTagExtra(out, TAG_INTENT_EXTRAS,
si.getIntentPersistableExtras());
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
new file mode 100644
index 0000000..ab45689
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
+
+import libcore.io.Base64;
+import libcore.util.HexEncoding;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Package information used by {@link android.content.pm.ShortcutManager} for backup / restore.
+ *
+ * TODO: The methods about signature hashes are copied from BackupManagerService, which is not
+ * visible here. Unify the code.
+ */
+class ShortcutPackageInfo implements ShortcutPackageItem {
+ private static final String TAG = ShortcutService.TAG;
+
+ static final String TAG_ROOT = "package-info";
+ private static final String ATTR_USER_ID = "user";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_VERSION = "version";
+ private static final String ATTR_SHADOW = "shadow";
+
+ private static final String TAG_SIGNATURE = "signature";
+ private static final String ATTR_SIGNATURE_HASH = "hash";
+
+ private final String mPackageName;
+ private final int mUserId;
+
+ /**
+ * When true, this package information was restored from the previous device, and the app hasn't
+ * been installed yet.
+ */
+ private boolean mIsShadow;
+ private int mVersionCode;
+ private ArrayList<byte[]> mSigHashes;
+
+ private ShortcutPackageInfo(String packageName, int userId,
+ int versionCode, ArrayList<byte[]> sigHashes, boolean isShadow) {
+ mPackageName = Preconditions.checkNotNull(packageName);
+ mUserId = userId;
+ mVersionCode = versionCode;
+ mIsShadow = isShadow;
+ mSigHashes = sigHashes;
+ }
+
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public int getUserId() {
+ return mUserId;
+ }
+
+ public boolean isShadow() {
+ return mIsShadow;
+ }
+
+ public boolean isInstalled() {
+ return !mIsShadow;
+ }
+
+ public void setShadow(boolean shadow) {
+ mIsShadow = shadow;
+ }
+
+ public int getVersionCode() {
+ return mVersionCode;
+ }
+
+ private static byte[] hashSignature(Signature sig) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ digest.update(sig.toByteArray());
+ return digest.digest();
+ } catch (NoSuchAlgorithmException e) {
+ Slog.w(TAG, "No SHA-256 algorithm found!");
+ }
+ return null;
+ }
+
+ private static ArrayList<byte[]> hashSignatureArray(Signature[] sigs) {
+ if (sigs == null) {
+ return null;
+ }
+
+ ArrayList<byte[]> hashes = new ArrayList<byte[]>(sigs.length);
+ for (Signature s : sigs) {
+ hashes.add(hashSignature(s));
+ }
+ return hashes;
+ }
+
+ private static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
+ if (target == null) {
+ return false;
+ }
+
+ // If the target resides on the system partition, we allow it to restore
+ // data from the like-named package in a restore set even if the signatures
+ // do not match. (Unlike general applications, those flashed to the system
+ // partition will be signed with the device's platform certificate, so on
+ // different phones the same system app will have different signatures.)
+ if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return true;
+ }
+
+ // Allow unsigned apps, but not signed on one device and unsigned on the other
+ // !!! TODO: is this the right policy?
+ Signature[] deviceSigs = target.signatures;
+ if ((storedSigHashes == null || storedSigHashes.size() == 0)
+ && (deviceSigs == null || deviceSigs.length == 0)) {
+ return true;
+ }
+ if (storedSigHashes == null || deviceSigs == null) {
+ return false;
+ }
+
+ // !!! TODO: this demands that every stored signature match one
+ // that is present on device, and does not demand the converse.
+ // Is this this right policy?
+ final int nStored = storedSigHashes.size();
+ final int nDevice = deviceSigs.length;
+
+ // hash each on-device signature
+ ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
+ for (int i = 0; i < nDevice; i++) {
+ deviceHashes.add(hashSignature(deviceSigs[i]));
+ }
+
+ // now ensure that each stored sig (hash) matches an on-device sig (hash)
+ for (int n = 0; n < nStored; n++) {
+ boolean match = false;
+ final byte[] storedHash = storedSigHashes.get(n);
+ for (int i = 0; i < nDevice; i++) {
+ if (Arrays.equals(storedHash, deviceHashes.get(i))) {
+ match = true;
+ break;
+ }
+ }
+ // match is false when no on-device sig matched one of the stored ones
+ if (!match) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean canRestoreTo(PackageInfo target) {
+ if (target.versionCode < mVersionCode) {
+ Slog.w(TAG, String.format("Package current version %d < backed up version %d",
+ target.versionCode, mVersionCode));
+ return false;
+ }
+ if (!signaturesMatch(mSigHashes, target)) {
+ Slog.w(TAG, "Package signature mismtach");
+ return false;
+ }
+ return true;
+ }
+
+ public static ShortcutPackageInfo generateForInstalledPackage(
+ ShortcutService s, String packageName, @UserIdInt int userId) {
+ final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, userId);
+ if (pi.signatures == null || pi.signatures.length == 0) {
+ Slog.e(TAG, "Can't get signatures: package=" + packageName);
+ return null;
+ }
+ final ShortcutPackageInfo ret = new ShortcutPackageInfo(packageName, userId, pi.versionCode,
+ hashSignatureArray(pi.signatures), /* shadow=*/ false);
+
+ return ret;
+ }
+
+ public void refreshAndSave(ShortcutService s, @UserIdInt int userId) {
+ final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, userId);
+ if (pi == null) {
+ Slog.w(TAG, "Package not found: " + mPackageName);
+ return;
+ }
+ mVersionCode = pi.versionCode;
+ mSigHashes = hashSignatureArray(pi.signatures);
+
+ s.scheduleSaveUser(userId);
+ }
+
+ public void saveToXml(XmlSerializer out, boolean forBackup)
+ throws IOException, XmlPullParserException {
+
+ out.startTag(null, TAG_ROOT);
+
+ ShortcutService.writeAttr(out, ATTR_NAME, mPackageName);
+ ShortcutService.writeAttr(out, ATTR_USER_ID, mUserId);
+ ShortcutService.writeAttr(out, ATTR_VERSION, mVersionCode);
+ ShortcutService.writeAttr(out, ATTR_SHADOW, mIsShadow);
+
+ for (int i = 0; i < mSigHashes.size(); i++) {
+ out.startTag(null, TAG_SIGNATURE);
+ ShortcutService.writeAttr(out, ATTR_SIGNATURE_HASH, Base64.encode(mSigHashes.get(i)));
+ out.endTag(null, TAG_SIGNATURE);
+ }
+ out.endTag(null, TAG_ROOT);
+ }
+
+ public static ShortcutPackageInfo loadFromXml(XmlPullParser parser, int ownerUserId)
+ throws IOException, XmlPullParserException {
+
+ final String packageName = ShortcutService.parseStringAttribute(parser, ATTR_NAME);
+ final int userId = ShortcutService.parseIntAttribute(parser, ATTR_USER_ID, ownerUserId);
+ final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION);
+ final boolean shadow = ShortcutService.parseBooleanAttribute(parser, ATTR_SHADOW);
+
+ final ArrayList<byte[]> hashes = new ArrayList<>();
+
+
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+ final int depth = parser.getDepth();
+ final String tag = parser.getName();
+ switch (tag) {
+ case TAG_SIGNATURE: {
+ final String hash = ShortcutService.parseStringAttribute(
+ parser, ATTR_SIGNATURE_HASH);
+ hashes.add(Base64.decode(hash.getBytes()));
+ continue;
+ }
+ }
+ throw ShortcutService.throwForInvalidTag(depth, tag);
+ }
+ return new ShortcutPackageInfo(packageName, userId, versionCode, hashes, shadow);
+ }
+
+ public void dump(ShortcutService s, PrintWriter pw, String prefix) {
+ pw.println();
+
+ pw.print(prefix);
+ pw.print("PackageInfo: ");
+ pw.print(mPackageName);
+ pw.println();
+
+ pw.print(prefix);
+ pw.print(" User: ");
+ pw.print(mUserId);
+ pw.println();
+
+ pw.print(prefix);
+ pw.print(" IsShadow: ");
+ pw.print(mIsShadow);
+ pw.println();
+
+ pw.print(prefix);
+ pw.print(" Version: ");
+ pw.print(mVersionCode);
+ pw.println();
+
+ for (int i = 0; i < mSigHashes.size(); i++) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print("SigHash: ");
+ pw.println(HexEncoding.encode(mSigHashes.get(i)));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
new file mode 100644
index 0000000..526c84d
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+
+public interface ShortcutPackageItem {
+ @NonNull
+ String getPackageName();
+
+ void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
+ throws IOException, XmlPullParserException;
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 42954f5..cf11025 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -19,15 +19,18 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.IShortcutService;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
@@ -55,7 +58,6 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
-import android.text.format.Formatter;
import android.text.format.Time;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -70,13 +72,14 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.pm.ShortcutUser.PackageWithUser;
import libcore.io.IoUtils;
-import libcore.util.Objects;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -101,14 +104,9 @@
*
* - Default launcher check does take a few ms. Worth caching.
*
- * - Allow non-default launcher to start pinned shortcuts. (but not dynamic.)
+ * - Don't backup launcher from different profile.
*
- * - Extract the user/package/launcher classes to their own files. Maybe rename so they all have
- * the same "Shortcut" prefix.
- *
- * - Listen to PACKAGE_*, remove orphan info, update timestamp for icon res
- * -> Need to scan all packages when a user starts too.
- * -> Clear data -> remove all dynamic? but not the pinned?
+ * - Clear data -> remove all dynamic? but not the pinned?
*
* - Scan and remove orphan bitmaps (just in case).
*
@@ -122,6 +120,7 @@
static final boolean DEBUG = false; // STOPSHIP if true
static final boolean DEBUG_LOAD = false; // STOPSHIP if true
+ static final boolean ENABLE_DEBUG_COMMAND = true; // STOPSHIP if true
@VisibleForTesting
static final long DEFAULT_RESET_INTERVAL_SEC = 24 * 60 * 60; // 1 day
@@ -249,12 +248,18 @@
private int mSaveDelayMillis;
+ private final IPackageManager mIPackageManager;
private final PackageManagerInternal mPackageManagerInternal;
private final UserManager mUserManager;
@GuardedBy("mLock")
private List<Integer> mDirtyUserIds = new ArrayList<>();
+ private static final int PACKAGE_MATCH_FLAGS =
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES;
+
public ShortcutService(Context context) {
this(context, BackgroundThread.get().getLooper());
}
@@ -264,6 +269,7 @@
mContext = Preconditions.checkNotNull(context);
LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
mHandler = new Handler(looper);
+ mIPackageManager = AppGlobals.getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mUserManager = context.getSystemService(UserManager.class);
@@ -319,6 +325,8 @@
synchronized (mLock) {
// Preload
getUserShortcutsLocked(userId);
+
+ cleanupGonePackages(userId);
}
}
@@ -434,20 +442,32 @@
return parser.getAttributeValue(null, attribute);
}
+ static boolean parseBooleanAttribute(XmlPullParser parser, String attribute) {
+ return parseLongAttribute(parser, attribute) == 1;
+ }
+
static int parseIntAttribute(XmlPullParser parser, String attribute) {
return (int) parseLongAttribute(parser, attribute);
}
+ static int parseIntAttribute(XmlPullParser parser, String attribute, int def) {
+ return (int) parseLongAttribute(parser, attribute, def);
+ }
+
static long parseLongAttribute(XmlPullParser parser, String attribute) {
+ return parseLongAttribute(parser, attribute, 0);
+ }
+
+ static long parseLongAttribute(XmlPullParser parser, String attribute, long def) {
final String value = parseStringAttribute(parser, attribute);
if (TextUtils.isEmpty(value)) {
- return 0;
+ return def;
}
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
Slog.e(TAG, "Error parsing long " + value);
- return 0;
+ return def;
}
}
@@ -510,6 +530,12 @@
writeAttr(out, name, String.valueOf(value));
}
+ static void writeAttr(XmlSerializer out, String name, boolean value) throws IOException {
+ if (value) {
+ writeAttr(out, name, "1");
+ }
+ }
+
static void writeAttr(XmlSerializer out, String name, ComponentName comp) throws IOException {
if (comp == null) return;
writeAttr(out, name, comp.flattenToString());
@@ -616,7 +642,7 @@
out.setOutput(outs, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
- getUserShortcutsLocked(userId).saveToXml(out);
+ getUserShortcutsLocked(userId).saveToXml(this, out, /* forBackup= */ false);
out.endDocument();
@@ -682,17 +708,17 @@
}
private void scheduleSaveBaseState() {
- scheduleSave(UserHandle.USER_NULL); // Special case -- use USER_NULL for base state.
+ scheduleSaveInner(UserHandle.USER_NULL); // Special case -- use USER_NULL for base state.
}
void scheduleSaveUser(@UserIdInt int userId) {
- scheduleSave(userId);
+ scheduleSaveInner(userId);
}
// In order to re-schedule, we need to reuse the same instance, so keep it in final.
private final Runnable mSaveDirtyInfoRunner = this::saveDirtyInfo;
- private void scheduleSave(@UserIdInt int userId) {
+ private void scheduleSaveInner(@UserIdInt int userId) {
if (DEBUG) {
Slog.d(TAG, "Scheduling to save for " + userId);
}
@@ -802,8 +828,8 @@
@GuardedBy("mLock")
@NonNull
ShortcutLauncher getLauncherShortcuts(
- @NonNull String packageName, @UserIdInt int userId) {
- return getUserShortcutsLocked(userId).getLauncherShortcuts(packageName);
+ @NonNull String packageName, @UserIdInt int userId, @UserIdInt int launcherUserId) {
+ return getUserShortcutsLocked(userId).getLauncherShortcuts(packageName, launcherUserId);
}
// === Caller validation ===
@@ -1035,19 +1061,6 @@
throw new SecurityException("Caller UID= doesn't own " + packageName);
}
- // Test overrides it.
- int injectGetPackageUid(@NonNull String packageName, @UserIdInt int userId) {
- try {
- return mContext.getPackageManager().getPackageUidAsUser(packageName,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_UNINSTALLED_PACKAGES,
- userId);
- } catch (NameNotFoundException e) {
- return -1;
- }
- }
-
void postToHandler(Runnable r) {
mHandler.post(r);
}
@@ -1169,6 +1182,8 @@
final int size = newShortcuts.size();
synchronized (mLock) {
+ getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
// Throttling.
@@ -1204,6 +1219,8 @@
final int size = newShortcuts.size();
synchronized (mLock) {
+ getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
// Throttling.
@@ -1241,6 +1258,8 @@
verifyCaller(packageName, userId);
synchronized (mLock) {
+ getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
// Throttling.
@@ -1308,8 +1327,7 @@
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
- getPackageShortcutsLocked(packageName, userId).findAll(this, ret, query, cloneFlags,
- /* callingLauncher= */ null);
+ getPackageShortcutsLocked(packageName, userId).findAll(this, ret, query, cloneFlags);
return new ParceledListSlice<>(ret);
}
@@ -1376,10 +1394,7 @@
@VisibleForTesting
boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
synchronized (mLock) {
- long start = 0;
- if (DEBUG) {
- start = System.currentTimeMillis();
- }
+ long start = System.currentTimeMillis();
final ShortcutUser user = getUserShortcutsLocked(userId);
@@ -1430,8 +1445,8 @@
lastPriority = ri.priority;
}
}
+ final long end = System.currentTimeMillis();
if (DEBUG) {
- long end = System.currentTimeMillis();
Slog.v(TAG, String.format("hasShortcutPermission took %d ms", end - start));
}
if (detected != null) {
@@ -1450,22 +1465,26 @@
// === House keeping ===
@VisibleForTesting
- void cleanUpPackageLocked(String packageName, int userId) {
- final boolean wasUserLoaded = isUserLoadedLocked(userId);
+ void cleanUpPackageLocked(String packageName, int owningUserId, int packageUserId) {
+ final boolean wasUserLoaded = isUserLoadedLocked(owningUserId);
- final ShortcutUser mUser = getUserShortcutsLocked(userId);
+ final ShortcutUser mUser = getUserShortcutsLocked(owningUserId);
boolean doNotify = false;
// First, remove the package from the package list (if the package is a publisher).
- if (mUser.getPackages().remove(packageName) != null) {
- doNotify = true;
+ if (packageUserId == owningUserId) {
+ if (mUser.getPackages().remove(packageName) != null) {
+ doNotify = true;
+ }
}
+
// Also remove from the launcher list (if the package is a launcher).
- mUser.getLaunchers().remove(packageName);
+ mUser.removeLauncher(packageUserId, packageName);
// Then remove pinned shortcuts from all launchers.
- for (int i = mUser.getLaunchers().size() - 1; i >= 0; i--) {
- mUser.getLaunchers().valueAt(i).cleanUpPackage(packageName);
+ final ArrayMap<PackageWithUser, ShortcutLauncher> launchers = mUser.getAllLaunchers();
+ for (int i = launchers.size() - 1; i >= 0; i--) {
+ launchers.valueAt(i).cleanUpPackage(packageName);
}
// Now there may be orphan shortcuts because we removed pinned shortucts at the previous
// step. Remove them too.
@@ -1473,15 +1492,18 @@
mUser.getPackages().valueAt(i).refreshPinnedFlags(this);
}
- scheduleSaveUser(userId);
+ // Remove the package info too.
+ mUser.removePackageInfo(packageUserId, packageName);
+
+ scheduleSaveUser(owningUserId);
if (doNotify) {
- notifyListeners(packageName, userId);
+ notifyListeners(packageName, owningUserId);
}
if (!wasUserLoaded) {
// Note this will execute the scheduled save.
- unloadUserLocked(userId);
+ unloadUserLocked(owningUserId);
}
}
@@ -1490,7 +1512,7 @@
*/
private class LocalService extends ShortcutServiceInternal {
@Override
- public List<ShortcutInfo> getShortcuts(
+ public List<ShortcutInfo> getShortcuts(int launcherUserId,
@NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable ComponentName componentName,
int queryFlags, int userId) {
@@ -1502,14 +1524,14 @@
synchronized (mLock) {
if (packageName != null) {
- getShortcutsInnerLocked(
+ getShortcutsInnerLocked(launcherUserId,
callingPackage, packageName, changedSince,
componentName, queryFlags, userId, ret, cloneFlag);
} else {
final ArrayMap<String, ShortcutPackage> packages =
getUserShortcutsLocked(userId).getPackages();
for (int i = packages.size() - 1; i >= 0; i--) {
- getShortcutsInnerLocked(
+ getShortcutsInnerLocked(launcherUserId,
callingPackage, packages.keyAt(i), changedSince,
componentName, queryFlags, userId, ret, cloneFlag);
}
@@ -1518,7 +1540,7 @@
return ret;
}
- private void getShortcutsInnerLocked(@NonNull String callingPackage,
+ private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
@Nullable String packageName,long changedSince,
@Nullable ComponentName componentName, int queryFlags,
int userId, ArrayList<ShortcutInfo> ret, int cloneFlag) {
@@ -1538,11 +1560,11 @@
((queryFlags & ShortcutQuery.FLAG_GET_PINNED) != 0)
&& si.isPinned();
return matchDynamic || matchPinned;
- }, cloneFlag, callingPackage);
+ }, cloneFlag, callingPackage, launcherUserId);
}
@Override
- public List<ShortcutInfo> getShortcutInfo(
+ public List<ShortcutInfo> getShortcutInfo(int launcherUserId,
@NonNull String callingPackage,
@NonNull String packageName, @Nullable List<String> ids, int userId) {
// Calling permission must be checked by LauncherAppsImpl.
@@ -1554,37 +1576,73 @@
getPackageShortcutsLocked(packageName, userId).findAll(
ShortcutService.this, ret,
(ShortcutInfo si) -> idSet.contains(si.getId()),
- ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER, callingPackage);
+ ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER, callingPackage, launcherUserId);
}
return ret;
}
@Override
- public void pinShortcuts(@NonNull String callingPackage, @NonNull String packageName,
+ public boolean isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ Preconditions.checkStringNotEmpty(packageName, "packageName");
+ Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
+
+ synchronized (mLock) {
+ final ShortcutInfo si = getShortcutInfoLocked(
+ launcherUserId, callingPackage, packageName, shortcutId, userId);
+ return si != null && si.isPinned();
+ }
+ }
+
+ public ShortcutInfo getShortcutInfoLocked(
+ int launcherUserId, @NonNull String callingPackage,
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ Preconditions.checkStringNotEmpty(packageName, "packageName");
+ Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
+
+ final ArrayList<ShortcutInfo> list = new ArrayList<>(1);
+ getPackageShortcutsLocked(packageName, userId).findAll(
+ ShortcutService.this, list,
+ (ShortcutInfo si) -> shortcutId.equals(si.getId()),
+ /* clone flags=*/ 0, callingPackage, launcherUserId);
+ return list.size() == 0 ? null : list.get(0);
+ }
+
+ @Override
+ public void pinShortcuts(int launcherUserId,
+ @NonNull String callingPackage, @NonNull String packageName,
@NonNull List<String> shortcutIds, int userId) {
// Calling permission must be checked by LauncherAppsImpl.
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkNotNull(shortcutIds, "shortcutIds");
synchronized (mLock) {
- getLauncherShortcuts(callingPackage, userId).pinShortcuts(
+ getUserShortcutsLocked(userId).ensurePackageInfo(
+ ShortcutService.this, callingPackage, launcherUserId);
+
+ getLauncherShortcuts(callingPackage, userId, launcherUserId).pinShortcuts(
ShortcutService.this, packageName, shortcutIds);
}
userPackageChanged(packageName, userId);
}
@Override
- public Intent createShortcutIntent(@NonNull String callingPackage,
+ public Intent createShortcutIntent(int launcherUserId,
+ @NonNull String callingPackage,
@NonNull String packageName, @NonNull String shortcutId, int userId) {
// Calling permission must be checked by LauncherAppsImpl.
Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
synchronized (mLock) {
- final ShortcutInfo fullShortcut =
- getPackageShortcutsLocked(packageName, userId)
- .findShortcutById(shortcutId);
- return fullShortcut == null ? null : fullShortcut.getIntent();
+ // Make sure the shortcut is actually visible to the launcher.
+ final ShortcutInfo si = getShortcutInfoLocked(
+ launcherUserId, callingPackage, packageName, shortcutId, userId);
+ // "si == null" should suffice here, but check the flags too just to make sure.
+ if (si == null || !(si.isDynamic() || si.isPinned())) {
+ return null;
+ }
+ return si.getIntent();
}
}
@@ -1596,7 +1654,8 @@
}
@Override
- public int getShortcutIconResId(@NonNull String callingPackage,
+ public int getShortcutIconResId(int launcherUserId,
+ @NonNull String callingPackage,
@NonNull ShortcutInfo shortcut, int userId) {
Preconditions.checkNotNull(shortcut, "shortcut");
@@ -1609,7 +1668,8 @@
}
@Override
- public ParcelFileDescriptor getShortcutIconFd(@NonNull String callingPackage,
+ public ParcelFileDescriptor getShortcutIconFd(int launcherUserId,
+ @NonNull String callingPackage,
@NonNull ShortcutInfo shortcutIn, int userId) {
Preconditions.checkNotNull(shortcutIn, "shortcut");
@@ -1635,12 +1695,22 @@
}
@Override
- public boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
- return ShortcutService.this.hasShortcutHostPermission(callingPackage, userId);
+ public boolean hasShortcutHostPermission(int launcherUserId,
+ @NonNull String callingPackage) {
+ return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId);
}
}
- private PackageMonitor mPackageMonitor = new PackageMonitor() {
+ /**
+ * Package event callbacks.
+ */
+ @VisibleForTesting
+ final PackageMonitor mPackageMonitor = new PackageMonitor() {
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ handlePackageAdded(packageName, getChangingUserId());
+ }
+
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
handlePackageUpdateFinished(packageName, getChangingUserId());
@@ -1650,38 +1720,131 @@
public void onPackageRemoved(String packageName, int uid) {
handlePackageRemoved(packageName, getChangingUserId());
}
-
- @Override
- public void onPackageRemovedAllUsers(String packageName, int uid) {
- handlePackageRemovedAllUsers(packageName, getChangingUserId());
- }
};
- void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) {
+ /**
+ * Called when a user is unlocked. Check all known packages still exist, and otherwise
+ * perform cleanup.
+ */
+ @VisibleForTesting
+ void cleanupGonePackages(@UserIdInt int userId) {
if (DEBUG) {
- Slog.d(TAG, "onPackageUpdateFinished() userId=" + userId);
+ Slog.d(TAG, "cleanupGonePackages() userId=" + userId);
}
- // TODO Update the version.
- }
+ ArrayList<PackageWithUser> gonePackages = null;
- void handlePackageRemoved(String packageName, @UserIdInt int userId) {
- if (DEBUG) {
- Slog.d(TAG, "onPackageRemoved() userId=" + userId);
- }
synchronized (mLock) {
- cleanUpPackageLocked(packageName, userId);
+ final ShortcutUser user = getUserShortcutsLocked(userId);
+ final ArrayMap<PackageWithUser, ShortcutPackageInfo> infos = user.getAllPackageInfos();
+ for (int i = infos.size() -1; i >= 0; i--) {
+ final ShortcutPackageInfo info = infos.valueAt(i);
+ if (info.isShadow()) {
+ continue;
+ }
+ if (isPackageInstalled(info.getPackageName(), info.getUserId())) {
+ continue;
+ }
+ gonePackages = ArrayUtils.add(gonePackages,
+ PackageWithUser.of(info.getUserId(), info.getPackageName()));
+ }
+ if (gonePackages != null) {
+ for (int i = gonePackages.size() - 1; i >= 0; i--) {
+ final PackageWithUser pu = gonePackages.get(i);
+ cleanUpPackageLocked(pu.packageName, userId, pu.userId);
+ }
+ }
}
}
- void handlePackageRemovedAllUsers(String packageName, @UserIdInt int userId) {
+ private void handlePackageAdded(String packageName, @UserIdInt int userId) {
if (DEBUG) {
- Slog.d(TAG, "onPackageRemovedAllUsers() userId=" + userId);
+ Slog.d(TAG, String.format("handlePackageAdded: %s user=%d", packageName, userId));
}
synchronized (mLock) {
- cleanUpPackageLocked(packageName, userId);
- }
+ final ShortcutPackageInfo existing = getUserShortcutsLocked(userId)
+ .getPackageInfo(userId, packageName);
- // TODO Remove from all users, which we can't if the user is locked.
+ if (existing != null && existing.isShadow()) {
+ Slog.w(TAG, "handlePackageAdded: TODO Restore not implemented");
+ }
+ }
+ }
+
+ private void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, String.format("handlePackageUpdateFinished: %s user=%d", packageName, userId));
+ }
+ synchronized (mLock) {
+ final ShortcutPackageInfo spi =
+ getUserShortcutsLocked(userId).getPackageInfo(userId, packageName);
+ if (spi != null) {
+ spi.refreshAndSave(this, userId);
+ }
+ }
+ }
+
+ private void handlePackageRemoved(String packageName, @UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, String.format("handlePackageRemoved: %s user=%d", packageName, userId));
+ }
+ synchronized (mLock) {
+ cleanUpPackageLocked(packageName, userId, userId);
+ }
+ }
+
+ // === Backup & restore ===
+
+ PackageInfo getPackageInfoWithSignatures(String packageName, @UserIdInt int userId) {
+ return injectPackageInfo(packageName, userId, true);
+ }
+
+ int injectGetPackageUid(@NonNull String packageName, @UserIdInt int userId) {
+ try {
+ return mIPackageManager.getPackageUid(packageName, PACKAGE_MATCH_FLAGS
+ , userId);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Slog.wtf(TAG, "RemoteException", e);
+ return -1;
+ }
+ }
+
+ @VisibleForTesting
+ PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
+ boolean getSignatures) {
+ try {
+ return mIPackageManager.getPackageInfo(packageName, PACKAGE_MATCH_FLAGS
+ | (getSignatures ? PackageManager.GET_SIGNATURES : 0)
+ , userId);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Slog.wtf(TAG, "RemoteException", e);
+ return null;
+ }
+ }
+
+ @VisibleForTesting
+ ApplicationInfo injectApplicationInfo(String packageName, @UserIdInt int userId) {
+ try {
+ return mIPackageManager.getApplicationInfo(packageName, PACKAGE_MATCH_FLAGS, userId);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Slog.wtf(TAG, "RemoteException", e);
+ return null;
+ }
+ }
+
+ private boolean isApplicationFlagSet(String packageName, int userId, int flags) {
+ final ApplicationInfo ai = injectApplicationInfo(packageName, userId);
+ return (ai != null) && ((ai.flags & flags) == flags);
+ }
+
+ boolean shouldBackupApp(String packageName, int userId) {
+ return isApplicationFlagSet(packageName, userId, ApplicationInfo.FLAG_ALLOW_BACKUP);
+ }
+
+ private boolean isPackageInstalled(String packageName, int userId) {
+ return isApplicationFlagSet(packageName, userId, ApplicationInfo.FLAG_INSTALLED);
}
// === Dump ===
@@ -2039,4 +2202,19 @@
return pkg.findShortcutById(shortcutId);
}
}
+
+ @VisibleForTesting
+ ShortcutPackageInfo getPackageInfoForTest(String packageName, int userId) {
+ return getPackageInfoForTest(packageName, userId, userId);
+ }
+
+ @VisibleForTesting
+ ShortcutPackageInfo getPackageInfoForTest(String packageName, int userId, int packageUserId) {
+ synchronized (mLock) {
+ final ShortcutUser user = mUsers.get(userId);
+ if (user == null) return null;
+
+ return user.getPackageInfo(packageUserId, packageName);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 4a6b1e4..19feb2a 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -19,6 +19,9 @@
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.util.ArrayMap;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
import libcore.util.Objects;
@@ -40,12 +43,48 @@
private static final String ATTR_VALUE = "value";
+ static final class PackageWithUser {
+ final int userId;
+ final String packageName;
+
+ private PackageWithUser(int userId, String packageName) {
+ this.userId = userId;
+ this.packageName = Preconditions.checkNotNull(packageName);
+ }
+
+ public static PackageWithUser of(int launcherUserId, String packageName) {
+ return new PackageWithUser(launcherUserId, packageName);
+ }
+
+ @Override
+ public int hashCode() {
+ return packageName.hashCode() ^ userId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof PackageWithUser)) {
+ return false;
+ }
+ final PackageWithUser that = (PackageWithUser) obj;
+
+ return userId == that.userId && packageName.equals(that.packageName);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("{Launcher: %d, %s}", userId, packageName);
+ }
+ }
+
@UserIdInt
final int mUserId;
private final ArrayMap<String, ShortcutPackage> mPackages = new ArrayMap<>();
- private final ArrayMap<String, ShortcutLauncher> mLaunchers = new ArrayMap<>();
+ private final ArrayMap<PackageWithUser, ShortcutLauncher> mLaunchers = new ArrayMap<>();
+
+ private final ArrayMap<PackageWithUser, ShortcutPackageInfo> mPackageInfos = new ArrayMap<>();
private ComponentName mLauncherComponent;
@@ -57,10 +96,41 @@
return mPackages;
}
- public ArrayMap<String, ShortcutLauncher> getLaunchers() {
+ public ArrayMap<PackageWithUser, ShortcutLauncher> getAllLaunchers() {
return mLaunchers;
}
+ public ShortcutLauncher getLauncher(@UserIdInt int userId, @NonNull String packageName) {
+ return mLaunchers.get(PackageWithUser.of(userId, packageName));
+ }
+
+ public void addLauncher(ShortcutLauncher launcher) {
+ mLaunchers.put(PackageWithUser.of(launcher.getUserId(), launcher.getPackageName()),
+ launcher);
+ }
+
+ public ShortcutLauncher removeLauncher(
+ @UserIdInt int userId, @NonNull String packageName) {
+ return mLaunchers.remove(PackageWithUser.of(userId, packageName));
+ }
+
+ public ArrayMap<PackageWithUser, ShortcutPackageInfo> getAllPackageInfos() {
+ return mPackageInfos;
+ }
+
+ public ShortcutPackageInfo getPackageInfo(@UserIdInt int userId, @NonNull String packageName) {
+ return mPackageInfos.get(PackageWithUser.of(userId, packageName));
+ }
+
+ public void addPackageInfo(ShortcutPackageInfo spi) {
+ mPackageInfos.put(PackageWithUser.of(spi.getUserId(), spi.getPackageName()), spi);
+ }
+
+ public ShortcutPackageInfo removePackageInfo(
+ @UserIdInt int userId, @NonNull String packageName) {
+ return mPackageInfos.remove(PackageWithUser.of(userId, packageName));
+ }
+
public ShortcutPackage getPackageShortcuts(@NonNull String packageName) {
ShortcutPackage ret = mPackages.get(packageName);
if (ret == null) {
@@ -70,34 +140,70 @@
return ret;
}
- public ShortcutLauncher getLauncherShortcuts(@NonNull String packageName) {
- ShortcutLauncher ret = mLaunchers.get(packageName);
+ public ShortcutLauncher getLauncherShortcuts(@NonNull String packageName,
+ @UserIdInt int launcherUserId) {
+ final PackageWithUser key = PackageWithUser.of(launcherUserId, packageName);
+ ShortcutLauncher ret = mLaunchers.get(key);
if (ret == null) {
- ret = new ShortcutLauncher(mUserId, packageName);
- mLaunchers.put(packageName, ret);
+ ret = new ShortcutLauncher(mUserId, packageName, launcherUserId);
+ mLaunchers.put(key, ret);
}
return ret;
}
- public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
+ public void ensurePackageInfo(ShortcutService s, String packageName, @UserIdInt int userId) {
+ final PackageWithUser key = PackageWithUser.of(userId, packageName);
+ final ShortcutPackageInfo existing = mPackageInfos.get(key);
+
+ if (existing != null) {
+ return;
+ }
+ if (ShortcutService.DEBUG) {
+ Slog.d(TAG, String.format("Fetching package info: %s user=%d", packageName, userId));
+ }
+ final ShortcutPackageInfo newSpi = ShortcutPackageInfo.generateForInstalledPackage(
+ s, packageName, userId);
+ mPackageInfos.put(key, newSpi);
+ s.scheduleSaveUser(mUserId);
+ }
+
+ public void saveToXml(ShortcutService s, XmlSerializer out, boolean forBackup)
+ throws IOException, XmlPullParserException {
out.startTag(null, TAG_ROOT);
ShortcutService.writeTagValue(out, TAG_LAUNCHER,
mLauncherComponent);
- final int lsize = mLaunchers.size();
- for (int i = 0; i < lsize; i++) {
- mLaunchers.valueAt(i).saveToXml(out);
+ {
+ final int size = mPackageInfos.size();
+ for (int i = 0; i < size; i++) {
+ saveShortcutPackageItem(s, out, mPackageInfos.valueAt(i), forBackup);
+ }
}
-
- final int psize = mPackages.size();
- for (int i = 0; i < psize; i++) {
- mPackages.valueAt(i).saveToXml(out);
+ {
+ final int size = mLaunchers.size();
+ for (int i = 0; i < size; i++) {
+ saveShortcutPackageItem(s, out, mLaunchers.valueAt(i), forBackup);
+ }
+ }
+ {
+ final int size = mPackages.size();
+ for (int i = 0; i < size; i++) {
+ saveShortcutPackageItem(s, out, mPackages.valueAt(i), forBackup);
+ }
}
out.endTag(null, TAG_ROOT);
}
+ private void saveShortcutPackageItem(ShortcutService s, XmlSerializer out,
+ ShortcutPackageItem spi, boolean forBackup) throws IOException, XmlPullParserException {
+ if (forBackup && !s.shouldBackupApp(spi.getPackageName(), mUserId)) {
+ return; // Don't save.
+ }
+ spi.saveToXml(out, forBackup);
+ }
+
public static ShortcutUser loadFromXml(XmlPullParser parser, int userId)
throws IOException, XmlPullParserException {
final ShortcutUser ret = new ShortcutUser(userId);
@@ -121,15 +227,17 @@
final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml(parser, userId);
// Don't use addShortcut(), we don't need to save the icon.
- ret.getPackages().put(shortcuts.mPackageName, shortcuts);
+ ret.getPackages().put(shortcuts.getPackageName(), shortcuts);
continue;
}
case ShortcutLauncher.TAG_ROOT: {
- final ShortcutLauncher shortcuts =
- ShortcutLauncher.loadFromXml(parser, userId);
+ ret.addLauncher(ShortcutLauncher.loadFromXml(parser, userId));
+ continue;
+ }
- ret.getLaunchers().put(shortcuts.mPackageName, shortcuts);
+ case ShortcutPackageInfo.TAG_ROOT: {
+ ret.addPackageInfo(ShortcutPackageInfo.loadFromXml(parser, userId));
continue;
}
}
@@ -175,5 +283,9 @@
for (int i = 0; i < mPackages.size(); i++) {
mPackages.valueAt(i).dump(s, pw, prefix + " ");
}
+
+ for (int i = 0; i < mPackageInfos.size(); i++) {
+ mPackageInfos.valueAt(i).dump(s, pw, prefix + " ");
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ac19e24..6df36e4 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -20,6 +20,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -37,6 +38,7 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
@@ -122,6 +124,7 @@
private static final String ATTR_ID = "id";
private static final String ATTR_CREATION_TIME = "created";
private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
+ private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint";
private static final String ATTR_SERIAL_NO = "serialNumber";
private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
private static final String ATTR_PARTIAL = "partial";
@@ -380,8 +383,6 @@
removeUserState(ui.id);
}
- onUserForeground(UserHandle.USER_SYSTEM);
-
mAppOpsService = IAppOpsService.Stub.asInterface(
ServiceManager.getService(Context.APP_OPS_SERVICE));
@@ -1541,6 +1542,8 @@
serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
Long.toString(userInfo.lastLoggedInTime));
+ serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT,
+ userInfo.lastLoggedInFingerprint);
if (userInfo.iconPath != null) {
serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath);
}
@@ -1671,6 +1674,7 @@
String iconPath = null;
long creationTime = 0L;
long lastLoggedInTime = 0L;
+ String lastLoggedInFingerprint = null;
int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
boolean partial = false;
@@ -1711,6 +1715,8 @@
iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
+ lastLoggedInFingerprint = parser.getAttributeValue(null,
+ ATTR_LAST_LOGGED_IN_FINGERPRINT);
profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
UserInfo.NO_PROFILE_GROUP_ID);
restrictedProfileParentId = readIntAttribute(parser,
@@ -1763,6 +1769,7 @@
userInfo.serialNumber = serialNumber;
userInfo.creationTime = creationTime;
userInfo.lastLoggedInTime = lastLoggedInTime;
+ userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
userInfo.partial = partial;
userInfo.guestToRemove = guestToRemove;
userInfo.profileGroupId = profileGroupId;
@@ -2189,7 +2196,13 @@
}
private void removeUserState(final int userHandle) {
- mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
+ try {
+ mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
+ } catch (IllegalStateException e) {
+ // This may be simply because the user was partially created.
+ Slog.i(LOG_TAG,
+ "Destroying key for user " + userHandle + " failed, continuing anyway", e);
+ }
// Cleanup package manager settings
mPm.cleanUpUser(this, userHandle);
@@ -2553,7 +2566,7 @@
* Called right before a user is unlocked. This gives us a chance to prepare
* app storage.
*/
- public void onBeforeUnlockUser(int userId) {
+ public void onBeforeUnlockUser(@UserIdInt int userId) {
final int userSerial = getUserSerialNumber(userId);
prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE);
@@ -2563,17 +2576,19 @@
* Make a note of the last started time of a user and do some cleanup.
* @param userId the user that was just foregrounded
*/
- public void onUserForeground(int userId) {
+ public void onUserLoggedIn(@UserIdInt int userId) {
UserData userData = getUserDataNoChecks(userId);
if (userData == null || userData.info.partial) {
Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
return;
}
- long now = System.currentTimeMillis();
+
+ final long now = System.currentTimeMillis();
if (now > EPOCH_PLUS_30_YEARS) {
userData.info.lastLoggedInTime = now;
- scheduleWriteUser(userData);
}
+ userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
+ scheduleWriteUser(userData);
}
/**
@@ -2838,6 +2853,8 @@
sb.append(" ago");
pw.println(sb);
}
+ pw.print(" Last logged in fingerprint: ");
+ pw.println(userInfo.lastLoggedInFingerprint);
pw.print(" Has profile owner: ");
pw.println(mIsUserManaged.get(userId));
pw.println(" Restrictions:");
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 1645366..574faa0 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2777,11 +2777,19 @@
int insets = mWindowManagerFuncs.getDockedDividerInsetsLw();
// If the divider is behind the navigation bar, don't animate.
- if (mNavigationBar != null
+ final Rect frame = win.getFrameLw();
+ final boolean behindNavBar = mNavigationBar != null
&& ((mNavigationBarOnBottom
- && win.getFrameLw().top + insets >= mNavigationBar.getFrameLw().top)
+ && frame.top + insets >= mNavigationBar.getFrameLw().top)
|| (!mNavigationBarOnBottom
- && win.getFrameLw().left + insets >= mNavigationBar.getFrameLw().left))) {
+ && frame.left + insets >= mNavigationBar.getFrameLw().left));
+ final boolean landscape = frame.height() > frame.width();
+ final boolean offscreenLandscape = landscape && (frame.right - insets <= 0
+ || frame.left + insets >= win.getDisplayFrameLw().right);
+ final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0
+ || frame.bottom + insets >= win.getDisplayFrameLw().bottom);
+ final boolean offscreen = offscreenLandscape || offscreenPortrait;
+ if (behindNavBar || offscreen) {
return 0;
}
if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
@@ -6291,8 +6299,7 @@
@Override
public boolean isNavBarForcedShownLw(WindowState windowState) {
- return mForceShowSystemBars
- && !windowState.getFrameLw().equals(windowState.getDisplayFrameLw());
+ return mForceShowSystemBars;
}
@Override
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 2c15818..98d44ac 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -21,6 +21,7 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.annotation.NonNull;
import android.app.Service;
import android.content.Context;
import android.graphics.Canvas;
@@ -122,6 +123,12 @@
}
}
+ public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
+ if (mDisplayMagnifier != null) {
+ mDisplayMagnifier.getMagnificationRegionsLocked(outMagnified, outAvailable);
+ }
+ }
+
public void onRectangleOnScreenRequestedLocked(Rect rectangle) {
if (mDisplayMagnifier != null) {
mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle);
@@ -392,6 +399,10 @@
return spec;
}
+ public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
+ mMagnifedViewport.getBoundsLocked(outMagnified, outAvailable);
+ }
+
public void destroyLocked() {
mMagnifedViewport.destroyWindow();
}
@@ -413,6 +424,7 @@
private final Matrix mTempMatrix = new Matrix();
private final Region mMagnifiedBounds = new Region();
+ private final Region mAvailableBounds = new Region();
private final Region mOldMagnifiedBounds = new Region();
private final Region mOldAvailableBounds = new Region();
@@ -450,6 +462,12 @@
recomputeBoundsLocked();
}
+ public void getBoundsLocked(@NonNull Region outMagnified,
+ @NonNull Region outAvailable) {
+ outMagnified.set(mMagnifiedBounds);
+ outAvailable.set(mAvailableBounds);
+ }
+
public void updateMagnificationSpecLocked(MagnificationSpec spec) {
if (spec != null) {
mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY);
@@ -469,14 +487,11 @@
final int screenWidth = mTempPoint.x;
final int screenHeight = mTempPoint.y;
- Region magnifiedBounds = mMagnifiedBounds;
- magnifiedBounds.set(0, 0, 0, 0);
-
- Region availableBounds = mTempRegion1;
- availableBounds.set(0, 0, screenWidth, screenHeight);
+ mMagnifiedBounds.set(0, 0, 0, 0);
+ mAvailableBounds.set(0, 0, screenWidth, screenHeight);
if (mCircularPath != null) {
- availableBounds.setPath(mCircularPath, availableBounds);
+ mAvailableBounds.setPath(mCircularPath, mAvailableBounds);
}
Region nonMagnifiedBounds = mTempRegion4;
@@ -505,8 +520,8 @@
matrix.mapRect(windowFrame);
windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
(int) windowFrame.right, (int) windowFrame.bottom);
- magnifiedBounds.op(windowBounds, Region.Op.UNION);
- magnifiedBounds.op(availableBounds, Region.Op.INTERSECT);
+ mMagnifiedBounds.op(windowBounds, Region.Op.UNION);
+ mMagnifiedBounds.op(mAvailableBounds, Region.Op.INTERSECT);
} else {
Region touchableRegion = mTempRegion3;
windowState.getTouchableRegion(touchableRegion);
@@ -518,12 +533,12 @@
windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
(int) windowFrame.right, (int) windowFrame.bottom);
nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
- windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE);
- availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
+ windowBounds.op(mMagnifiedBounds, Region.Op.DIFFERENCE);
+ mAvailableBounds.op(windowBounds, Region.Op.DIFFERENCE);
}
Region accountedBounds = mTempRegion2;
- accountedBounds.set(magnifiedBounds);
+ accountedBounds.set(mMagnifiedBounds);
accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);
@@ -539,15 +554,15 @@
visibleWindows.clear();
- magnifiedBounds.op(mDrawBorderInset, mDrawBorderInset,
+ mMagnifiedBounds.op(mDrawBorderInset, mDrawBorderInset,
screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset,
Region.Op.INTERSECT);
- final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(magnifiedBounds);
- final boolean availableChanged = !mOldAvailableBounds.equals(availableBounds);
+ final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(mMagnifiedBounds);
+ final boolean availableChanged = !mOldAvailableBounds.equals(mAvailableBounds);
if (magnifiedChanged || availableChanged) {
if (magnifiedChanged) {
- mWindow.setBounds(magnifiedBounds);
+ mWindow.setBounds(mMagnifiedBounds);
Rect dirtyRect = mTempRect1;
if (mFullRedrawNeeded) {
mFullRedrawNeeded = false;
@@ -557,23 +572,23 @@
mWindow.invalidate(dirtyRect);
} else {
Region dirtyRegion = mTempRegion3;
- dirtyRegion.set(magnifiedBounds);
+ dirtyRegion.set(mMagnifiedBounds);
dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION);
dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
dirtyRegion.getBounds(dirtyRect);
mWindow.invalidate(dirtyRect);
}
- mOldMagnifiedBounds.set(magnifiedBounds);
+ mOldMagnifiedBounds.set(mMagnifiedBounds);
}
if (availableChanged) {
- mOldAvailableBounds.set(availableBounds);
+ mOldAvailableBounds.set(mAvailableBounds);
}
final SomeArgs args = SomeArgs.obtain();
- args.arg1 = Region.obtain(magnifiedBounds);
- args.arg2 = Region.obtain(availableBounds);
+ args.arg1 = Region.obtain(mMagnifiedBounds);
+ args.arg2 = Region.obtain(mAvailableBounds);
mHandler.obtainMessage(
MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 15a2691..d684278 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -996,7 +996,14 @@
private Path createCurvedPath(float fromX, float toX, float fromY, float toY) {
final Path path = new Path();
path.moveTo(fromX, fromY);
- path.cubicTo(fromX, fromY, toX, 0.9f * fromY + 0.1f * toY, toX, toY);
+
+ if (fromY > toY) {
+ // If the object needs to go up, move it in horizontal direction first, then vertical.
+ path.cubicTo(fromX, fromY, toX, 0.9f * fromY + 0.1f * toY, toX, toY);
+ } else {
+ // If the object needs to go down, move it in vertical direction first, then horizontal.
+ path.cubicTo(fromX, fromY, fromX, 0.1f * fromY + 0.9f * toY, toX, toY);
+ }
return path;
}
@@ -1557,6 +1564,7 @@
int getAppStackClipMode() {
return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH
|| mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+ || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
? STACK_CLIP_NONE
: STACK_CLIP_AFTER_ANIM;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5212211..28379f4 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -429,6 +429,7 @@
}
if (getDockedStackVisibleForUserLocked() != null) {
mDividerControllerLocked.getTouchRegion(mTmpRect);
+ mTmpRegion.set(mTmpRect);
mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
}
if (mTapDetector != null) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 6741aba..68ea4df 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -41,6 +41,8 @@
import com.android.server.wm.DimLayer.DimLayerUser;
+import java.util.ArrayList;
+
/**
* Keeps information about the docked stack divider.
*/
@@ -87,7 +89,7 @@
private final DimLayer mDimLayer;
private boolean mMinimizedDock;
- private boolean mAnimating;
+ private boolean mAnimatingForMinimizedDockedStack;
private boolean mAnimationStarted;
private long mAnimationStartTime;
private float mAnimationStart;
@@ -96,7 +98,8 @@
private final Interpolator mMinimizedDockInterpolator;
private float mMaximizeMeetFraction;
private final Rect mTouchRegion = new Rect();
- private boolean mAdjustingForIme;
+ private boolean mAnimatingForIme;
+ private boolean mAdjustedForIme;
DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
mService = service;
@@ -174,12 +177,11 @@
return mLastVisibility;
}
- void setAdjustingForIme(boolean adjusting) {
- mAdjustingForIme = adjusting;
- }
-
- boolean isAdjustingForIme() {
- return mAdjustingForIme;
+ void setAdjustedForIme(boolean adjusted, boolean animate) {
+ if (mAdjustedForIme != adjusted) {
+ mAnimatingForIme = animate;
+ mAdjustedForIme = adjusted;
+ }
}
void positionDockedStackedDivider(Rect frame) {
@@ -342,6 +344,7 @@
}
mMinimizedDock = minimizedDock;
+ mAnimatingForIme = false;
if (minimizedDock) {
if (animate) {
startAdjustAnimation(0f, 1f);
@@ -358,7 +361,7 @@
}
private void startAdjustAnimation(float from, float to) {
- mAnimating = true;
+ mAnimatingForMinimizedDockedStack = true;
mAnimationStarted = false;
mAnimationStart = from;
mAnimationTarget = to;
@@ -380,10 +383,45 @@
}
public boolean animate(long now) {
- if (!mAnimating) {
+ if (mAnimatingForMinimizedDockedStack) {
+ return animateForMinimizedDockedStack(now);
+ } else if (mAnimatingForIme) {
+ return animateForIme();
+ } else {
return false;
}
+ }
+ private boolean animateForIme() {
+ boolean updated = false;
+ boolean animating = false;
+
+ final ArrayList<TaskStack> stacks = mDisplayContent.getStacks();
+ for (int i = stacks.size() - 1; i >= 0; --i) {
+ final TaskStack stack = stacks.get(i);
+ if (stack != null && stack.isAdjustedForIme()) {
+ updated |= stack.updateAdjustForIme();
+ animating |= stack.isAnimatingForIme();
+ }
+ }
+
+ if (updated) {
+ mService.mWindowPlacerLocked.performSurfacePlacement();
+ }
+
+ if (!animating) {
+ mAnimatingForIme = false;
+ for (int i = stacks.size() - 1; i >= 0; --i) {
+ final TaskStack stack = stacks.get(i);
+ if (stack != null) {
+ stack.clearImeGoingAway();
+ }
+ }
+ }
+ return animating;
+ }
+
+ private boolean animateForMinimizedDockedStack(long now) {
final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked();
if (!mAnimationStarted) {
mAnimationStarted = true;
@@ -406,7 +444,7 @@
}
}
if (t >= 1.0f) {
- mAnimating = false;
+ mAnimatingForMinimizedDockedStack = false;
return false;
} else {
return true;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4e8f19e..1f03c04 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -498,7 +498,15 @@
return;
}
- out.set(mBounds);
+ if (!mFullscreen) {
+ // When minimizing the docked stack when going home, we don't adjust the task bounds
+ // so we need to intersect the task bounds with the stack bounds here.
+ mStack.getBounds(mTmpRect);
+ mTmpRect.intersect(mBounds);
+ out.set(mTmpRect);
+ } else {
+ out.set(mBounds);
+ }
return;
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 8d67771..0bf7102 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -55,6 +55,11 @@
// If the stack should be resized to fullscreen.
private static final boolean FULLSCREEN = true;
+ // When we have a top-bottom split screen, we shift the bottom stack up to accommodate
+ // the IME window. The static flag below controls whether to run animation when the
+ // IME window goes away.
+ private static final boolean ANIMATE_IME_GOING_AWAY = false;
+
/** Unique identifier */
final int mStackId;
@@ -107,6 +112,7 @@
private final Rect mLastContentBounds = new Rect();
private final Rect mTmpAdjustedBounds = new Rect();
private boolean mAdjustedForIme;
+ private boolean mImeGoingAway;
private WindowState mImeWin;
private float mMinimizeAmount;
private final int mDockedStackMinimizeThickness;
@@ -796,19 +802,54 @@
void setAdjustedForIme(WindowState imeWin) {
mAdjustedForIme = true;
mImeWin = imeWin;
- if (updateAdjustedBounds()) {
- getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true);
+ mImeGoingAway = false;
+ }
+
+ boolean isAdjustedForIme() {
+ return mAdjustedForIme || mImeGoingAway;
+ }
+ void clearImeGoingAway() {
+ mImeGoingAway = false;
+ }
+
+ boolean isAnimatingForIme() {
+ return mImeWin != null && mImeWin.isAnimatingLw();
+ }
+
+ /**
+ * Update the stack's bounds (crop or position) according to the IME window's
+ * current position. When IME window is animated, the bottom stack is animated
+ * together to track the IME window's current position, and the top stack is
+ * cropped as necessary.
+ *
+ * @return true if a traversal should be performed after the adjustment.
+ */
+ boolean updateAdjustForIme() {
+ boolean stopped = false;
+ if (mImeGoingAway && (!ANIMATE_IME_GOING_AWAY || !isAnimatingForIme())) {
+ mImeWin = null;
+ mAdjustedForIme = false;
+ stopped = true;
}
+ // Make sure to run a traversal when the animation stops so that the stack
+ // is moved to its final position.
+ return updateAdjustedBounds() || stopped;
}
/**
* Resets the adjustment after it got adjusted for the IME.
+ * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
+ * animations; otherwise, set flag and animates the window away together
+ * with IME window.
*/
- void resetAdjustedForIme() {
- mAdjustedForIme = false;
- mImeWin = null;
- if (updateAdjustedBounds()) {
- getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true);
+ void resetAdjustedForIme(boolean adjustBoundsNow) {
+ if (adjustBoundsNow) {
+ mImeWin = null;
+ mAdjustedForIme = false;
+ mImeGoingAway = false;
+ updateAdjustedBounds();
+ } else {
+ mImeGoingAway |= mAdjustedForIme;
}
}
@@ -843,6 +884,12 @@
getDisplayContent().getContentRect(displayContentRect);
contentBounds.set(displayContentRect);
int imeTop = Math.max(imeWin.getDisplayFrameLw().top, contentBounds.top);
+
+ // if IME window is animating, get its actual vertical shown position (but no smaller than
+ // the final target vertical position)
+ if (imeWin.isAnimatingLw()) {
+ imeTop = Math.max(imeTop, imeWin.getShownPositionLw().y);
+ }
imeTop += imeWin.getGivenContentInsetsLw().top;
if (contentBounds.bottom > imeTop) {
contentBounds.bottom = imeTop;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5771d69..6d350b0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7380,8 +7380,9 @@
final WindowState imeWin = mInputMethodWindow;
final TaskStack focusedStack =
mCurrentFocus != null ? mCurrentFocus.getStack() : null;
+ final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID);
if (imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
- && isStackVisibleLocked(DOCKED_STACK_ID)
+ && dockVisible
&& focusedStack != null
&& focusedStack.getDockSide() == DOCKED_BOTTOM){
final ArrayList<TaskStack> stacks = displayContent.getStacks();
@@ -7391,12 +7392,14 @@
stack.setAdjustedForIme(imeWin);
}
}
+ displayContent.mDividerControllerLocked.setAdjustedForIme(true, true);
} else {
final ArrayList<TaskStack> stacks = displayContent.getStacks();
for (int i = stacks.size() - 1; i >= 0; --i) {
final TaskStack stack = stacks.get(i);
- stack.resetAdjustedForIme();
+ stack.resetAdjustedForIme(!dockVisible);
}
+ displayContent.mDividerControllerLocked.setAdjustedForIme(false, dockVisible);
}
}
@@ -10725,6 +10728,19 @@
}
@Override
+ public void getMagnificationRegions(@NonNull Region outMagnified,
+ @NonNull Region outAvailable) {
+ synchronized (mWindowMap) {
+ if (mAccessibilityController != null) {
+ mAccessibilityController.getMagnificationRegionsLocked(
+ outMagnified, outAvailable);
+ } else {
+ throw new IllegalStateException("Magnification callbacks not set!");
+ }
+ }
+ }
+
+ @Override
public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
synchronized (mWindowMap) {
WindowState windowState = mWindowMap.get(windowToken);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a302006..0866c03 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -799,38 +799,44 @@
mContentInsets.setEmpty();
mVisibleInsets.setEmpty();
} else {
+ // Using mContentInsets as a temp rect. It is safe because we're setting it below.
+ getDisplayContent().getLogicalDisplayRect(mContentInsets);
+ // Override right and/or bottom insets in case if the frame doesn't fit the screen in
+ // non-fullscreen mode.
+ boolean overrideRightInset = !fullscreenTask && mFrame.right > mContentInsets.right;
+ boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mContentInsets.bottom;
mContentInsets.set(mContentFrame.left - frame.left,
mContentFrame.top - frame.top,
- frame.right - mContentFrame.right,
- frame.bottom - mContentFrame.bottom);
+ overrideRightInset ? 0 : frame.right - mContentFrame.right,
+ overrideBottomInset ? 0 : frame.bottom - mContentFrame.bottom);
mVisibleInsets.set(mVisibleFrame.left - frame.left,
mVisibleFrame.top - frame.top,
- frame.right - mVisibleFrame.right,
- frame.bottom - mVisibleFrame.bottom);
+ overrideRightInset ? 0 : frame.right - mVisibleFrame.right,
+ overrideBottomInset ? 0 : frame.bottom - mVisibleFrame.bottom);
mStableInsets.set(Math.max(mStableFrame.left - frame.left, 0),
Math.max(mStableFrame.top - frame.top, 0),
- Math.max(frame.right - mStableFrame.right, 0),
- Math.max(frame.bottom - mStableFrame.bottom, 0));
+ overrideRightInset ? 0 : Math.max(frame.right - mStableFrame.right, 0),
+ overrideBottomInset ? 0 : Math.max(frame.bottom - mStableFrame.bottom, 0));
}
if (!mInsetFrame.isEmpty()) {
mContentFrame.set(mFrame);
mContentFrame.top += mContentInsets.top;
- mContentFrame.bottom += mContentInsets.bottom;
+ mContentFrame.bottom -= mContentInsets.bottom;
mContentFrame.left += mContentInsets.left;
- mContentFrame.right += mContentInsets.right;
+ mContentFrame.right -= mContentInsets.right;
mVisibleFrame.set(mFrame);
mVisibleFrame.top += mVisibleInsets.top;
- mVisibleFrame.bottom += mVisibleInsets.bottom;
+ mVisibleFrame.bottom -= mVisibleInsets.bottom;
mVisibleFrame.left += mVisibleInsets.left;
- mVisibleFrame.right += mVisibleInsets.right;
+ mVisibleFrame.right -= mVisibleInsets.right;
mStableFrame.set(mFrame);
mStableFrame.top += mStableInsets.top;
- mStableFrame.bottom += mStableInsets.bottom;
+ mStableFrame.bottom -= mStableInsets.bottom;
mStableFrame.left += mStableInsets.left;
- mStableFrame.right += mStableInsets.right;
+ mStableFrame.right -= mStableInsets.right;
}
mCompatFrame.set(mFrame);
if (mEnforceSizeCompat) {
@@ -864,7 +870,7 @@
+ "): frame=" + mFrame.toShortString()
+ " ci=" + mContentInsets.toShortString()
+ " vi=" + mVisibleInsets.toShortString()
- + " vi=" + mStableInsets.toShortString()
+ + " si=" + mStableInsets.toShortString()
+ " of=" + mOutsets.toShortString());
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 3b0081d..3e5ddbc 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -693,16 +693,14 @@
// currently animating... let's do something.
final int left = w.mFrame.left;
final int top = w.mFrame.top;
- final boolean adjustedForMinimizedDockedStack = w.getTask() != null &&
- w.getTask().mStack.isAdjustedForMinimizedDockedStack();
+ final boolean adjustedForMinimizedDockOrIme = task != null
+ && (task.mStack.isAdjustedForMinimizedDockedStack()
+ || task.mStack.isAdjustedForIme());
if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
- && !w.isDragResizing() && !adjustedForMinimizedDockedStack
+ && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
&& (task == null || !w.getTask().mStack.getFreezeMovementAnimations())
&& !w.mWinAnimator.mLastHidden) {
winAnimator.setMoveAnimation(left, top);
- } else if (w.mAttrs.type == TYPE_DOCK_DIVIDER &&
- displayContent.getDockedDividerController().isAdjustingForIme()) {
- winAnimator.setMoveAnimation(left, top);
}
//TODO (multidisplay): Accessibility supported only for the default display.
@@ -819,8 +817,6 @@
mService.updateResizingWindows(w);
}
- displayContent.getDockedDividerController().setAdjustingForIme(false);
-
mService.mDisplayManagerInternal.setDisplayProperties(displayId,
mDisplayHasContent,
mPreferredRefreshRate,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7da0a9a..b2cd69d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4868,10 +4868,24 @@
// we start using it for different purposes.
ensureCallerPackage(callerPackage);
+ final ApplicationInfo ai;
+ try {
+ ai = mIPackageManager.getApplicationInfo(callerPackage, 0, userHandle);
+ } catch (RemoteException e) {
+ throw new SecurityException(e);
+ }
+
+ boolean legacyApp = false;
+ if (ai.targetSdkVersion <= Build.VERSION_CODES.M) {
+ legacyApp = true;
+ } else if ("com.google.android.apps.enterprise.dmagent".equals(ai.packageName)
+ && ai.versionCode == 697) {
+ // TODO: STOPSHIP remove this (revert ag/895987) once a new prebuilt is dropped
+ legacyApp = true;
+ }
+
final int rawStatus = getEncryptionStatus();
- if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER)
- && (callerPackage != null)
- && (getTargetSdk(callerPackage, userHandle) <= VERSION_CODES.M)) {
+ if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER) && legacyApp) {
return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
}
return rawStatus;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5975405..14efc27 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -153,6 +153,8 @@
"com.android.server.MountService$Lifecycle";
private static final String SEARCH_MANAGER_SERVICE_CLASS =
"com.android.server.search.SearchManagerService$Lifecycle";
+ private static final String THERMAL_OBSERVER_CLASS =
+ "com.google.android.clockwork.ThermalObserver";
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
@@ -959,7 +961,7 @@
if (context.getPackageManager().hasSystemFeature
(PackageManager.FEATURE_WATCH)) {
- mSystemServiceManager.startService(ThermalObserver.class);
+ mSystemServiceManager.startService(THERMAL_OBSERVER_CLASS);
}
}
diff --git a/services/net/java/android/net/apf/ApfCapabilities.java b/services/net/java/android/net/apf/ApfCapabilities.java
index f169411..0ec50c4 100644
--- a/services/net/java/android/net/apf/ApfCapabilities.java
+++ b/services/net/java/android/net/apf/ApfCapabilities.java
@@ -43,4 +43,9 @@
this.maximumApfProgramSize = maximumApfProgramSize;
this.apfPacketFormat = apfPacketFormat;
}
-}
\ No newline at end of file
+
+ public String toString() {
+ return String.format("%s{version: %d, maxSize: %d format: %d}", getClass().getSimpleName(),
+ apfVersionSupported, maximumApfProgramSize, apfPacketFormat);
+ }
+}
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 66c7909..c25fae3 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -45,6 +45,7 @@
import com.android.internal.util.StateMachine;
import com.android.server.net.NetlinkTracker;
+import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -211,6 +212,8 @@
}
}
+ public static final String DUMP_ARG = "ipmanager";
+
private static final int CMD_STOP = 1;
private static final int CMD_START = 2;
private static final int CMD_CONFIRM = 3;
@@ -393,17 +396,18 @@
}
}
- public void dumpApf(PrintWriter writer) {
- writer.println("--------------------------------------------------------------------");
- writer.println("APF dump:");
+ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
+ pw.println("APF dump:");
+ pw.increaseIndent();
// Thread-unsafe access to mApfFilter but just used for debugging.
ApfFilter apfFilter = mApfFilter;
if (apfFilter != null) {
- apfFilter.dump(new IndentingPrintWriter(writer, " "));
+ apfFilter.dump(pw);
} else {
- writer.println("No apf support");
+ pw.println("No apf support");
}
- writer.println("--------------------------------------------------------------------");
+ pw.decreaseIndent();
}
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 8cfc4a3..985917b 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -129,7 +129,7 @@
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -151,7 +151,7 @@
return null;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -176,7 +176,7 @@
return null;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -197,7 +197,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -222,7 +222,7 @@
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -247,7 +247,7 @@
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -269,7 +269,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -303,7 +303,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -325,7 +325,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -347,7 +347,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -373,7 +373,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -394,7 +394,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -415,7 +415,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -436,7 +436,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -457,7 +457,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -481,7 +481,7 @@
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -503,7 +503,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -525,7 +525,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -547,7 +547,7 @@
if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
- userState = getOrCreateUserStateLocked(resolvedUserId);
+ userState = getOrCreateUserStateLocked(resolvedUserId, false);
}
final long identity = Binder.clearCallingIdentity();
try {
@@ -661,7 +661,7 @@
@Override
public void onPackageModified(String packageName) {
if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false);
synchronized (mLock) {
if (hadPrintService(userState, packageName)
@@ -676,7 +676,7 @@
@Override
public void onPackageRemoved(String packageName, int uid) {
if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false);
synchronized (mLock) {
if (hadPrintService(userState, packageName)) {
@@ -695,7 +695,8 @@
// A background user/profile's print jobs are running but there is
// no UI shown. Hence, if the packages of such a user change we need
// to handle it as the change may affect ongoing print jobs.
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId(),
+ false);
boolean stoppedSomePackages = false;
List<PrintServiceInfo> enabledServices = userState
@@ -730,7 +731,8 @@
if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
synchronized (mLock) {
if (hasPrintService(packageName)) {
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId(),
+ false);
userState.updateIfNeededLocked();
}
}
@@ -742,7 +744,7 @@
UserHandle.ALL, true);
}
- private UserState getOrCreateUserStateLocked(int userId) {
+ private UserState getOrCreateUserStateLocked(int userId, boolean lowPriority) {
if (!mUserManager.isUserUnlocked(userId)) {
throw new IllegalStateException(
"User " + userId + " must be unlocked for printing to be available");
@@ -750,9 +752,14 @@
UserState userState = mUserStates.get(userId);
if (userState == null) {
- userState = new UserState(mContext, userId, mLock);
+ userState = new UserState(mContext, userId, mLock, lowPriority);
mUserStates.put(userId, userState);
}
+
+ if (!lowPriority) {
+ userState.increasePriority();
+ }
+
return userState;
}
@@ -764,7 +771,7 @@
public void run() {
UserState userState;
synchronized (mLock) {
- userState = getOrCreateUserStateLocked(userId);
+ userState = getOrCreateUserStateLocked(userId, true);
userState.updateIfNeededLocked();
}
// This is the first time we switch to this user after boot, so
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index be822c8..07cc9c0 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -98,6 +98,8 @@
private final PrintSpoolerCallbacks mCallbacks;
+ private boolean mIsLowPriority;
+
private IPrintSpooler mRemoteInstance;
private boolean mDestroyed;
@@ -110,17 +112,42 @@
public void onPrintJobStateChanged(PrintJobInfo printJob);
}
- public RemotePrintSpooler(Context context, int userId,
+ public RemotePrintSpooler(Context context, int userId, boolean lowPriority,
PrintSpoolerCallbacks callbacks) {
mContext = context;
mUserHandle = new UserHandle(userId);
mCallbacks = callbacks;
+ mIsLowPriority = lowPriority;
mClient = new PrintSpoolerClient(this);
mIntent = new Intent();
mIntent.setComponent(new ComponentName(PrintManager.PRINT_SPOOLER_PACKAGE_NAME,
PrintManager.PRINT_SPOOLER_PACKAGE_NAME + ".model.PrintSpoolerService"));
}
+ public void increasePriority() {
+ if (mIsLowPriority) {
+ mIsLowPriority = false;
+
+ synchronized (mLock) {
+ throwIfDestroyedLocked();
+
+ while (!mCanUnbind) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ Slog.e(LOG_TAG, "Interrupted while waiting for operation to complete");
+ }
+ }
+
+ if (DEBUG) {
+ Slog.i(LOG_TAG, "Unbinding as previous binding was low priority");
+ }
+
+ unbindLocked();
+ }
+ }
+ }
+
public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state,
int appId) {
throwIfCalledOnMainThread();
@@ -579,11 +606,18 @@
return;
}
if (DEBUG) {
- Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
+ Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " +
+ (mIsLowPriority ? "low priority" : ""));
}
- mContext.bindServiceAsUser(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, mUserHandle);
+ int flags;
+ if (mIsLowPriority) {
+ flags = Context.BIND_AUTO_CREATE;
+ } else {
+ flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+ }
+
+ mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle);
final long startMillis = SystemClock.uptimeMillis();
while (true) {
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 8ab1878..263dead 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -126,11 +126,11 @@
private boolean mDestroyed;
- public UserState(Context context, int userId, Object lock) {
+ public UserState(Context context, int userId, Object lock, boolean lowPriority) {
mContext = context;
mUserId = userId;
mLock = lock;
- mSpooler = new RemotePrintSpooler(context, userId, this);
+ mSpooler = new RemotePrintSpooler(context, userId, lowPriority, this);
mHandler = new UserStateHandler(context.getMainLooper());
synchronized (mLock) {
@@ -145,6 +145,10 @@
}
}
+ public void increasePriority() {
+ mSpooler.increasePriority();
+ }
+
@Override
public void onPrintJobQueued(PrintJobInfo printJob) {
final RemotePrintService service;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
index 28966ca..61249ae 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
@@ -20,11 +20,14 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.BroadcastReceiver;
@@ -32,19 +35,23 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
import android.content.pm.ILauncherApps;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.pm.ShortcutServiceInternal;
+import android.content.pm.Signature;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.FileUtils;
@@ -68,6 +75,7 @@
import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
import com.android.server.pm.ShortcutService.ConfigConstants;
import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
+import com.android.server.pm.ShortcutUser.PackageWithUser;
import libcore.io.IoUtils;
@@ -103,7 +111,6 @@
* TODO: separate, detailed tests for ShortcutInfo (CTS?) *
*
* TODO: Cross-user test (do in CTS?)
- *
*/
@SmallTest
public class ShortcutManagerTest extends InstrumentationTestCase {
@@ -115,7 +122,8 @@
*/
private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true
- private class BaseContext extends MockContext {
+ // public for mockito
+ public class BaseContext extends MockContext {
@Override
public Object getSystemService(String name) {
switch (name) {
@@ -149,7 +157,7 @@
}
/** Context used in the client side */
- private class ClientContext extends BaseContext {
+ public class ClientContext extends BaseContext {
@Override
public String getPackageName() {
return mInjectedClientPackage;
@@ -157,7 +165,7 @@
}
/** Context used in the service side */
- private final class ServiceContext extends BaseContext {
+ public class ServiceContext extends BaseContext {
long injectClearCallingIdentity() {
final int prevCallingUid = mInjectedCallingUid;
mInjectedCallingUid = Process.SYSTEM_UID;
@@ -167,6 +175,11 @@
void injectRestoreCallingIdentity(long token) {
mInjectedCallingUid = (int) token;
}
+
+ @Override
+ public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
+ UserHandle userId) {
+ }
}
/** ShortcutService with injection override methods. */
@@ -217,8 +230,7 @@
@Override
int injectGetPackageUid(String packageName, int userId) {
- Integer uid = mInjectedPackageUidMap.get(packageName);
- return UserHandle.getUid(getCallingUserId(), (uid != null ? uid : 0));
+ return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
}
@Override
@@ -253,6 +265,18 @@
}
@Override
+ PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
+ boolean getSignatures) {
+ return getInjectedPackageInfo(packageName, userId, getSignatures);
+ }
+
+ @Override
+ ApplicationInfo injectApplicationInfo(String packageName, @UserIdInt int userId) {
+ PackageInfo pi = injectPackageInfo(packageName, userId, /* getSignatures= */ false);
+ return pi != null ? pi.applicationInfo : null;
+ }
+
+ @Override
void postToHandler(Runnable r) {
final long token = mContext.injectClearCallingIdentity();
super.postToHandler(r);
@@ -296,9 +320,17 @@
if (getCallingUserId() == userToCheck.getIdentifier()) {
return; // okay
}
+ if (getCallingUserId() == USER_0 && userToCheck.getIdentifier() == USER_P0) {
+ return; // profile, okay.
+ }
+ if (getCallingUserId() == USER_P0 && userToCheck.getIdentifier() == USER_0) {
+ return; // profile, okay.
+ }
- assertEquals(Process.SYSTEM_UID, mInjectedCallingUid);
- // SKIP
+ if (mInjectedCallingUid != Process.SYSTEM_UID) {
+ throw new SecurityException("To access other users, you need to be SYSTEM" +
+ ", but current UID=" + mInjectedCallingUid);
+ }
}
@Override
@@ -319,6 +351,11 @@
r.run();
mContext.injectRestoreCallingIdentity(token);
}
+
+ @Override
+ int injectBinderCallingUid() {
+ return mInjectedCallingUid;
+ }
}
private class LauncherAppsTestable extends LauncherApps {
@@ -355,7 +392,9 @@
private int mInjectedCallingUid;
private String mInjectedClientPackage;
- private Map<String, Integer> mInjectedPackageUidMap;
+ private Map<String, PackageInfo> mInjectedPackages;
+
+ private ArrayList<PackageWithUser> mUninstalledPackages;
private PackageManager mMockPackageManager;
private PackageManagerInternal mMockPackageManagerInternal;
@@ -379,6 +418,13 @@
private static final int USER_0 = UserHandle.USER_SYSTEM;
private static final int USER_10 = 10;
private static final int USER_11 = 11;
+ private static final int USER_P0 = 20; // profile of user 0
+
+ private static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
+ private static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
+ private static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
+ private static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
+
private static final long START_TIME = 1440000000101L;
@@ -396,7 +442,7 @@
protected void setUp() throws Exception {
super.setUp();
- mServiceContext = new ServiceContext();
+ mServiceContext = spy(new ServiceContext());
mClientContext = new ClientContext();
mMockPackageManager = mock(PackageManager.class);
@@ -407,12 +453,14 @@
mInjectedCurrentTimeLillis = START_TIME;
- mInjectedPackageUidMap = new HashMap<>();
- mInjectedPackageUidMap.put(CALLING_PACKAGE_1, CALLING_UID_1);
- mInjectedPackageUidMap.put(CALLING_PACKAGE_2, CALLING_UID_2);
- mInjectedPackageUidMap.put(CALLING_PACKAGE_3, CALLING_UID_3);
- mInjectedPackageUidMap.put(LAUNCHER_1, LAUNCHER_UID_1);
- mInjectedPackageUidMap.put(LAUNCHER_2, LAUNCHER_UID_2);
+ mInjectedPackages = new HashMap<>();;
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1);
+ addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 2);
+ addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 3);
+ addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4);
+ addPackage(LAUNCHER_2, LAUNCHER_UID_2, 5);
+
+ mUninstalledPackages = new ArrayList<>();
mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
@@ -448,12 +496,70 @@
mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
}
+ private void addPackage(String packageName, int uid, int version) {
+ addPackage(packageName, uid, version, packageName);
+ }
+
+ private <T> List<T> list(T... array) {
+ return Arrays.asList(array);
+ }
+
+ private Signature[] genSignatures(String... signatures) {
+ final Signature[] sigs = new Signature[signatures.length];
+ for (int i = 0; i < signatures.length; i++){
+ sigs[i] = new Signature(signatures[i].getBytes());
+ }
+ return sigs;
+ }
+
+ private PackageInfo genPackage(String packageName, int uid, int version, String... signatures) {
+ final PackageInfo pi = new PackageInfo();
+ pi.packageName = packageName;
+ pi.applicationInfo = new ApplicationInfo();
+ pi.applicationInfo.uid = uid;
+ pi.applicationInfo.flags = ApplicationInfo.FLAG_INSTALLED
+ | ApplicationInfo.FLAG_ALLOW_BACKUP;
+ pi.versionCode = version;
+ pi.signatures = genSignatures(signatures);
+
+ return pi;
+ }
+
+ private void addPackage(String packageName, int uid, int version, String... signatures) {
+ mInjectedPackages.put(packageName, genPackage(packageName, uid, version, signatures));
+ }
+
+ private void uninstallPackage(int userId, String packageName) {
+ mUninstalledPackages.add(PackageWithUser.of(userId, packageName));
+ }
+
+ PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
+ boolean getSignatures) {
+ final PackageInfo pi = mInjectedPackages.get(packageName);
+ if (pi == null) return null;
+
+ final PackageInfo ret = new PackageInfo();
+ ret.packageName = pi.packageName;
+ ret.versionCode = pi.versionCode;
+ ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
+ ret.applicationInfo.uid = UserHandle.getUid(userId, pi.applicationInfo.uid);
+ if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
+ ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+ }
+
+ if (getSignatures) {
+ ret.signatures = pi.signatures;
+ }
+
+ return ret;
+ }
+
/** Replace the current calling package */
private void setCaller(String packageName, int userId) {
mInjectedClientPackage = packageName;
- mInjectedCallingUid = UserHandle.getUid(userId,
- Preconditions.checkNotNull(mInjectedPackageUidMap.get(packageName),
- "Unknown package"));
+ mInjectedCallingUid =
+ Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false),
+ "Unknown package").applicationInfo.uid;
}
private void setCaller(String packageName) {
@@ -466,13 +572,13 @@
private void runWithCaller(String packageName, int userId, Runnable r) {
final String previousPackage = mInjectedClientPackage;
- final int previousUid = mInjectedCallingUid;
+ final int previousUserId = UserHandle.getUserId(mInjectedCallingUid);
setCaller(packageName, userId);
r.run();
- setCaller(previousPackage, previousUid);
+ setCaller(previousPackage, previousUserId);
}
private int getCallingUserId() {
@@ -692,7 +798,7 @@
private List<ShortcutInfo> assertShortcutIds(@NonNull List<ShortcutInfo> actualShortcuts,
String... expectedIds) {
assertEquals(expectedIds.length, actualShortcuts.size());
- final HashSet<String> expected = new HashSet<>(Arrays.asList(expectedIds));
+ final HashSet<String> expected = new HashSet<>(list(expectedIds));
final HashSet<String> actual = new HashSet<>();
for (ShortcutInfo s : actualShortcuts) {
actual.add(s.getId());
@@ -823,6 +929,21 @@
return actualShortcuts;
}
+ private void assertDynamicOnly(ShortcutInfo si) {
+ assertTrue(si.isDynamic());
+ assertFalse(si.isPinned());
+ }
+
+ private void assertPinnedOnly(ShortcutInfo si) {
+ assertFalse(si.isDynamic());
+ assertTrue(si.isPinned());
+ }
+
+ private void assertDynamicAndPinned(ShortcutInfo si) {
+ assertTrue(si.isDynamic());
+ assertTrue(si.isPinned());
+ }
+
private void assertBitmapSize(int expectedWidth, int expectedHeight, @NonNull Bitmap bitmap) {
assertEquals("width", expectedWidth, bitmap.getWidth());
assertEquals("height", expectedHeight, bitmap.getHeight());
@@ -852,6 +973,18 @@
assertTrue(b == null || b.size() == 0);
}
+ private void assertShortcutPackageInfo(String packageName, int userId, int expectedVersion) {
+ ShortcutPackageInfo spi = mService.getPackageInfoForTest(packageName, userId);
+ assertNotNull(spi);
+ assertEquals(expectedVersion, spi.getVersionCode());
+
+ assertTrue(spi.canRestoreTo(genPackage(packageName, /*uid*/ 0, 9999999, packageName)));
+ }
+
+ private void assertNoShortcutPackageInfo(String packageName, int userId) {
+ assertNull(mService.getPackageInfoForTest(packageName, userId));
+ }
+
private ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) {
return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
}
@@ -864,6 +997,39 @@
assertTrue(getPackageShortcut(packageName, shortcutId, userId) == null);
}
+ private Intent launchShortcutAndGetIntent(
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ reset(mServiceContext);
+ assertTrue(mLauncherApps.startShortcut(packageName, shortcutId, null, null,
+ UserHandle.of(userId)));
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mServiceContext).startActivityAsUser(
+ intentCaptor.capture(),
+ any(Bundle.class),
+ eq(UserHandle.of(userId)));
+ return intentCaptor.getValue();
+ }
+
+ private void assertShortcutLaunchable(@NonNull String packageName, @NonNull String shortcutId,
+ int userId) {
+ assertNotNull(launchShortcutAndGetIntent(packageName, shortcutId, userId));
+ }
+
+ private void assertShortcutNotLaunchable(@NonNull String packageName,
+ @NonNull String shortcutId, int userId) {
+ try {
+ final boolean ok = mLauncherApps.startShortcut(packageName, shortcutId, null, null,
+ UserHandle.of(userId));
+ if (!ok) {
+ return; // didn't launch, okay.
+ }
+ fail();
+ } catch (SecurityException expected) {
+ // security exception is okay too.
+ }
+ }
+
private ShortcutInfo getPackageShortcut(String packageName, String shortcutId) {
return getPackageShortcut(packageName, shortcutId, getCallingUserId());
}
@@ -886,6 +1052,22 @@
return getLauncherShortcuts(launcher, userId, ShortcutQuery.FLAG_GET_PINNED);
}
+
+ private Intent genPackageDeleteIntent(String pakcageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+ i.setData(Uri.parse("package:" + pakcageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ return i;
+ }
+
+ private Intent genPackageUpdateIntent(String pakcageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
+ i.setData(Uri.parse("package:" + pakcageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ i.putExtra(Intent.EXTRA_REPLACING, true);
+ return i;
+ }
+
/**
* Wrap a set in an ArraySet just to get a better toString.
*/
@@ -1017,6 +1199,8 @@
}
public void testSetDynamicShortcuts() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -1039,21 +1223,26 @@
/* weight */ 12);
final ShortcutInfo si3 = makeShortcut("shortcut3");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
assertShortcutIds(assertAllNotKeyFieldsOnly(
mManager.getDynamicShortcuts()),
"shortcut1", "shortcut2");
assertEquals(2, mManager.getRemainingCallCount());
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_0);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_1, USER_10);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_10);
+
// TODO: Check fields
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertShortcutIds(assertAllNotKeyFieldsOnly(
mManager.getDynamicShortcuts()),
"shortcut1");
assertEquals(1, mManager.getRemainingCallCount());
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList()));
+ assertTrue(mManager.setDynamicShortcuts(list()));
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getRemainingCallCount());
@@ -1064,20 +1253,31 @@
dumpsysOnLogcat();
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2, si3)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2, si3)));
assertEquals(2, mManager.getDynamicShortcuts().size());
// TODO Check max number
+
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
+
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_0);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_1, USER_10);
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_10, 2);
+ });
}
public void testAddDynamicShortcuts() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+
final ShortcutInfo si1 = makeShortcut("shortcut1");
final ShortcutInfo si2 = makeShortcut("shortcut2");
final ShortcutInfo si3 = makeShortcut("shortcut3");
assertEquals(3, mManager.getRemainingCallCount());
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
assertShortcutIds(assertAllNotKeyFieldsOnly(
mManager.getDynamicShortcuts()),
@@ -1099,6 +1299,11 @@
// TODO Check max number
// TODO Check fields.
+
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_10, 2);
+ });
}
public void testDeleteDynamicShortcut() {
@@ -1106,7 +1311,7 @@
final ShortcutInfo si2 = makeShortcut("shortcut2");
final ShortcutInfo si3 = makeShortcut("shortcut3");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
assertShortcutIds(assertAllNotKeyFieldsOnly(
mManager.getDynamicShortcuts()),
"shortcut1", "shortcut2", "shortcut3");
@@ -1148,7 +1353,7 @@
final ShortcutInfo si2 = makeShortcut("shortcut2");
final ShortcutInfo si3 = makeShortcut("shortcut3");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
assertShortcutIds(assertAllNotKeyFieldsOnly(
mManager.getDynamicShortcuts()),
"shortcut1", "shortcut2", "shortcut3");
@@ -1165,7 +1370,7 @@
assertEquals(0, mManager.getDynamicShortcuts().size());
// This should still work.
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
assertEquals(3, mManager.getDynamicShortcuts().size());
// Still 1 call left
@@ -1177,62 +1382,62 @@
public void testThrottling() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(1, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
// Reached the max
mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
// Still throttled
mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
// Now it should work.
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1))); // fail
+ assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail
assertEquals(2, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(1, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
// 4 days later...
mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(1, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
@@ -1242,7 +1447,7 @@
assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
}
@@ -1250,7 +1455,7 @@
public void testThrottling_rewind() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
@@ -1269,7 +1474,7 @@
mInjectedCurrentTimeLillis = START_TIME - 100000;
assertEquals(3, mManager.getRemainingCallCount());
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
// Forward again, should be reset now.
@@ -1280,21 +1485,21 @@
public void testThrottling_perPackage() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(2, mManager.getRemainingCallCount());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(1, mManager.getRemainingCallCount());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
// Reached the max
mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
// Try from a different caller.
mInjectedClientPackage = CALLING_PACKAGE_2;
@@ -1305,11 +1510,11 @@
assertEquals(3, mManager.getRemainingCallCount());
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
assertEquals(2, mManager.getRemainingCallCount());
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
assertEquals(1, mManager.getRemainingCallCount());
// Back to the original caller, still throttled.
@@ -1318,37 +1523,37 @@
mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
assertEquals(0, mManager.getRemainingCallCount());
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
assertEquals(0, mManager.getRemainingCallCount());
// Now it should work.
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL;
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
mInjectedClientPackage = CALLING_PACKAGE_2;
mInjectedCallingUid = CALLING_UID_2;
assertEquals(3, mManager.getRemainingCallCount());
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2)));
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2)));
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si2)));
- assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertFalse(mManager.setDynamicShortcuts(list(si2)));
}
public void testIcons() {
@@ -1365,7 +1570,7 @@
// Set from package 1
setCaller(CALLING_PACKAGE_1);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("res32x32", res32x32),
makeShortcutWithIcon("res64x64", res64x64),
makeShortcutWithIcon("bmp32x32", bmp32x32),
@@ -1385,7 +1590,7 @@
// Call from another caller with the same ID, just to make sure storage is per-package.
setCaller(CALLING_PACKAGE_2);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("res32x32", res512x512),
makeShortcutWithIcon("res64x64", res512x512),
makeShortcutWithIcon("none", res512x512)
@@ -1406,23 +1611,23 @@
// Check hasIconResource()/hasIconFile().
assertShortcutIds(assertAllHaveIconResId(mLauncherApps.getShortcutInfo(
- CALLING_PACKAGE_1, Arrays.asList("res32x32"),
+ CALLING_PACKAGE_1, list("res32x32"),
getCallingUser())), "res32x32");
assertShortcutIds(assertAllHaveIconResId(mLauncherApps.getShortcutInfo(
- CALLING_PACKAGE_1, Arrays.asList("res64x64"), getCallingUser())),
+ CALLING_PACKAGE_1, list("res64x64"), getCallingUser())),
"res64x64");
assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo(
- CALLING_PACKAGE_1, Arrays.asList("bmp32x32"), getCallingUser())),
+ CALLING_PACKAGE_1, list("bmp32x32"), getCallingUser())),
"bmp32x32");
assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo(
- CALLING_PACKAGE_1, Arrays.asList("bmp64x64"), getCallingUser())),
+ CALLING_PACKAGE_1, list("bmp64x64"), getCallingUser())),
"bmp64x64");
assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo(
- CALLING_PACKAGE_1, Arrays.asList("bmp512x512"), getCallingUser())),
+ CALLING_PACKAGE_1, list("bmp512x512"), getCallingUser())),
"bmp512x512");
// Check
@@ -1517,7 +1722,7 @@
final File p11_1_3 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
// Make sure their paths are all unique
- assertAllUnique(Arrays.asList(
+ assertAllUnique(list(
p10_1_1,
p10_1_2,
p10_1_3,
@@ -1546,7 +1751,7 @@
assertEquals(p11_1_1.getParent(), p11_1_3.getParent());
// Check the parents are still unique.
- assertAllUnique(Arrays.asList(
+ assertAllUnique(list(
p10_1_1.getParent(),
p10_2_1.getParent(),
p11_1_1.getParent()
@@ -1571,7 +1776,7 @@
public void testUpdateShortcuts() {
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
makeShortcut("s3"),
@@ -1580,7 +1785,7 @@
)));
});
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
makeShortcut("s3"),
@@ -1589,9 +1794,9 @@
)));
});
runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s2", "s3"),
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"),
getCallingUser());
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s4", "s5"),
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s4", "s5"),
getCallingUser());
});
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
@@ -1631,7 +1836,7 @@
.setTitle("new title")
.build();
- mManager.updateShortcuts(Arrays.asList(s2, s4));
+ mManager.updateShortcuts(list(s2, s4));
});
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
ShortcutInfo s2 = makeShortcutBuilder()
@@ -1645,7 +1850,7 @@
.setIntent(new Intent(Intent.ACTION_ALL_APPS))
.build();
- mManager.updateShortcuts(Arrays.asList(s2, s4));
+ mManager.updateShortcuts(list(s2, s4));
});
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
@@ -1691,6 +1896,15 @@
// TODO Check with other fields too.
// TODO Check bitmap removal too.
+
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_11);
+
+ mManager.updateShortcuts(list());
+
+ // Even an empty update call will populate the package info.
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_11, 2);
+ });
}
// TODO: updateShortcuts()
@@ -1717,17 +1931,17 @@
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 5000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 1000);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s1_1, s1_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
setCaller(CALLING_PACKAGE_2);
final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s2_2, s2_3, s2_4)));
+ assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
setCaller(CALLING_PACKAGE_3);
final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s3", 5000);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s3_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
setCaller(LAUNCHER_1);
@@ -1765,7 +1979,7 @@
// Pin some shortcuts.
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- Arrays.asList("s3", "s4"), getCallingUser());
+ list("s3", "s4"), getCallingUser());
// Pinned ones only
assertAllPinned(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
@@ -1808,7 +2022,7 @@
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
/* weight */ 12);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s1_1, s1_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
dumpsysOnLogcat();
setCaller(CALLING_PACKAGE_2);
@@ -1820,14 +2034,14 @@
makeIntent(Intent.ACTION_ANSWER, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
/* weight */ 10);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s2_1)));
+ assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
dumpsysOnLogcat();
// Pin some.
setCaller(LAUNCHER_1);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- Arrays.asList("s2"), getCallingUser());
+ list("s2"), getCallingUser());
dumpsysOnLogcat();
@@ -1846,19 +2060,19 @@
list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
- Arrays.asList("s2", "s1", "s3", null), getCallingUser())))),
+ list("s2", "s1", "s3", null), getCallingUser())))),
"s1", "s2");
assertEquals("Title 1", findById(list, "s1").getTitle());
assertEquals("Title 2", findById(list, "s2").getTitle());
assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
- Arrays.asList("s3"), getCallingUser())))
+ list("s3"), getCallingUser())))
/* none */);
list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
mLauncherApps.getShortcutInfo(CALLING_PACKAGE_2,
- Arrays.asList("s1", "s2", "s3"), getCallingUser()))),
+ list("s1", "s2", "s3"), getCallingUser()))),
"s1");
assertEquals("ABC", findById(list, "s1").getTitle());
}
@@ -1869,31 +2083,38 @@
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s1_1, s1_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
});
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s2_2, s2_3, s2_4)));
+ assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
});
runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s2", 1000);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s3_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
});
// Pin some.
runWithCaller(LAUNCHER_1, USER_0, () -> {
+ assertNoShortcutPackageInfo(LAUNCHER_1, USER_0);
+
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- Arrays.asList("s2", "s3"), getCallingUser());
+ list("s2", "s3"), getCallingUser());
+
+ assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+ assertNoShortcutPackageInfo(LAUNCHER_1, USER_10);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- Arrays.asList("s3", "s4", "s5"), getCallingUser());
+ list("s3", "s4", "s5"), getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_3,
- Arrays.asList("s3"), getCallingUser()); // Note ID doesn't exist
+ list("s3"), getCallingUser()); // Note ID doesn't exist
});
// Delete some.
@@ -1938,24 +2159,32 @@
public void testPinShortcutAndGetPinnedShortcuts_multi() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
dumpsysOnLogcat();
+ assertNoShortcutPackageInfo(LAUNCHER_1, USER_0);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+ assertNoShortcutPackageInfo(LAUNCHER_1, USER_10);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
// Pin some.
runWithCaller(LAUNCHER_1, USER_0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- Arrays.asList("s3", "s4"), getCallingUser());
+ list("s3", "s4"), getCallingUser());
+
+ assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- Arrays.asList("s1", "s2", "s4"), getCallingUser());
+ list("s1", "s2", "s4"), getCallingUser());
});
dumpsysOnLogcat();
@@ -2027,12 +2256,18 @@
| ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
"s2");
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
// Now pin some.
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- Arrays.asList("s1", "s2"), getCallingUser());
+ list("s1", "s2"), getCallingUser());
+
+ assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+ assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- Arrays.asList("s1", "s2"), getCallingUser());
+ list("s1", "s2"), getCallingUser());
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2048,10 +2283,26 @@
"s2");
});
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+ assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+ assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+
// Re-initialize and load from the files.
mService.saveDirtyInfo();
initService();
+ // Load from file.
+ mService.handleUnlockUser(USER_0);
+
+ // Make sure package info is restored too.
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+ assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+ assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+
runWithCaller(LAUNCHER_1, USER_0, () -> {
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2108,7 +2359,7 @@
// Update pined. Note s2 and s3 are actually available, but not visible to this
// launcher, so still can't be pinned.
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s1", "s2", "s3", "s4"),
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
getCallingUser());
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
@@ -2130,7 +2381,7 @@
"s3");
// Now "s1" is visible, so can be pinned.
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s1", "s2", "s3", "s4"),
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
getCallingUser());
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
@@ -2141,8 +2392,8 @@
// Now clear pinned shortcuts. First, from launcher 1.
runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList(), getCallingUser());
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList(), getCallingUser());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
assertEquals(0,
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2162,8 +2413,8 @@
// Clear all pins from launcher 2.
runWithCaller(LAUNCHER_2, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList(), getCallingUser());
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList(), getCallingUser());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
assertEquals(0,
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2182,7 +2433,502 @@
});
}
- public void testCreateShortcutIntent() {
+ public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
+ // Create some shortcuts.
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+ makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
+ });
+
+ // Pin some shortcuts and see the result.
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s1"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
+ list("s1", "s2", "s3"), HANDLE_USER_0);
+ });
+
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s2"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
+ list("s2", "s3"), HANDLE_USER_0);
+ });
+
+ runWithCaller(LAUNCHER_2, USER_P0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s3"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
+ list("s3"), HANDLE_USER_0);
+ });
+
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s1", "s2", "s3"), HANDLE_USER_10);
+ });
+
+ // Cross profile pinning.
+ final int PIN_AND_DYNAMIC = ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC;
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_2, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
+ "s1", "s2", "s3", "s4", "s5", "s6");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
+ "s1", "s2", "s3", "s4", "s5", "s6");
+ });
+
+ // Remove some dynamic shortcuts.
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"))));
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"))));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_2, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s3");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
+ "s1", "s2", "s3");
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+
+ // Save & load and make sure we still have the same information.
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_0);
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s2", "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s2", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ runWithCaller(LAUNCHER_2, USER_P0, () -> {
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s3");
+
+ assertShortcutIds(assertAllPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ "s3");
+ assertShortcutIds(assertAllDynamic(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ "s1");
+ assertShortcutIds(assertAllDynamicOrPinned(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ "s1", "s3");
+
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s4", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s5", USER_10);
+ assertShortcutNotLaunchable(CALLING_PACKAGE_1, "s6", USER_10);
+ });
+ }
+
+ public void testStartShortcut() {
// Create some shortcuts.
setCaller(CALLING_PACKAGE_1);
final ShortcutInfo s1_1 = makeShortcut(
@@ -2202,7 +2948,7 @@
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
/* weight */ 12);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s1_1, s1_2)));
+ assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
setCaller(CALLING_PACKAGE_2);
final ShortcutInfo s2_1 = makeShortcut(
@@ -2213,15 +2959,15 @@
makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
"key1", "val1", "nest", makeBundle("key", 123)),
/* weight */ 10);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(s2_1)));
+ assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
// Pin all.
setCaller(LAUNCHER_1);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- Arrays.asList("s1", "s2"), getCallingUser());
+ list("s1", "s2"), getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- Arrays.asList("s1"), getCallingUser());
+ list("s1"), getCallingUser());
// Just to make it complicated, delete some.
setCaller(CALLING_PACKAGE_1);
@@ -2229,17 +2975,16 @@
// intent and check.
setCaller(LAUNCHER_1);
+
Intent intent;
- intent = mInternal.createShortcutIntent(getCallingPackage(),
- CALLING_PACKAGE_1, "s1", getCallingUserId());
+ intent = launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s1", USER_0);
assertEquals(ShortcutActivity2.class.getName(), intent.getComponent().getClassName());
- intent = mInternal.createShortcutIntent(getCallingPackage(),
- CALLING_PACKAGE_1, "s2", getCallingUserId());
+
+ intent = launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0);
assertEquals(ShortcutActivity3.class.getName(), intent.getComponent().getClassName());
- intent = mInternal.createShortcutIntent(getCallingPackage(),
- CALLING_PACKAGE_2, "s1", getCallingUserId());
+ intent = launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0);
assertEquals(ShortcutActivity.class.getName(), intent.getComponent().getClassName());
// TODO Check extra, etc
@@ -2261,7 +3006,7 @@
});
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
@@ -2270,7 +3015,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
"s1", "s2", "s3");
@@ -2278,7 +3023,7 @@
// From different package.
reset(c0);
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
waitOnMainThread();
@@ -2286,7 +3031,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_2),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
"s1", "s2", "s3");
@@ -2294,7 +3039,7 @@
// Different user, callback shouldn't be called.
reset(c0);
runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
waitOnMainThread();
@@ -2315,7 +3060,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
"s1", "s2", "s3", "s4");
@@ -2331,7 +3076,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
"s2", "s3", "s4");
@@ -2339,7 +3084,7 @@
// Test for update
reset(c0);
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.updateShortcuts(Arrays.asList(
+ assertTrue(mManager.updateShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
@@ -2348,7 +3093,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertShortcutIds(assertAllDynamic(shortcuts.getValue()),
"s2", "s3", "s4");
@@ -2364,13 +3109,13 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertEquals(0, shortcuts.getValue().size());
// Remove CALLING_PACKAGE_2
reset(c0);
- mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_0);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_0, USER_0);
// Should get a callback with an empty list.
waitOnMainThread();
@@ -2378,7 +3123,7 @@
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_2),
shortcuts.capture(),
- eq(UserHandle.of(USER_0))
+ eq(HANDLE_USER_0)
);
assertEquals(0, shortcuts.getValue().size());
}
@@ -2386,7 +3131,7 @@
// === Test for persisting ===
public void testSaveAndLoadUser_empty() {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList()));
+ assertTrue(mManager.setDynamicShortcuts(list()));
Log.i(TAG, "Saved state");
dumpsysOnLogcat();
@@ -2426,7 +3171,7 @@
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
/* weight */ 12);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
assertEquals(2, mManager.getRemainingCallCount());
@@ -2453,7 +3198,7 @@
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
/* weight */ 12);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
assertEquals(2, mManager.getRemainingCallCount());
@@ -2480,7 +3225,7 @@
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
/* weight */ 12);
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
assertEquals(2, mManager.getRemainingCallCount());
@@ -2489,6 +3234,10 @@
mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncherComponent(
mService, new ComponentName("pkg1", "class"));
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+
// Restore.
mService.saveDirtyInfo();
initService();
@@ -2499,6 +3248,10 @@
// this will pre-load the per-user info.
mService.handleUnlockUser(UserHandle.USER_SYSTEM);
+ assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+ assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+ assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+
// Now it's loaded.
assertEquals(1, mService.getShortcutsForTest().size());
@@ -2549,45 +3302,45 @@
public void testCleanupPackage() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s0_1"))));
});
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s0_2"))));
});
runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s0_1"),
- UserHandle.of(USER_0));
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s0_2"),
- UserHandle.of(USER_0));
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
+ HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
+ HANDLE_USER_0);
});
runWithCaller(LAUNCHER_2, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s0_1"),
- UserHandle.of(USER_0));
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s0_2"),
- UserHandle.of(USER_0));
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
+ HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
+ HANDLE_USER_0);
});
runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s10_1"))));
});
runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
- assertTrue(mManager.setDynamicShortcuts(Arrays.asList(
+ assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s10_2"))));
});
runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s10_1"),
- UserHandle.of(USER_10));
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s10_2"),
- UserHandle.of(USER_10));
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
+ HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
+ HANDLE_USER_10);
});
runWithCaller(LAUNCHER_2, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s10_1"),
- UserHandle.of(USER_10));
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s10_2"),
- UserHandle.of(USER_10));
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
+ HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
+ HANDLE_USER_10);
});
// Remove all dynamic shortcuts; now all shortcuts are just pinned.
@@ -2615,15 +3368,19 @@
// Check the registered packages.
-
+ dumpsysOnLogcat();
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_10, LAUNCHER_1),
+ PackageWithUser.of(USER_10, LAUNCHER_2)),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_1", "s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2637,20 +3394,29 @@
assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
mService.saveDirtyInfo();
// Nonexistent package.
- mService.cleanUpPackageLocked("abc", USER_0);
+ mService.cleanUpPackageLocked("abc", USER_0, USER_0);
// No changes.
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_10, LAUNCHER_1),
+ PackageWithUser.of(USER_10, LAUNCHER_2)),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_1", "s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2664,19 +3430,28 @@
assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
mService.saveDirtyInfo();
// Remove a package.
- mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0);
assertEquals(makeSet(CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_10, LAUNCHER_1),
+ PackageWithUser.of(USER_10, LAUNCHER_2)),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2690,19 +3465,27 @@
assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
mService.saveDirtyInfo();
// Remove a launcher.
- mService.cleanUpPackageLocked(LAUNCHER_1, USER_10);
+ mService.cleanUpPackageLocked(LAUNCHER_1, USER_10, USER_10);
assertEquals(makeSet(CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(LAUNCHER_2),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_10, LAUNCHER_2)),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2717,16 +3500,19 @@
mService.saveDirtyInfo();
// Remove a package.
- mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10, USER_10);
assertEquals(makeSet(CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(LAUNCHER_2),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_10, LAUNCHER_2)),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2738,19 +3524,27 @@
assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
mService.saveDirtyInfo();
// Remove the other launcher from user 10 too.
- mService.cleanUpPackageLocked(LAUNCHER_2, USER_10);
+ mService.cleanUpPackageLocked(LAUNCHER_2, USER_10, USER_10);
assertEquals(makeSet(CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(CALLING_PACKAGE_1),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
- assertEquals(makeSet(),
- set(user10.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
+ assertEquals(
+ makeSet(),
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2765,16 +3559,18 @@
mService.saveDirtyInfo();
// More remove.
- mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10);
assertEquals(makeSet(CALLING_PACKAGE_2),
set(user0.getPackages().keySet()));
assertEquals(makeSet(),
set(user10.getPackages().keySet()));
- assertEquals(makeSet(LAUNCHER_1, LAUNCHER_2),
- set(user0.getLaunchers().keySet()));
+ assertEquals(
+ makeSet(PackageWithUser.of(USER_0, LAUNCHER_1),
+ PackageWithUser.of(USER_0, LAUNCHER_2)),
+ set(user0.getAllLaunchers().keySet()));
assertEquals(makeSet(),
- set(user10.getLaunchers().keySet()));
+ set(user10.getAllLaunchers().keySet()));
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
@@ -2789,7 +3585,526 @@
mService.saveDirtyInfo();
}
+ public void testHandleGonePackage_crossProfile() {
+ // Create some shortcuts.
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ // Pin some.
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s1"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s2"), UserHandle.of(USER_P0));
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
+ list("s3"), HANDLE_USER_0);
+ });
+
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s2"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s3"), UserHandle.of(USER_P0));
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
+ list("s1"), HANDLE_USER_0);
+ });
+
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("s3"), HANDLE_USER_10);
+ });
+
+ // Check the state.
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ // These two shouldn't exist
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0, USER_P0));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ // Make sure all the information is persisted.
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_10);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ // These two shouldn't exist
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0, USER_P0));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+
+ // Start uninstalling.
+ uninstallPackage(USER_10, LAUNCHER_1);
+ mService.cleanupGonePackages(USER_10);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ // Uninstall.
+ uninstallPackage(USER_10, CALLING_PACKAGE_1);
+ mService.cleanupGonePackages(USER_10);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ uninstallPackage(USER_P0, LAUNCHER_1);
+ mService.cleanupGonePackages(USER_0);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ mService.cleanupGonePackages(USER_P0);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ uninstallPackage(USER_P0, CALLING_PACKAGE_1);
+
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_10);
+
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ // Uninstall
+ uninstallPackage(USER_0, LAUNCHER_1);
+
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_10);
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+
+ uninstallPackage(USER_0, CALLING_PACKAGE_2);
+
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_10);
+
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_P0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_P0, USER_P0));
+ assertNull(mService.getPackageInfoForTest(LAUNCHER_1, USER_10, USER_10));
+ }
+
// TODO Detailed test for hasShortcutPermissionInner().
// TODO Add tests for the command line functions too.
+
+ private void checkCanRestoreTo(boolean expected, ShortcutPackageInfo spi,
+ int version, String... signatures) {
+ assertEquals(expected, spi.canRestoreTo(genPackage(
+ "dummy", /* uid */ 0, version, signatures)));
+ }
+
+ public void testCanRestoreTo() {
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
+ addPackage(CALLING_PACKAGE_2, CALLING_UID_1, 10, "sig1", "sig2");
+
+ final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackage(
+ mService, CALLING_PACKAGE_1, USER_0);
+ final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackage(
+ mService, CALLING_PACKAGE_2, USER_0);
+
+ checkCanRestoreTo(true, spi1, 10, "sig1");
+ checkCanRestoreTo(true, spi1, 10, "x", "sig1");
+ checkCanRestoreTo(true, spi1, 10, "sig1", "y");
+ checkCanRestoreTo(true, spi1, 10, "x", "sig1", "y");
+ checkCanRestoreTo(true, spi1, 11, "sig1");
+
+ checkCanRestoreTo(false, spi1, 10 /* empty */);
+ checkCanRestoreTo(false, spi1, 10, "x");
+ checkCanRestoreTo(false, spi1, 10, "x", "y");
+ checkCanRestoreTo(false, spi1, 10, "x");
+ checkCanRestoreTo(false, spi1, 9, "sig1");
+
+ checkCanRestoreTo(true, spi2, 10, "sig1", "sig2");
+ checkCanRestoreTo(true, spi2, 10, "sig2", "sig1");
+ checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2");
+ checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1");
+ checkCanRestoreTo(true, spi2, 10, "sig1", "sig2", "y");
+ checkCanRestoreTo(true, spi2, 10, "sig2", "sig1", "y");
+ checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2", "y");
+ checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1", "y");
+ checkCanRestoreTo(true, spi2, 11, "x", "sig2", "sig1", "y");
+
+ checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x");
+ checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x");
+ checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2");
+ checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1");
+ checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x", "y");
+ checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x", "y");
+ checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2", "y");
+ checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1", "y");
+ checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y");
+ }
+
+ public void testShortcutPackageInfoRefresh() {
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
+
+ final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackage(
+ mService, CALLING_PACKAGE_1, USER_0);
+
+ checkCanRestoreTo(true, spi1, 10, "sig1");
+
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 11, "sig1", "sig2");
+
+ spi1.refreshAndSave(mService, USER_0);
+
+ mService.handleCleanupUser(USER_0);
+ initService();
+
+ checkCanRestoreTo(false, spi1, 10, "sig1", "sig2");
+ checkCanRestoreTo(false, spi1, 11, "sig", "sig2");
+ checkCanRestoreTo(false, spi1, 11, "sig1", "sig");
+ checkCanRestoreTo(true, spi1, 11, "sig1", "sig2");
+ }
+
+ public void testHandlePackageDelete() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ setCaller(CALLING_PACKAGE_2, USER_0);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ setCaller(CALLING_PACKAGE_3, USER_0);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ setCaller(CALLING_PACKAGE_1, USER_10);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ setCaller(CALLING_PACKAGE_2, USER_10);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ setCaller(CALLING_PACKAGE_3, USER_10);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0));
+
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10));
+
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+ mInjectedPackages.remove(CALLING_PACKAGE_1);
+ mInjectedPackages.remove(CALLING_PACKAGE_3);
+
+ mService.handleUnlockUser(USER_0);
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+ mService.handleUnlockUser(USER_10);
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+ assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+ }
+
+ public void testHandlePackageUpdate() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+ assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+ assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+ assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 123);
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageUpdateIntent("abc", USER_0));
+ assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageUpdateIntent("abc", USER_10));
+ assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(123, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0)
+ .getVersionCode());
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
new file mode 100644
index 0000000..c016e61
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm.backup;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageParser.Package;
+import android.content.pm.Signature;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.backup.BackupUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+@SmallTest
+public class BackupUtilsTest extends AndroidTestCase {
+
+ private Signature[] genSignatures(String... signatures) {
+ final Signature[] sigs = new Signature[signatures.length];
+ for (int i = 0; i < signatures.length; i++){
+ sigs[i] = new Signature(signatures[i].getBytes());
+ }
+ return sigs;
+ }
+
+ private PackageInfo genPackage(String... signatures) {
+ final PackageInfo pi = new PackageInfo();
+ pi.packageName = "package";
+ pi.applicationInfo = new ApplicationInfo();
+ pi.signatures = genSignatures(signatures);
+
+ return pi;
+ }
+
+ public void testSignaturesMatch() {
+ final ArrayList<byte[]> stored1 = BackupUtils.hashSignatureArray(Arrays.asList(
+ "abc".getBytes()));
+ final ArrayList<byte[]> stored2 = BackupUtils.hashSignatureArray(Arrays.asList(
+ "abc".getBytes(), "def".getBytes()));
+
+ PackageInfo pi;
+
+ // False for null package.
+ assertFalse(BackupUtils.signaturesMatch(stored1, null));
+
+ // If it's a system app, signatures don't matter.
+ pi = genPackage("xyz");
+ pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ assertTrue(BackupUtils.signaturesMatch(stored1, pi));
+
+ // Non system apps.
+ assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc")));
+
+ // Superset is okay.
+ assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc", "xyz")));
+ assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "abc")));
+
+ assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz")));
+ assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "def")));
+
+ assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("def", "abc")));
+ assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("x", "def", "abc", "y")));
+
+ // Subset is not okay.
+ assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("abc")));
+ assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("def")));
+ }
+
+ public void testHashSignature() {
+ final byte[] sig1 = "abc".getBytes();
+ final byte[] sig2 = "def".getBytes();
+
+ final byte[] hash1a = BackupUtils.hashSignature(sig1);
+ final byte[] hash1b = BackupUtils.hashSignature(new Signature(sig1));
+
+ final byte[] hash2a = BackupUtils.hashSignature(sig2);
+ final byte[] hash2b = BackupUtils.hashSignature(new Signature(sig2));
+
+ assertEquals(32, hash1a.length);
+ MoreAsserts.assertEquals(hash1a, hash1b);
+
+ assertEquals(32, hash2a.length);
+ MoreAsserts.assertEquals(hash2a, hash2b);
+
+ assertFalse(Arrays.equals(hash1a, hash2a));
+
+ final ArrayList<byte[]> listA = BackupUtils.hashSignatureArray(Arrays.asList(
+ "abc".getBytes(), "def".getBytes()));
+
+ final ArrayList<byte[]> listB = BackupUtils.hashSignatureArray(new Signature[]{
+ new Signature("abc".getBytes()), new Signature("def".getBytes())});
+
+ assertEquals(2, listA.size());
+ assertEquals(2, listB.size());
+
+ MoreAsserts.assertEquals(hash1a, listA.get(0));
+ MoreAsserts.assertEquals(hash1a, listB.get(0));
+
+ MoreAsserts.assertEquals(hash2a, listA.get(1));
+ MoreAsserts.assertEquals(hash2a, listB.get(1));
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 129e537..058de05 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -385,6 +385,7 @@
UsbAudioDevice audioDevice = selectAudioCard(addedCard);
if (audioDevice != null) {
mAudioDevices.put(usbDevice, audioDevice);
+ Slog.i(TAG, "USB Audio Device Added: " + audioDevice);
}
// look for MIDI devices
@@ -441,6 +442,7 @@
}
UsbAudioDevice audioDevice = mAudioDevices.remove(usbDevice);
+ Slog.i(TAG, "USB Audio Device Removed: " + audioDevice);
if (audioDevice != null) {
if (audioDevice.mHasPlayback || audioDevice.mHasCapture) {
notifyDeviceState(audioDevice, false);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 5fe944c..08cbcf7 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -780,7 +780,7 @@
|| ("0".equals(SystemProperties.get("persist.charging.notify")))) return;
int id = 0;
Resources r = mContext.getResources();
- if (mConnected || mHostConnected) {
+ if (mConnected) {
if (!mUsbDataUnlocked) {
id = com.android.internal.R.string.usb_charging_notification_title;
} else if (UsbManager.containsFunction(mCurrentFunctions,
@@ -798,6 +798,8 @@
} else {
id = com.android.internal.R.string.usb_charging_notification_title;
}
+ } else if (mHostConnected) {
+ id = com.android.internal.R.string.usb_supplying_notification_title;
}
if (id != mUsbNotificationId) {
// clear notification if title needs changing
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 06851ee..1ce4ade 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -694,7 +694,7 @@
if (mPreviousExtraKeys != null) {
List<String> toRemove = new ArrayList<String>();
for (String oldKey : mPreviousExtraKeys) {
- if (!extras.containsKey(oldKey)) {
+ if (extras == null || !extras.containsKey(oldKey)) {
toRemove.add(oldKey);
}
}
@@ -710,7 +710,9 @@
mPreviousExtraKeys = new ArraySet<String>();
}
mPreviousExtraKeys.clear();
- mPreviousExtraKeys.addAll(extras.keySet());
+ if (extras != null) {
+ mPreviousExtraKeys.addAll(extras.keySet());
+ }
}
/**
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 310c957..d83cdb8 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1887,7 +1887,7 @@
if (mPreviousExtraKeys != null) {
List<String> toRemove = new ArrayList<String>();
for (String oldKey : mPreviousExtraKeys) {
- if (!extras.containsKey(oldKey)) {
+ if (extras == null || !extras.containsKey(oldKey)) {
toRemove.add(oldKey);
}
}
@@ -1902,7 +1902,9 @@
mPreviousExtraKeys = new ArraySet<String>();
}
mPreviousExtraKeys.clear();
- mPreviousExtraKeys.addAll(extras.keySet());
+ if (extras != null) {
+ mPreviousExtraKeys.addAll(extras.keySet());
+ }
}
/**
@@ -2317,7 +2319,7 @@
*/
public void sendConnectionEvent(String event, Bundle extras) {
for (Listener l : mListeners) {
- l.onConnectionEvent(this, event, null);
+ l.onConnectionEvent(this, event, extras);
}
}
}
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 4c12c2d..0412bc7 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -65,4 +65,9 @@
}
return certs;
}
+
+ @Override
+ public void handleTrustStorageUpdate() {
+ // Nothing to do.
+ }
}
diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml
index dc4cdb5..71d6001 100644
--- a/tests/SoundTriggerTestApp/AndroidManifest.xml
+++ b/tests/SoundTriggerTestApp/AndroidManifest.xml
@@ -2,7 +2,7 @@
package="com.android.test.soundtrigger">
<uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
- <uses-permission android:name="android.permission.WAKE_LOCk" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
<activity
android:name="TestSoundTriggerActivity"
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
index af6ba24..2cdc647 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
@@ -43,6 +43,7 @@
import android.view.ViewGroup;
import android.view.WindowCallback;
import android.widget.ActionMenuPresenter;
+import android.widget.ActionMenuView;
import android.widget.Toolbar;
import android.widget.Toolbar_Accessor;
@@ -196,11 +197,16 @@
@Override
protected void inflateMenus() {
super.inflateMenus();
- // Inflating the menus doesn't initialize the ActionMenuPresenter. Setting a fake menu
- // and then setting it back does the trick.
+ // Inflating the menus isn't enough. ActionMenuPresenter needs to be initialized too.
MenuBuilder menu = getMenuBuilder();
DecorToolbar decorToolbar = getDecorToolbar();
+ // Setting a menu different from the above initializes the presenter.
decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
+ // ActionMenuView needs to be recreated to be able to set the menu back.
+ ActionMenuPresenter presenter = getActionMenuPresenter();
+ if (presenter != null) {
+ presenter.setMenuView(new ActionMenuView(getPopupContext()));
+ }
decorToolbar.setMenu(menu, null);
}
@@ -255,7 +261,7 @@
@NonNull ActionBarView actionBarView) {
super(context, callback, new WindowDecorActionBar(decorContentRoot));
mActionBarView = actionBarView;
- mActionBar = ((WindowDecorActionBar) super.mActionBar);
+ mActionBar = (WindowDecorActionBar) super.mActionBar;
mDecorContentRoot = decorContentRoot;
}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
index 035317e..4c38c9b 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
+++ b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
@@ -19,6 +19,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
+
/**
* Record of energy and activity information from controller and
* underlying wifi stack state. Timestamp the record with elapsed
@@ -44,6 +46,11 @@
/**
* @hide
*/
+ public long[] mControllerTxTimePerLevelMs;
+
+ /**
+ * @hide
+ */
public long mControllerRxTimeMs;
/**
@@ -62,10 +69,12 @@
public static final int STACK_STATE_STATE_IDLE = 3;
public WifiActivityEnergyInfo(long timestamp, int stackState,
- long txTime, long rxTime, long idleTime, long energyUsed) {
+ long txTime, long[] txTimePerLevel, long rxTime, long idleTime,
+ long energyUsed) {
mTimestamp = timestamp;
mStackState = stackState;
mControllerTxTimeMs = txTime;
+ mControllerTxTimePerLevelMs = txTimePerLevel;
mControllerRxTimeMs = rxTime;
mControllerIdleTimeMs = idleTime;
mControllerEnergyUsed = energyUsed;
@@ -77,6 +86,7 @@
+ " timestamp=" + mTimestamp
+ " mStackState=" + mStackState
+ " mControllerTxTimeMs=" + mControllerTxTimeMs
+ + " mControllerTxTimePerLevelMs=" + Arrays.toString(mControllerTxTimePerLevelMs)
+ " mControllerRxTimeMs=" + mControllerRxTimeMs
+ " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+ " mControllerEnergyUsed=" + mControllerEnergyUsed
@@ -89,11 +99,12 @@
long timestamp = in.readLong();
int stackState = in.readInt();
long txTime = in.readLong();
+ long[] txTimePerLevel = in.createLongArray();
long rxTime = in.readLong();
long idleTime = in.readLong();
long energyUsed = in.readLong();
return new WifiActivityEnergyInfo(timestamp, stackState,
- txTime, rxTime, idleTime, energyUsed);
+ txTime, txTimePerLevel, rxTime, idleTime, energyUsed);
}
public WifiActivityEnergyInfo[] newArray(int size) {
return new WifiActivityEnergyInfo[size];
@@ -104,6 +115,7 @@
out.writeLong(mTimestamp);
out.writeInt(mStackState);
out.writeLong(mControllerTxTimeMs);
+ out.writeLongArray(mControllerTxTimePerLevelMs);
out.writeLong(mControllerRxTimeMs);
out.writeLong(mControllerIdleTimeMs);
out.writeLong(mControllerEnergyUsed);
@@ -128,6 +140,16 @@
}
/**
+ * @return tx time at power level provided in ms
+ */
+ public long getControllerTxTimeMillisAtLevel(int level) {
+ if (level < mControllerTxTimePerLevelMs.length) {
+ return mControllerTxTimePerLevelMs[level];
+ }
+ return 0;
+ }
+
+ /**
* @return rx time in ms
*/
public long getControllerRxTimeMillis() {
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 06dea07..fb2bdd4 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -938,6 +938,15 @@
private boolean mSeenInLastQualifiedNetworkSelection;
/**
+ * Boolean indicating if we have ever successfully connected to this network.
+ *
+ * This value will be set to true upon a successful connection.
+ * This value will be set to false if a previous value was not stored in the config or if
+ * the credentials are updated (ex. a password change).
+ */
+ private boolean mHasEverConnected;
+
+ /**
* set whether this network is visible in latest Qualified Network Selection
* @param seen value set to candidate
*/
@@ -1027,7 +1036,18 @@
return QUALITY_NETWORK_SELECTION_STATUS[mStatus];
}
- private NetworkSelectionStatus() {};
+ public void setHasEverConnected(boolean value) {
+ mHasEverConnected = value;
+ }
+
+ public boolean getHasEverConnected() {
+ return mHasEverConnected;
+ }
+
+ private NetworkSelectionStatus() {
+ // previously stored configs will not have this parameter, so we default to false.
+ mHasEverConnected = false;
+ };
/**
* @param reason specific error reason
@@ -1226,6 +1246,7 @@
mNetworkSelectionBSSID = source.mNetworkSelectionBSSID;
setConnectChoice(source.getConnectChoice());
setConnectChoiceTimestamp(source.getConnectChoiceTimestamp());
+ setHasEverConnected(source.getHasEverConnected());
}
public void writeToParcel(Parcel dest) {
@@ -1244,6 +1265,7 @@
} else {
dest.writeInt(CONNECT_CHOICE_NOT_EXISTS);
}
+ dest.writeInt(getHasEverConnected() ? 1 : 0);
}
public void readFromParcel(Parcel in) {
@@ -1262,6 +1284,7 @@
setConnectChoice(null);
setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
}
+ setHasEverConnected(in.readInt() != 0);
}
}
@@ -1389,6 +1412,8 @@
sbuf.append(" connect choice set time: ").append(mNetworkSelectionStatus
.getConnectChoiceTimestamp());
}
+ sbuf.append(" hasEverConnected: ")
+ .append(mNetworkSelectionStatus.getHasEverConnected()).append("\n");
if (this.numAssociation > 0) {
sbuf.append(" numAssociation ").append(this.numAssociation).append("\n");
diff --git a/wifi/java/android/net/wifi/WifiLinkLayerStats.java b/wifi/java/android/net/wifi/WifiLinkLayerStats.java
index 1de4fd8..edd400b 100644
--- a/wifi/java/android/net/wifi/WifiLinkLayerStats.java
+++ b/wifi/java/android/net/wifi/WifiLinkLayerStats.java
@@ -19,6 +19,8 @@
import android.os.Parcelable;
import android.os.Parcel;
+import java.util.Arrays;
+
/**
* A class representing link layer statistics collected over a Wifi Interface.
*/
@@ -101,6 +103,8 @@
/** {@hide} */
public int tx_time;
/** {@hide} */
+ public int[] tx_time_per_level;
+ /** {@hide} */
public int rx_time;
/** {@hide} */
public int on_time_scan;
@@ -141,9 +145,10 @@
.append(" lost=").append(Long.toString(this.lostmpdu_vo))
.append(" retries=").append(Long.toString(this.retries_vo)).append('\n');
sbuf.append(" on_time : ").append(Integer.toString(this.on_time))
- .append(" tx_time=").append(Integer.toString(this.tx_time))
.append(" rx_time=").append(Integer.toString(this.rx_time))
- .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n');
+ .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n')
+ .append(" tx_time=").append(Integer.toString(this.tx_time))
+ .append(" tx_time_per_level=" + Arrays.toString(tx_time_per_level));
return sbuf.toString();
}
@@ -179,6 +184,7 @@
dest.writeString(BSSID);
dest.writeInt(on_time);
dest.writeInt(tx_time);
+ dest.writeIntArray(tx_time_per_level);
dest.writeInt(rx_time);
dest.writeInt(on_time_scan);
}
@@ -192,6 +198,7 @@
stats.BSSID = in.readString();
stats.on_time = in.readInt();
stats.tx_time = in.readInt();
+ stats.tx_time_per_level = in.createIntArray();
stats.rx_time = in.readInt();
stats.on_time_scan = in.readInt();
return stats;
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index ecf5447..508bdff 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -322,6 +322,11 @@
return mFlags;
}
+ /** {@hide} */
+ public int getBucketsScanned() {
+ return mBucketsScanned;
+ }
+
public ScanResult[] getResults() {
return mResults;
}