Merge "Keyboard Shortcuts Helper: Find device with KeyCharacterMap" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index a623b11..fbbb2e3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4916,6 +4916,7 @@
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -4924,12 +4925,14 @@
field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+ field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+ field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -4938,6 +4941,7 @@
field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
field public static final java.lang.String EXTRA_TEXT = "android.text";
field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
field public static final java.lang.String EXTRA_TITLE = "android.title";
field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5027,11 +5031,13 @@
method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
method public java.lang.CharSequence getCancelLabel();
method public java.lang.CharSequence getConfirmLabel();
+ method public boolean getHintContentIntentLaunchesActivity();
method public java.lang.CharSequence getInProgressLabel();
method public boolean isAvailableOffline();
method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean);
method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+ method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
}
@@ -5175,6 +5181,32 @@
method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
}
+ public static class Notification.MessagingStyle extends android.app.Notification.Style {
+ ctor public Notification.MessagingStyle(java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+ method public boolean getAllowGeneratedReplies();
+ method public java.lang.CharSequence getConversationTitle();
+ method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+ method public java.lang.CharSequence getUserDisplayName();
+ method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+ method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+ field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+ }
+
+ public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+ ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public int describeContents();
+ method public java.lang.String getDataMimeType();
+ method public android.net.Uri getDataUri();
+ method public java.lang.CharSequence getSender();
+ method public java.lang.CharSequence getText();
+ method public long getTimestamp();
+ method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+ }
+
public static abstract class Notification.Style {
ctor public Notification.Style();
method public android.app.Notification build();
@@ -5208,6 +5240,7 @@
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAvoidBackgroundClipping();
+ method public boolean getHintContentIntentLaunchesActivity();
method public boolean getHintHideIcon();
method public int getHintScreenTimeout();
method public boolean getHintShowBackgroundOnly();
@@ -5223,6 +5256,7 @@
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
+ method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
@@ -7670,8 +7704,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -8654,6 +8686,7 @@
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
field public static final java.lang.String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
+ field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -8665,6 +8698,7 @@
field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
+ field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -13892,11 +13926,11 @@
method public abstract void close();
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createCaptureSessionByOutputConfigurations(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createReprocessableCaptureSessionByConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -19218,7 +19252,7 @@
field public static final int ADR_STATE_VALID = 1; // 0x1
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
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_NOT_DETECTED = 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
@@ -19238,21 +19272,20 @@
}
public final class GnssMeasurementsEvent implements android.os.Parcelable {
- ctor public GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]);
method public int describeContents();
method public android.location.GnssClock getClock();
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
- field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
- field public static final int STATUS_READY = 1; // 0x1
}
public static abstract class GnssMeasurementsEvent.Callback {
ctor public GnssMeasurementsEvent.Callback();
method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
}
public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -19280,36 +19313,24 @@
field public static final int TYPE_UNKNOWN = 0; // 0x0
}
- public final class GnssNavigationMessageEvent implements android.os.Parcelable {
- ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
- method public int describeContents();
- method public android.location.GnssNavigationMessage getNavigationMessage();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ public static abstract class GnssNavigationMessage.Callback {
+ ctor public GnssNavigationMessage.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+ method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
- public static abstract class GnssNavigationMessageEvent.Callback {
- ctor public GnssNavigationMessageEvent.Callback();
- method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
- method public void onStatusChanged(int);
- }
-
- public abstract interface GnssNmeaListener {
- method public abstract void onNmeaReceived(long, java.lang.String);
- }
-
public final class GnssStatus {
method public float getAzimuthDegrees(int);
method public float getCn0DbHz(int);
method public int getConstellationType(int);
method public float getElevationDegrees(int);
- method public int getNumSatellites();
+ method public int getSatelliteCount();
method public int getSvid(int);
- method public boolean hasAlmanac(int);
- method public boolean hasEphemeris(int);
+ method public boolean hasAlmanacData(int);
+ method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -19320,15 +19341,15 @@
field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
- public abstract class GnssStatusCallback {
- ctor public GnssStatusCallback();
+ public static abstract class GnssStatus.Callback {
+ ctor public GnssStatus.Callback();
method public void onFirstFix(int);
method public void onSatelliteStatusChanged(android.location.GnssStatus);
method public void onStarted();
method public void onStopped();
}
- public final class GpsSatellite {
+ public final deprecated class GpsSatellite {
method public float getAzimuth();
method public float getElevation();
method public int getPrn();
@@ -19338,7 +19359,7 @@
method public boolean usedInFix();
}
- public final class GpsStatus {
+ public final deprecated class GpsStatus {
method public int getMaxSatellites();
method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
method public int getTimeToFirstFix();
@@ -19348,11 +19369,11 @@
field public static final int GPS_EVENT_STOPPED = 2; // 0x2
}
- public static abstract interface GpsStatus.Listener {
+ public static abstract deprecated interface GpsStatus.Listener {
method public abstract void onGpsStatusChanged(int);
}
- public static abstract interface GpsStatus.NmeaListener {
+ public static abstract deprecated interface GpsStatus.NmeaListener {
method public abstract void onNmeaReceived(long, java.lang.String);
}
@@ -19414,8 +19435,8 @@
public class LocationManager {
method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
method public void clearTestProviderEnabled(java.lang.String);
@@ -19431,13 +19452,13 @@
method public boolean isProviderEnabled(java.lang.String);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
- method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void removeNmeaListener(android.location.OnNmeaMessageListener);
method public void removeProximityAlert(android.app.PendingIntent);
method public void removeTestProvider(java.lang.String);
method public void removeUpdates(android.location.LocationListener);
@@ -19456,8 +19477,8 @@
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
field public static final java.lang.String GPS_PROVIDER = "gps";
field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -19486,6 +19507,10 @@
field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
}
+ public abstract interface OnNmeaMessageListener {
+ method public abstract void onNmeaMessage(java.lang.String, long);
+ }
+
public abstract class SettingInjectorService extends android.app.Service {
ctor public SettingInjectorService(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
@@ -34689,6 +34714,7 @@
method public android.os.IBinder onBind(android.content.Intent);
method public void onInterruptionFilterChanged(int);
method public void onListenerConnected();
+ method public void onListenerDisconnected();
method public void onListenerHintsChanged(int);
method public void onNotificationPosted(android.service.notification.StatusBarNotification);
method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -34700,7 +34726,9 @@
method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException;
method public final void requestUnbind() throws android.os.RemoteException;
method public final void setNotificationsShown(java.lang.String[]);
+ field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
+ field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
@@ -34716,6 +34744,7 @@
method public int getImportance();
method public java.lang.CharSequence getImportanceExplanation();
method public java.lang.String getKey();
+ method public java.lang.String getOverrideGroupKey();
method public int getRank();
method public int getSuppressedVisualEffects();
method public boolean isAmbient();
@@ -34746,13 +34775,16 @@
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
+ method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();
method public java.lang.String getTag();
method public android.os.UserHandle getUser();
method public deprecated int getUserId();
method public boolean isClearable();
+ method public boolean isGroup();
method public boolean isOngoing();
+ method public void setOverrideGroupKey(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.notification.StatusBarNotification> CREATOR;
}
@@ -34788,7 +34820,7 @@
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public int onTileAdded();
+ method public void onTileAdded();
method public void onTileRemoved();
method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
@@ -34796,8 +34828,7 @@
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
- field public static final int TILE_MODE_ACTIVE = 2; // 0x2
- field public static final int TILE_MODE_PASSIVE = 1; // 0x1
+ field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
}
}
@@ -50026,6 +50057,9 @@
method public int compareTo(java.lang.Boolean);
method public static boolean getBoolean(java.lang.String);
method public static int hashCode(boolean);
+ method public static boolean logicalAnd(boolean, boolean);
+ method public static boolean logicalOr(boolean, boolean);
+ method public static boolean logicalXor(boolean, boolean);
method public static boolean parseBoolean(java.lang.String);
method public static java.lang.String toString(boolean);
method public static java.lang.Boolean valueOf(boolean);
@@ -50989,6 +51023,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -50998,12 +51034,20 @@
method public static float copySign(float, float);
method public static double cos(double);
method public static double cosh(double);
+ method public static int decrementExact(int);
+ method public static long decrementExact(long);
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
+ method public static int incrementExact(int);
+ method public static long incrementExact(long);
method public static double log(double);
method public static double log10(double);
method public static double log1p(double);
@@ -51015,8 +51059,14 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
+ method public static int negateExact(int);
+ method public static long negateExact(long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -51031,9 +51081,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -51317,6 +51370,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -51329,6 +51384,10 @@
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
@@ -51343,8 +51402,12 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -51359,9 +51422,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -51919,7 +51985,6 @@
public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
method public boolean equals(java.lang.Object);
method public A getAnnotation(java.lang.Class<A>);
- method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
method public java.lang.Class<?> getDeclaringClass();
method public java.lang.Object getDefaultValue();
method public java.lang.Class<?>[] getExceptionTypes();
@@ -51933,7 +51998,6 @@
method public java.lang.Class<?> getReturnType();
method public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
- method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
method public boolean isBridge();
method public boolean isDefault();
method public boolean isSynthetic();
@@ -57409,6 +57473,14 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+ method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
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);
diff --git a/api/removed.txt b/api/removed.txt
index 3f16bca..8c6abdc 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -84,6 +84,67 @@
}
+package android.location {
+
+ public final class GnssMeasurement implements android.os.Parcelable {
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ }
+
+ public final class GnssMeasurementsEvent implements android.os.Parcelable {
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+ ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+ method public int describeContents();
+ method public android.location.GnssNavigationMessage getNavigationMessage();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public static abstract class GnssNavigationMessageEvent.Callback {
+ ctor public GnssNavigationMessageEvent.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+ method public void onStatusChanged(int);
+ }
+
+ public abstract interface GnssNmeaListener {
+ method public abstract void onNmeaReceived(long, java.lang.String);
+ }
+
+ public final class GnssStatus {
+ method public int getNumSatellites();
+ method public boolean hasAlmanac(int);
+ method public boolean hasEphemeris(int);
+ }
+
+ public abstract class GnssStatusCallback {
+ ctor public GnssStatusCallback();
+ method public void onFirstFix(int);
+ method public void onSatelliteStatusChanged(android.location.GnssStatus);
+ method public void onStarted();
+ method public void onStopped();
+ }
+
+ public class LocationManager {
+ method public boolean addNmeaListener(android.location.GnssNmeaListener);
+ method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ }
+
+}
+
package android.media {
public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 9d8abef..d91f5d1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5049,6 +5049,7 @@
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -5057,12 +5058,14 @@
field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+ field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+ field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5071,8 +5074,10 @@
field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
field public static final java.lang.String EXTRA_TEXT = "android.text";
field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
field public static final java.lang.String EXTRA_TITLE = "android.title";
field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
+ field public static final int FLAG_AUTOGROUP_SUMMARY = 1024; // 0x400
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
@@ -5160,11 +5165,13 @@
method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
method public java.lang.CharSequence getCancelLabel();
method public java.lang.CharSequence getConfirmLabel();
+ method public boolean getHintContentIntentLaunchesActivity();
method public java.lang.CharSequence getInProgressLabel();
method public boolean isAvailableOffline();
method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean);
method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+ method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
}
@@ -5308,6 +5315,32 @@
method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
}
+ public static class Notification.MessagingStyle extends android.app.Notification.Style {
+ ctor public Notification.MessagingStyle(java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+ method public boolean getAllowGeneratedReplies();
+ method public java.lang.CharSequence getConversationTitle();
+ method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+ method public java.lang.CharSequence getUserDisplayName();
+ method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+ method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+ field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+ }
+
+ public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+ ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public int describeContents();
+ method public java.lang.String getDataMimeType();
+ method public android.net.Uri getDataUri();
+ method public java.lang.CharSequence getSender();
+ method public java.lang.CharSequence getText();
+ method public long getTimestamp();
+ method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+ }
+
public static abstract class Notification.Style {
ctor public Notification.Style();
method public android.app.Notification build();
@@ -5341,6 +5374,7 @@
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAvoidBackgroundClipping();
+ method public boolean getHintContentIntentLaunchesActivity();
method public boolean getHintHideIcon();
method public int getHintScreenTimeout();
method public boolean getHintShowBackgroundOnly();
@@ -5356,6 +5390,7 @@
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
+ method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
@@ -7968,8 +8003,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -8973,6 +9006,7 @@
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
field public static final java.lang.String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
+ field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -8986,6 +9020,7 @@
field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
field public static final java.lang.String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
field public static final java.lang.String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";
+ field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -14299,11 +14334,11 @@
method public abstract void close();
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createCaptureSessionByOutputConfigurations(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createReprocessableCaptureSessionByConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -20378,7 +20413,7 @@
field public static final int ADR_STATE_VALID = 1; // 0x1
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
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_NOT_DETECTED = 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
@@ -20398,21 +20433,20 @@
}
public final class GnssMeasurementsEvent implements android.os.Parcelable {
- ctor public GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]);
method public int describeContents();
method public android.location.GnssClock getClock();
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
- field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
- field public static final int STATUS_READY = 1; // 0x1
}
public static abstract class GnssMeasurementsEvent.Callback {
ctor public GnssMeasurementsEvent.Callback();
method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
}
public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -20440,36 +20474,24 @@
field public static final int TYPE_UNKNOWN = 0; // 0x0
}
- public final class GnssNavigationMessageEvent implements android.os.Parcelable {
- ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
- method public int describeContents();
- method public android.location.GnssNavigationMessage getNavigationMessage();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ public static abstract class GnssNavigationMessage.Callback {
+ ctor public GnssNavigationMessage.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+ method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
- public static abstract class GnssNavigationMessageEvent.Callback {
- ctor public GnssNavigationMessageEvent.Callback();
- method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
- method public void onStatusChanged(int);
- }
-
- public abstract interface GnssNmeaListener {
- method public abstract void onNmeaReceived(long, java.lang.String);
- }
-
public final class GnssStatus {
method public float getAzimuthDegrees(int);
method public float getCn0DbHz(int);
method public int getConstellationType(int);
method public float getElevationDegrees(int);
- method public int getNumSatellites();
+ method public int getSatelliteCount();
method public int getSvid(int);
- method public boolean hasAlmanac(int);
- method public boolean hasEphemeris(int);
+ method public boolean hasAlmanacData(int);
+ method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -20480,8 +20502,8 @@
field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
- public abstract class GnssStatusCallback {
- ctor public GnssStatusCallback();
+ public static abstract class GnssStatus.Callback {
+ ctor public GnssStatus.Callback();
method public void onFirstFix(int);
method public void onSatelliteStatusChanged(android.location.GnssStatus);
method public void onStarted();
@@ -20713,7 +20735,7 @@
method public abstract void onStatusChanged(int);
}
- public final class GpsSatellite {
+ public final deprecated class GpsSatellite {
method public float getAzimuth();
method public float getElevation();
method public int getPrn();
@@ -20723,7 +20745,7 @@
method public boolean usedInFix();
}
- public final class GpsStatus {
+ public final deprecated class GpsStatus {
method public int getMaxSatellites();
method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
method public int getTimeToFirstFix();
@@ -20733,11 +20755,11 @@
field public static final int GPS_EVENT_STOPPED = 2; // 0x2
}
- public static abstract interface GpsStatus.Listener {
+ public static abstract deprecated interface GpsStatus.Listener {
method public abstract void onGpsStatusChanged(int);
}
- public static abstract interface GpsStatus.NmeaListener {
+ public static abstract deprecated interface GpsStatus.NmeaListener {
method public abstract void onNmeaReceived(long, java.lang.String);
}
@@ -20821,8 +20843,8 @@
method public deprecated boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
method public void clearTestProviderEnabled(java.lang.String);
@@ -20838,15 +20860,15 @@
method public boolean isProviderEnabled(java.lang.String);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
method public deprecated void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
method public deprecated void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
- method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void removeNmeaListener(android.location.OnNmeaMessageListener);
method public void removeProximityAlert(android.app.PendingIntent);
method public void removeTestProvider(java.lang.String);
method public void removeUpdates(android.location.LocationListener);
@@ -20867,8 +20889,8 @@
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
field public static final java.lang.String GPS_PROVIDER = "gps";
field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -20931,6 +20953,10 @@
field public static final int POWER_NONE = 200; // 0xc8
}
+ public abstract interface OnNmeaMessageListener {
+ method public abstract void onNmeaMessage(java.lang.String, long);
+ }
+
public abstract class SettingInjectorService extends android.app.Service {
ctor public SettingInjectorService(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
@@ -37095,6 +37121,22 @@
package android.service.notification {
+ public final class Adjustment implements android.os.Parcelable {
+ ctor public Adjustment(java.lang.String, java.lang.String, int, android.os.Bundle, java.lang.CharSequence, android.net.Uri);
+ ctor protected Adjustment(android.os.Parcel);
+ method public int describeContents();
+ method public java.lang.CharSequence getExplanation();
+ method public int getImportance();
+ method public java.lang.String getKey();
+ method public java.lang.String getPackage();
+ method public android.net.Uri getReference();
+ method public android.os.Bundle getSignals();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
+ field public static final java.lang.String GROUP_KEY_OVERRIDE_KEY = "group_key_override";
+ field public static final java.lang.String NEEDS_AUTOGROUPING_KEY = "autogroup_needed";
+ }
+
public class Condition implements android.os.Parcelable {
ctor public Condition(android.net.Uri, java.lang.String, int);
ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
@@ -37155,6 +37197,7 @@
method public android.os.IBinder onBind(android.content.Intent);
method public void onInterruptionFilterChanged(int);
method public void onListenerConnected();
+ method public void onListenerDisconnected();
method public void onListenerHintsChanged(int);
method public void onNotificationPosted(android.service.notification.StatusBarNotification);
method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -37169,7 +37212,9 @@
method public final void setNotificationsShown(java.lang.String[]);
method public final void setOnNotificationPostedTrim(int);
method public void unregisterAsSystemService() throws android.os.RemoteException;
+ field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
+ field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
@@ -37187,6 +37232,7 @@
method public int getImportance();
method public java.lang.CharSequence getImportanceExplanation();
method public java.lang.String getKey();
+ method public java.lang.String getOverrideGroupKey();
method public int getRank();
method public int getSuppressedVisualEffects();
method public boolean isAmbient();
@@ -37210,11 +37256,12 @@
public abstract class NotificationRankerService extends android.service.notification.NotificationListenerService {
ctor public NotificationRankerService();
- method public final void adjustImportance(java.lang.String, android.service.notification.NotificationRankerService.Adjustment);
+ method public final void adjustNotification(android.service.notification.Adjustment);
+ method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>);
method public final android.os.IBinder onBind(android.content.Intent);
method public void onNotificationActionClick(java.lang.String, long, int);
method public void onNotificationClick(java.lang.String, long);
- method public abstract android.service.notification.NotificationRankerService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
method public void onNotificationRemoved(java.lang.String, long, int);
method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
field public static final int REASON_APP_CANCEL = 8; // 0x8
@@ -37231,14 +37278,11 @@
field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe
field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf
+ field public static final int REASON_UNAUTOBUNDLED = 16; // 0x10
field public static final int REASON_USER_STOPPED = 6; // 0x6
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationRankerService";
}
- public class NotificationRankerService.Adjustment {
- ctor public NotificationRankerService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
- }
-
public class StatusBarNotification implements android.os.Parcelable {
ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long);
ctor public StatusBarNotification(android.os.Parcel);
@@ -37248,13 +37292,16 @@
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
+ method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();
method public java.lang.String getTag();
method public android.os.UserHandle getUser();
method public deprecated int getUserId();
method public boolean isClearable();
+ method public boolean isGroup();
method public boolean isOngoing();
+ method public void setOverrideGroupKey(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.notification.StatusBarNotification> CREATOR;
}
@@ -37323,7 +37370,7 @@
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public int onTileAdded();
+ method public void onTileAdded();
method public void onTileRemoved();
method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void setStatusIcon(android.graphics.drawable.Icon, java.lang.String);
@@ -37332,8 +37379,7 @@
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
- field public static final int TILE_MODE_ACTIVE = 2; // 0x2
- field public static final int TILE_MODE_PASSIVE = 1; // 0x1
+ field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
}
}
@@ -53123,6 +53169,9 @@
method public int compareTo(java.lang.Boolean);
method public static boolean getBoolean(java.lang.String);
method public static int hashCode(boolean);
+ method public static boolean logicalAnd(boolean, boolean);
+ method public static boolean logicalOr(boolean, boolean);
+ method public static boolean logicalXor(boolean, boolean);
method public static boolean parseBoolean(java.lang.String);
method public static java.lang.String toString(boolean);
method public static java.lang.Boolean valueOf(boolean);
@@ -54086,6 +54135,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -54095,12 +54146,20 @@
method public static float copySign(float, float);
method public static double cos(double);
method public static double cosh(double);
+ method public static int decrementExact(int);
+ method public static long decrementExact(long);
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
+ method public static int incrementExact(int);
+ method public static long incrementExact(long);
method public static double log(double);
method public static double log10(double);
method public static double log1p(double);
@@ -54112,8 +54171,14 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
+ method public static int negateExact(int);
+ method public static long negateExact(long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -54128,9 +54193,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -54414,6 +54482,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -54426,6 +54496,10 @@
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
@@ -54440,8 +54514,12 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -54456,9 +54534,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -55016,7 +55097,6 @@
public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
method public boolean equals(java.lang.Object);
method public A getAnnotation(java.lang.Class<A>);
- method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
method public java.lang.Class<?> getDeclaringClass();
method public java.lang.Object getDefaultValue();
method public java.lang.Class<?>[] getExceptionTypes();
@@ -55030,7 +55110,6 @@
method public java.lang.Class<?> getReturnType();
method public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
- method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
method public boolean isBridge();
method public boolean isDefault();
method public boolean isSynthetic();
@@ -60506,6 +60585,14 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+ method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
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);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 03cf8b0..95734c1 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -82,6 +82,67 @@
}
+package android.location {
+
+ public final class GnssMeasurement implements android.os.Parcelable {
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ }
+
+ public final class GnssMeasurementsEvent implements android.os.Parcelable {
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+ ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+ method public int describeContents();
+ method public android.location.GnssNavigationMessage getNavigationMessage();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public static abstract class GnssNavigationMessageEvent.Callback {
+ ctor public GnssNavigationMessageEvent.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+ method public void onStatusChanged(int);
+ }
+
+ public abstract interface GnssNmeaListener {
+ method public abstract void onNmeaReceived(long, java.lang.String);
+ }
+
+ public final class GnssStatus {
+ method public int getNumSatellites();
+ method public boolean hasAlmanac(int);
+ method public boolean hasEphemeris(int);
+ }
+
+ public abstract class GnssStatusCallback {
+ ctor public GnssStatusCallback();
+ method public void onFirstFix(int);
+ method public void onSatelliteStatusChanged(android.location.GnssStatus);
+ method public void onStarted();
+ method public void onStopped();
+ }
+
+ public class LocationManager {
+ method public boolean addNmeaListener(android.location.GnssNmeaListener);
+ method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ }
+
+}
+
package android.media {
public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 099ead3..bad9733 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4916,6 +4916,7 @@
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -4924,12 +4925,14 @@
field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+ field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+ field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -4938,6 +4941,7 @@
field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
field public static final java.lang.String EXTRA_TEXT = "android.text";
field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
field public static final java.lang.String EXTRA_TITLE = "android.title";
field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5027,11 +5031,13 @@
method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
method public java.lang.CharSequence getCancelLabel();
method public java.lang.CharSequence getConfirmLabel();
+ method public boolean getHintContentIntentLaunchesActivity();
method public java.lang.CharSequence getInProgressLabel();
method public boolean isAvailableOffline();
method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean);
method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+ method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
}
@@ -5175,6 +5181,32 @@
method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
}
+ public static class Notification.MessagingStyle extends android.app.Notification.Style {
+ ctor public Notification.MessagingStyle(java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+ method public boolean getAllowGeneratedReplies();
+ method public java.lang.CharSequence getConversationTitle();
+ method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+ method public java.lang.CharSequence getUserDisplayName();
+ method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+ method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+ field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+ }
+
+ public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+ ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public int describeContents();
+ method public java.lang.String getDataMimeType();
+ method public android.net.Uri getDataUri();
+ method public java.lang.CharSequence getSender();
+ method public java.lang.CharSequence getText();
+ method public long getTimestamp();
+ method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+ }
+
public static abstract class Notification.Style {
ctor public Notification.Style();
method public android.app.Notification build();
@@ -5208,6 +5240,7 @@
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAvoidBackgroundClipping();
+ method public boolean getHintContentIntentLaunchesActivity();
method public boolean getHintHideIcon();
method public int getHintScreenTimeout();
method public boolean getHintShowBackgroundOnly();
@@ -5223,6 +5256,7 @@
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
+ method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
@@ -7674,8 +7708,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -8661,6 +8693,7 @@
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
field public static final java.lang.String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
+ field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -8672,6 +8705,7 @@
field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
+ field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -13902,11 +13936,11 @@
method public abstract void close();
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createCaptureSessionByOutputConfigurations(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createReprocessableCaptureSessionByConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -19273,7 +19307,7 @@
field public static final int ADR_STATE_VALID = 1; // 0x1
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
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_NOT_DETECTED = 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
@@ -19299,15 +19333,15 @@
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
- field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
- field public static final int STATUS_READY = 1; // 0x1
}
public static abstract class GnssMeasurementsEvent.Callback {
ctor public GnssMeasurementsEvent.Callback();
method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
}
public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -19344,36 +19378,24 @@
field public static final int TYPE_UNKNOWN = 0; // 0x0
}
- public final class GnssNavigationMessageEvent implements android.os.Parcelable {
- ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
- method public int describeContents();
- method public android.location.GnssNavigationMessage getNavigationMessage();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ public static abstract class GnssNavigationMessage.Callback {
+ ctor public GnssNavigationMessage.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+ method public void onStatusChanged(int);
+ field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
- public static abstract class GnssNavigationMessageEvent.Callback {
- ctor public GnssNavigationMessageEvent.Callback();
- method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
- method public void onStatusChanged(int);
- }
-
- public abstract interface GnssNmeaListener {
- method public abstract void onNmeaReceived(long, java.lang.String);
- }
-
public final class GnssStatus {
method public float getAzimuthDegrees(int);
method public float getCn0DbHz(int);
method public int getConstellationType(int);
method public float getElevationDegrees(int);
- method public int getNumSatellites();
+ method public int getSatelliteCount();
method public int getSvid(int);
- method public boolean hasAlmanac(int);
- method public boolean hasEphemeris(int);
+ method public boolean hasAlmanacData(int);
+ method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -19384,15 +19406,15 @@
field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
- public abstract class GnssStatusCallback {
- ctor public GnssStatusCallback();
+ public static abstract class GnssStatus.Callback {
+ ctor public GnssStatus.Callback();
method public void onFirstFix(int);
method public void onSatelliteStatusChanged(android.location.GnssStatus);
method public void onStarted();
method public void onStopped();
}
- public final class GpsSatellite {
+ public final deprecated class GpsSatellite {
method public float getAzimuth();
method public float getElevation();
method public int getPrn();
@@ -19402,7 +19424,7 @@
method public boolean usedInFix();
}
- public final class GpsStatus {
+ public final deprecated class GpsStatus {
method public int getMaxSatellites();
method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
method public int getTimeToFirstFix();
@@ -19412,11 +19434,11 @@
field public static final int GPS_EVENT_STOPPED = 2; // 0x2
}
- public static abstract interface GpsStatus.Listener {
+ public static abstract deprecated interface GpsStatus.Listener {
method public abstract void onGpsStatusChanged(int);
}
- public static abstract interface GpsStatus.NmeaListener {
+ public static abstract deprecated interface GpsStatus.NmeaListener {
method public abstract void onNmeaReceived(long, java.lang.String);
}
@@ -19478,8 +19500,8 @@
public class LocationManager {
method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener);
- method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+ method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
method public void clearTestProviderEnabled(java.lang.String);
@@ -19496,13 +19518,13 @@
method public boolean isProviderEnabled(java.lang.String);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
- method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
- method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void removeNmeaListener(android.location.OnNmeaMessageListener);
method public void removeProximityAlert(android.app.PendingIntent);
method public void removeTestProvider(java.lang.String);
method public void removeUpdates(android.location.LocationListener);
@@ -19521,8 +19543,8 @@
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
- method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
field public static final java.lang.String GPS_PROVIDER = "gps";
field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -19551,6 +19573,10 @@
field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
}
+ public abstract interface OnNmeaMessageListener {
+ method public abstract void onNmeaMessage(java.lang.String, long);
+ }
+
public abstract class SettingInjectorService extends android.app.Service {
ctor public SettingInjectorService(java.lang.String);
method public final android.os.IBinder onBind(android.content.Intent);
@@ -34761,6 +34787,7 @@
method public android.os.IBinder onBind(android.content.Intent);
method public void onInterruptionFilterChanged(int);
method public void onListenerConnected();
+ method public void onListenerDisconnected();
method public void onListenerHintsChanged(int);
method public void onNotificationPosted(android.service.notification.StatusBarNotification);
method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -34772,7 +34799,9 @@
method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException;
method public final void requestUnbind() throws android.os.RemoteException;
method public final void setNotificationsShown(java.lang.String[]);
+ field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
+ field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
@@ -34788,6 +34817,7 @@
method public int getImportance();
method public java.lang.CharSequence getImportanceExplanation();
method public java.lang.String getKey();
+ method public java.lang.String getOverrideGroupKey();
method public int getRank();
method public int getSuppressedVisualEffects();
method public boolean isAmbient();
@@ -34818,13 +34848,16 @@
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
+ method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();
method public java.lang.String getTag();
method public android.os.UserHandle getUser();
method public deprecated int getUserId();
method public boolean isClearable();
+ method public boolean isGroup();
method public boolean isOngoing();
+ method public void setOverrideGroupKey(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.notification.StatusBarNotification> CREATOR;
}
@@ -34860,7 +34893,7 @@
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public int onTileAdded();
+ method public void onTileAdded();
method public void onTileRemoved();
method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
@@ -34868,8 +34901,7 @@
method public final void unlockAndRun(java.lang.Runnable);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
- field public static final int TILE_MODE_ACTIVE = 2; // 0x2
- field public static final int TILE_MODE_PASSIVE = 1; // 0x1
+ field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
}
}
@@ -50101,6 +50133,9 @@
method public int compareTo(java.lang.Boolean);
method public static boolean getBoolean(java.lang.String);
method public static int hashCode(boolean);
+ method public static boolean logicalAnd(boolean, boolean);
+ method public static boolean logicalOr(boolean, boolean);
+ method public static boolean logicalXor(boolean, boolean);
method public static boolean parseBoolean(java.lang.String);
method public static java.lang.String toString(boolean);
method public static java.lang.Boolean valueOf(boolean);
@@ -51064,6 +51099,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -51073,12 +51110,20 @@
method public static float copySign(float, float);
method public static double cos(double);
method public static double cosh(double);
+ method public static int decrementExact(int);
+ method public static long decrementExact(long);
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
+ method public static int incrementExact(int);
+ method public static long incrementExact(long);
method public static double log(double);
method public static double log10(double);
method public static double log1p(double);
@@ -51090,8 +51135,14 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
+ method public static int negateExact(int);
+ method public static long negateExact(long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -51106,9 +51157,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -51392,6 +51446,8 @@
method public static float abs(float);
method public static double abs(double);
method public static double acos(double);
+ method public static int addExact(int, int);
+ method public static long addExact(long, long);
method public static double asin(double);
method public static double atan(double);
method public static double atan2(double, double);
@@ -51404,6 +51460,10 @@
method public static double exp(double);
method public static double expm1(double);
method public static double floor(double);
+ method public static int floorDiv(int, int);
+ method public static long floorDiv(long, long);
+ method public static int floorMod(int, int);
+ method public static long floorMod(long, long);
method public static int getExponent(float);
method public static int getExponent(double);
method public static double hypot(double, double);
@@ -51418,8 +51478,12 @@
method public static long min(long, long);
method public static float min(float, float);
method public static double min(double, double);
+ method public static int multiplyExact(int, int);
+ method public static long multiplyExact(long, long);
method public static double nextAfter(double, double);
method public static float nextAfter(float, double);
+ method public static double nextDown(double);
+ method public static float nextDown(float);
method public static double nextUp(double);
method public static float nextUp(float);
method public static double pow(double, double);
@@ -51434,9 +51498,12 @@
method public static double sin(double);
method public static double sinh(double);
method public static double sqrt(double);
+ method public static int subtractExact(int, int);
+ method public static long subtractExact(long, long);
method public static double tan(double);
method public static double tanh(double);
method public static double toDegrees(double);
+ method public static int toIntExact(long);
method public static double toRadians(double);
method public static double ulp(double);
method public static float ulp(float);
@@ -51994,7 +52061,6 @@
public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
method public boolean equals(java.lang.Object);
method public A getAnnotation(java.lang.Class<A>);
- method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
method public java.lang.Class<?> getDeclaringClass();
method public java.lang.Object getDefaultValue();
method public java.lang.Class<?>[] getExceptionTypes();
@@ -52008,7 +52074,6 @@
method public java.lang.Class<?> getReturnType();
method public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
- method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
method public boolean isBridge();
method public boolean isDefault();
method public boolean isSynthetic();
@@ -57484,6 +57549,14 @@
method public static int hashCode(float[]);
method public static int hashCode(double[]);
method public static int hashCode(java.lang.Object[]);
+ method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+ method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+ method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+ method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+ method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
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);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 3f16bca..8c6abdc 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -84,6 +84,67 @@
}
+package android.location {
+
+ public final class GnssMeasurement implements android.os.Parcelable {
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ }
+
+ public final class GnssMeasurementsEvent implements android.os.Parcelable {
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+ ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+ method public int describeContents();
+ method public android.location.GnssNavigationMessage getNavigationMessage();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field public static final int STATUS_READY = 1; // 0x1
+ }
+
+ public static abstract class GnssNavigationMessageEvent.Callback {
+ ctor public GnssNavigationMessageEvent.Callback();
+ method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+ method public void onStatusChanged(int);
+ }
+
+ public abstract interface GnssNmeaListener {
+ method public abstract void onNmeaReceived(long, java.lang.String);
+ }
+
+ public final class GnssStatus {
+ method public int getNumSatellites();
+ method public boolean hasAlmanac(int);
+ method public boolean hasEphemeris(int);
+ }
+
+ public abstract class GnssStatusCallback {
+ ctor public GnssStatusCallback();
+ method public void onFirstFix(int);
+ method public void onSatelliteStatusChanged(android.location.GnssStatus);
+ method public void onStarted();
+ method public void onStopped();
+ }
+
+ public class LocationManager {
+ method public boolean addNmeaListener(android.location.GnssNmeaListener);
+ method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+ method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+ method public void removeNmeaListener(android.location.GnssNmeaListener);
+ method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+ method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+ }
+
+}
+
package android.media {
public final class AudioFormat implements android.os.Parcelable {
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 0e674c8..d527ad7 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -74,6 +74,8 @@
runGetPrimaryStorageUuid();
} else if ("set-force-adoptable".equals(op)) {
runSetForceAdoptable();
+ } else if ("set-sdcardfs".equals(op)) {
+ runSetSdcardfs();
} else if ("partition".equals(op)) {
runPartition();
} else if ("mount".equals(op)) {
@@ -141,6 +143,22 @@
StorageManager.DEBUG_FORCE_ADOPTABLE);
}
+ public void runSetSdcardfs() throws RemoteException {
+ final int mask = StorageManager.DEBUG_SDCARDFS_FORCE_ON
+ | StorageManager.DEBUG_SDCARDFS_FORCE_OFF;
+ switch (nextArg()) {
+ case "on":
+ mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_ON, mask);
+ break;
+ case "off":
+ mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_OFF, mask);
+ break;
+ case "default":
+ mSm.setDebugFlags(0, mask);
+ break;
+ }
+ }
+
public void runSetEmulateFbe() throws RemoteException {
final boolean emulateFbe = Boolean.parseBoolean(nextArg());
mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0,
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index bf823f8..56728ad 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -600,11 +600,16 @@
* Dispatch a gesture to the touch screen. Any gestures currently in progress, whether from
* the user, this service, or another service, will be cancelled.
* <p>
+ * The gesture will be dispatched as if it were performed directly on the screen by a user, so
+ * the events may be affected by features such as magnification and explore by touch.
+ * </p>
+ * <p>
* <strong>Note:</strong> In order to dispatch gestures, your service
* must declare the capability by setting the
* {@link android.R.styleable#AccessibilityService_canPerformGestures}
* property in its meta-data. For more information, see
* {@link #SERVICE_META_DATA}.
+ * </p>
*
* @param gesture The gesture to dispatch
* @param callback The object to call back when the status of the gesture is known. If
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 70357ea..7652766 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1343,20 +1343,21 @@
* {@link #getVoiceInteractor()}.
*/
public void onLocalVoiceInteractionStarted() {
- Log.i(TAG, "onLocalVoiceInteractionStarted! " + getVoiceInteractor());
}
/**
- * Callback to indicate that the local voice interaction has stopped for some
- * reason.
+ * Callback to indicate that the local voice interaction has stopped either
+ * because it was requested through a call to {@link #stopLocalVoiceInteraction()}
+ * or because it was canceled by the user. The previously acquired {@link VoiceInteractor}
+ * is no longer valid after this.
*/
public void onLocalVoiceInteractionStopped() {
- Log.i(TAG, "onLocalVoiceInteractionStopped :( " + getVoiceInteractor());
}
/**
* Request to terminate the current voice interaction that was previously started
- * using {@link #startLocalVoiceInteraction(Bundle)}.
+ * using {@link #startLocalVoiceInteraction(Bundle)}. When the interaction is
+ * terminated, {@link #onLocalVoiceInteractionStopped()} will be called.
*/
public void stopLocalVoiceInteraction() {
try {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 14c4fc6..36e962e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1526,7 +1526,7 @@
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
@@ -1541,7 +1541,7 @@
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SERVICE_ARGS:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
@@ -4727,8 +4727,16 @@
if (callbacks != null) {
final int N = callbacks.size();
for (int i=0; i<N; i++) {
- performConfigurationChanged(callbacks.get(i), null, config, null,
- REPORT_TO_ACTIVITY);
+ ComponentCallbacks2 cb = callbacks.get(i);
+ if (cb instanceof Activity) {
+ // If callback is an Activity - call corresponding method to consider override
+ // config and avoid onConfigurationChanged if it hasn't changed.
+ Activity a = (Activity) cb;
+ performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
+ config, REPORT_TO_ACTIVITY);
+ } else {
+ performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
+ }
}
}
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 7a69c62..ee80ec3 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -25,6 +25,7 @@
import android.content.pm.ParceledListSlice;
import android.net.Uri;
import android.os.Bundle;
+import android.service.notification.Adjustment;
import android.service.notification.Condition;
import android.service.notification.IConditionListener;
import android.service.notification.IConditionProvider;
@@ -80,7 +81,8 @@
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
void setInterruptionFilter(String pkg, int interruptionFilter);
- void setImportanceFromRankerService(in INotificationListener token, String key, int importance, CharSequence explanation);
+ void applyAdjustmentFromRankerService(in INotificationListener token, in Adjustment adjustment);
+ void applyAdjustmentsFromRankerService(in INotificationListener token, in List<Adjustment> adjustments);
ComponentName getEffectsSuppressor();
boolean matchesCallFilter(in Bundle extras);
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index fa67529..496ca6f 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -40,4 +40,9 @@
* Called when we launched an activity that we forced to be resizable.
*/
void onActivityForcedResizable(String packageName, int taskId);
+
+ /**
+ * Callen when we launched an activity that is dismissed the docked stack.
+ */
+ void onActivityDismissingDockedStack();
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 13e8e75..4fca69a 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -206,7 +206,7 @@
}
results.putAll(mPerfMetrics);
}
- if (mUiAutomation != null) {
+ if ((mUiAutomation != null) && !mUiAutomation.isDestroyed()) {
mUiAutomation.disconnect();
mUiAutomation = null;
}
@@ -1834,7 +1834,7 @@
}
/**
- * Gets the {@link UiAutomation} instance.
+ * Gets the {@link UiAutomation} instance with no flags set.
* <p>
* <strong>Note:</strong> The APIs exposed via the returned {@link UiAutomation}
* work across application boundaries while the APIs exposed by the instrumentation
@@ -1848,25 +1848,21 @@
* {@link Instrumentation} APIs. Using both APIs at the same time is not
* a mistake by itself but a client has to be aware of the APIs limitations.
* </p>
- * @return The UI automation instance. If none exists, a new one is created with no flags set.
+ * <p>
+ * Equivalent to {@code getUiAutomation(0)}. If a {@link UiAutomation} exists with different
+ * flags, the flags on that instance will be changed, and then it will be returned.
+ * </p>
+ * @return The UI automation instance.
*
* @see UiAutomation
*/
public UiAutomation getUiAutomation() {
- if ((mUiAutomation == null) || (mUiAutomation.isDestroyed())) {
- return getUiAutomation(0);
- }
- return mUiAutomation;
+ return getUiAutomation(0);
}
/**
* Gets the {@link UiAutomation} instance with flags set.
* <p>
- * <strong>Note:</strong> Only one UiAutomation can be obtained. Calling this method
- * twice with different flags will fail unless the UiAutomation obtained in the first call
- * is released with {@link UiAutomation#destroy()}.
- * </p>
- * <p>
* <strong>Note:</strong> The APIs exposed via the returned {@link UiAutomation}
* work across application boundaries while the APIs exposed by the instrumentation
* do not. For example, {@link Instrumentation#sendPointerSync(MotionEvent)} will
@@ -1879,6 +1875,10 @@
* {@link Instrumentation} APIs. Using both APIs at the same time is not
* a mistake by itself but a client has to be aware of the APIs limitations.
* </p>
+ * <p>
+ * If a {@link UiAutomation} exists with different flags, the flags on that instance will be
+ * changed, and then it will be returned.
+ * </p>
*
* @param flags The flags to be passed to the UiAutomation, for example
* {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES}.
@@ -1888,17 +1888,19 @@
* @see UiAutomation
*/
public UiAutomation getUiAutomation(@UiAutomationFlags int flags) {
+ boolean mustCreateNewAutomation = (mUiAutomation == null) || (mUiAutomation.isDestroyed());
+
if (mUiAutomationConnection != null) {
- if ((mUiAutomation == null) || (mUiAutomation.isDestroyed())) {
+ if (!mustCreateNewAutomation && (mUiAutomation.getFlags() == flags)) {
+ return mUiAutomation;
+ }
+ if (mustCreateNewAutomation) {
mUiAutomation = new UiAutomation(getTargetContext().getMainLooper(),
mUiAutomationConnection);
- mUiAutomation.connect(flags);
} else {
- if (mUiAutomation.getFlags() != flags) {
- throw new RuntimeException(
- "Cannot get a UiAutomation with different flags from the existing one");
- }
+ mUiAutomation.disconnect();
}
+ mUiAutomation.connect(flags);
return mUiAutomation;
}
return null;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 65e9f10..4bf1aa3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -496,6 +497,15 @@
*/
public static final int FLAG_GROUP_SUMMARY = 0x00000200;
+ /**
+ * Bit to be bitswise-ored into the {@link #flags} field that should be
+ * set if this notification is the group summary for an auto-group of notifications.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_AUTOGROUP_SUMMARY = 0x00000400;
+
public int flags;
/** @hide */
@@ -904,6 +914,34 @@
public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
/**
+ * {@link #extras} key: the username to be displayed for all messages sent by the user including
+ * direct replies
+ * {@link android.app.Notification.MessagingStyle} notification.
+ */
+ public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+
+ /**
+ * {@link #extras} key: a boolean describing whether the platform should automatically
+ * generate possible replies to
+ * {@link android.app.Notification.MessagingStyle.Message} objects provided by a
+ * {@link android.app.Notification.MessagingStyle} notification.
+ */
+ public static final String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
+
+ /**
+ * {@link #extras} key: a {@link String} to be displayed as the title to a thread represented by
+ * a {@link android.app.Notification.MessagingStyle}
+ */
+ public static final String EXTRA_THREAD_TITLE = "android.threadTitle";
+
+ /**
+ * {@link #extras} key: an array of {@link android.app.Notification.MessagingStyle.Message}
+ * bundles provided by a
+ * {@link android.app.Notification.MessagingStyle} notification.
+ */
+ public static final String EXTRA_MESSAGES = "android.messages";
+
+ /**
* {@link #extras} key: the user that built the notification.
*
* @hide
@@ -1210,6 +1248,7 @@
// Flags bitwise-ored to mFlags
private static final int FLAG_AVAILABLE_OFFLINE = 0x1;
+ private static final int FLAG_HINT_LAUNCHES_ACTIVITY = 1 << 1;
// Default value for flags integer
private static final int DEFAULT_FLAGS = FLAG_AVAILABLE_OFFLINE;
@@ -1372,6 +1411,30 @@
public CharSequence getCancelLabel() {
return mCancelLabel;
}
+
+ /**
+ * Set a hint that this Action will launch an {@link Activity} directly, telling the
+ * platform that it can generate the appropriate transitions.
+ * @param hintLaunchesActivity {@code true} if the content intent will launch
+ * an activity and transitions should be generated, false otherwise.
+ * @return this object for method chaining
+ */
+ public WearableExtender setHintContentIntentLaunchesActivity(
+ boolean hintLaunchesActivity) {
+ setFlag(FLAG_HINT_LAUNCHES_ACTIVITY, hintLaunchesActivity);
+ return this;
+ }
+
+ /**
+ * Get a hint that this Action will launch an {@link Activity} directly, telling the
+ * platform that it can generate the appropriate transitions
+ * @return {@code true} if the content intent will launch an activity and transitions
+ * should be generated, false otherwise. The default value is {@code false} if this was
+ * never set.
+ */
+ public boolean getHintContentIntentLaunchesActivity() {
+ return (mFlags & FLAG_HINT_LAUNCHES_ACTIVITY) != 0;
+ }
}
}
@@ -1892,13 +1955,9 @@
* @hide
*/
public static void addFieldsFromContext(Context context, Notification notification) {
- if (notification.extras.getParcelable(EXTRA_BUILDER_APPLICATION_INFO) == null) {
- notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO,
- context.getApplicationInfo());
- }
- if (!notification.extras.containsKey(EXTRA_ORIGINATING_USERID)) {
- notification.extras.putInt(EXTRA_ORIGINATING_USERID, context.getUserId());
- }
+ notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO,
+ context.getApplicationInfo());
+ notification.extras.putInt(EXTRA_ORIGINATING_USERID, context.getUserId());
}
@Override
@@ -2967,12 +3026,13 @@
/**
* @hide
*/
- public void setFlag(int mask, boolean value) {
+ public Builder setFlag(int mask, boolean value) {
if (value) {
mN.flags |= mask;
} else {
mN.flags &= ~mask;
}
+ return this;
}
/**
@@ -3535,7 +3595,8 @@
private static Class<? extends Style> getNotificationStyleClass(String templateClass) {
Class<? extends Style>[] classes = new Class[] {
BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
- DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class };
+ DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
+ MessagingStyle.class };
for (Class<? extends Style> innerClass : classes) {
if (templateClass.equals(innerClass.getName())) {
return innerClass;
@@ -4132,6 +4193,350 @@
}
/**
+ * Helper class for generating large-format notifications that include multiple back-and-forth
+ * messages of varying types between any number of people.
+ *
+ * <br>
+ * If the platform does not provide large-format notifications, this method has no effect. The
+ * user will always see the normal notification view.
+ * <br>
+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like
+ * so:
+ * <pre class="prettyprint">
+ *
+ * Notification noti = new Notification.Builder()
+ * .setContentTitle("2 new messages wtih " + sender.toString())
+ * .setContentText(subject)
+ * .setSmallIcon(R.drawable.new_message)
+ * .setLargeIcon(aBitmap)
+ * .setStyle(new Notification.MessagingStyle(resources.getString(R.string.reply_name))
+ * .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender())
+ * .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender()))
+ * .build();
+ * </pre>
+ */
+ public static class MessagingStyle extends Style {
+
+ /**
+ * The maximum number of messages that will be retained in the Notification itself (the
+ * number displayed is up to the platform).
+ */
+ public static final int MAXIMUM_RETAINED_MESSAGES = 25;
+
+ CharSequence mUserDisplayName;
+ CharSequence mConversationTitle;
+ boolean mAllowGeneratedReplies = true;
+ ArrayList<Message> mMessages = new ArrayList<>();
+
+ MessagingStyle() {
+ }
+
+ /**
+ * @param userDisplayName the name to be displayed for any replies sent by the user before the
+ * posting app reposts the notification with those messages after they've been actually
+ * sent and in previous messages sent by the user added in
+ * {@link #addMessage(Notification.MessagingStyle.Message)}
+ */
+ public MessagingStyle(CharSequence userDisplayName) {
+ mUserDisplayName = userDisplayName;
+ }
+
+ /**
+ * Returns the name to be displayed for any replies sent by the user
+ */
+ public CharSequence getUserDisplayName() {
+ return mUserDisplayName;
+ }
+
+ /**
+ * Set whether the platform should automatically generate possible replies from messages.
+ * @param allowGeneratedReplies {@code true} to allow generated replies, {@code false}
+ * otherwise
+ * @return this object for method chaining
+ * The default value is {@code true}
+ */
+ public MessagingStyle setAllowGeneratedReplies(boolean allowGeneratedReplies) {
+ mAllowGeneratedReplies = allowGeneratedReplies;
+ return this;
+ }
+
+ /**
+ * Return whether the platform should automatically generate possible replies from messages.
+ */
+ public boolean getAllowGeneratedReplies() {
+ return mAllowGeneratedReplies;
+ }
+
+ /**
+ * Sets the title to be displayed on this conversation. This should only be used for
+ * group messaging and left unset for one-on-one conversations.
+ * @param conversationTitle
+ * @return this object for method chaining.
+ */
+ public MessagingStyle setConversationTitle(CharSequence conversationTitle) {
+ mConversationTitle = conversationTitle;
+ return this;
+ }
+
+ /**
+ * Return the title to be displayed on this conversation. Can be <code>null</code> and
+ * should be for one-on-one conversations
+ */
+ public CharSequence getConversationTitle() {
+ return mConversationTitle;
+ }
+
+ /**
+ * Adds a message for display by this notification. Convenience call for a simple
+ * {@link Message} in {@link #addMessage(Notification.MessagingStyle.Message)}.
+ * @param text A {@link CharSequence} to be displayed as the message content
+ * @param timestamp Time at which the message arrived
+ * @param sender A {@link CharSequence} to be used for displaying the name of the
+ * sender. Should be <code>null</code> for messages by the current user, in which case
+ * the platform will insert {@link #getUserDisplayName()}.
+ * Should be unique amongst all individuals in the conversation, and should be
+ * consistent during re-posts of the notification.
+ *
+ * @see Message#Message(CharSequence, long, CharSequence)
+ *
+ * @return this object for method chaining
+ */
+ public MessagingStyle addMessage(CharSequence text, long timestamp, CharSequence sender) {
+ mMessages.add(new Message(text, timestamp, sender));
+ if (mMessages.size() > MAXIMUM_RETAINED_MESSAGES) {
+ mMessages.remove(0);
+ }
+ return this;
+ }
+
+ /**
+ * Adds a {@link Message} for display in this notification.
+ * @param message The {@link Message} to be displayed
+ * @return this object for method chaining
+ */
+ public MessagingStyle addMessage(Message message) {
+ mMessages.add(message);
+ if (mMessages.size() > MAXIMUM_RETAINED_MESSAGES) {
+ mMessages.remove(0);
+ }
+ return this;
+ }
+
+ /**
+ * Gets the list of {@code Message} objects that represent the notification
+ */
+ public List<Message> getMessages() {
+ return mMessages;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void addExtras(Bundle extras) {
+ super.addExtras(extras);
+ if (mUserDisplayName != null) {
+ extras.putCharSequence(EXTRA_SELF_DISPLAY_NAME, mUserDisplayName);
+ }
+ if (mConversationTitle != null) {
+ extras.putCharSequence(EXTRA_THREAD_TITLE, mConversationTitle);
+ }
+ extras.putBoolean(EXTRA_ALLOW_GENERATED_REPLIES, mAllowGeneratedReplies);
+ if (!mMessages.isEmpty()) {
+ extras.putParcelableArrayList(EXTRA_MESSAGES, mMessages);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected void restoreFromExtras(Bundle extras) {
+ super.restoreFromExtras(extras);
+
+ mMessages.clear();
+ mUserDisplayName = extras.getString(EXTRA_SELF_DISPLAY_NAME);
+ mConversationTitle = extras.getString(EXTRA_THREAD_TITLE);
+ mAllowGeneratedReplies = extras.getBoolean(EXTRA_ALLOW_GENERATED_REPLIES,
+ mAllowGeneratedReplies);
+ List<Message> messages = extras.getParcelableArrayList(EXTRA_MESSAGES);
+ if (messages != null) {
+ mMessages.addAll(messages);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public RemoteViews makeBigContentView() {
+ // TODO handset to write implementation
+ RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
+
+ return contentView;
+ }
+
+ public static final class Message implements Parcelable {
+
+ private final CharSequence mText;
+ private final long mTimestamp;
+ private final CharSequence mSender;
+
+ private String mDataMimeType;
+ private Uri mDataUri;
+
+ /**
+ * Constructor
+ * @param text A {@link CharSequence} to be displayed as the message content
+ * @param timestamp Time at which the message arrived
+ * @param sender A {@link CharSequence} to be used for displaying the name of the
+ * sender. Should be <code>null</code> for messages by the current user, in which case
+ * the platform will insert {@link MessagingStyle#getUserDisplayName()}.
+ * Should be unique amongst all individuals in the conversation, and should be
+ * consistent during re-posts of the notification.
+ */
+ public Message(CharSequence text, long timestamp, CharSequence sender){
+ mText = text;
+ mTimestamp = timestamp;
+ mSender = sender;
+ }
+
+ /**
+ * Sets a binary blob of data and an associated MIME type for a message. In the case
+ * where the platform doesn't support the MIME type, the original text provided in the
+ * constructor will be used.
+ * @param dataMimeType The MIME type of the content. See
+ * <a href="{@docRoot}notifications/messaging.html"> for the list of supported MIME
+ * types on Android and Android Wear.
+ * @param dataUri The uri containing the content whose type is given by the MIME type.
+ * <p class="note">
+ * <ol>
+ * <li>Notification Listeners including the System UI need permission to access the
+ * data the Uri points to. The recommended ways to do this are:</li>
+ * <li>Store the data in your own ContentProvider, making sure that other apps have
+ * the correct permission to access your provider. The preferred mechanism for
+ * providing access is to use per-URI permissions which are temporary and only
+ * grant access to the receiving application. An easy way to create a
+ * ContentProvider like this is to use the FileProvider helper class.</li>
+ * <li>Use the system MediaStore. The MediaStore is primarily aimed at video, audio
+ * and image MIME types, however beginning with Android 3.0 (API level 11) it can
+ * also store non-media types (see MediaStore.Files for more info). Files can be
+ * inserted into the MediaStore using scanFile() after which a content:// style
+ * Uri suitable for sharing is passed to the provided onScanCompleted() callback.
+ * Note that once added to the system MediaStore the content is accessible to any
+ * app on the device.</li>
+ * </ol>
+ * @return this object for method chaining
+ */
+ public Message setData(String dataMimeType, Uri dataUri) {
+ mDataMimeType = dataMimeType;
+ mDataUri = dataUri;
+ return this;
+ }
+
+ private Message(Parcel in) {
+ if (in.readInt() != 0) {
+ mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ } else {
+ mText = null;
+ }
+ mTimestamp = in.readLong();
+ if (in.readInt() != 0) {
+ mSender = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ } else {
+ mSender = null;
+ }
+ if (in.readInt() != 0) {
+ mDataMimeType = in.readString();
+ }
+ if (in.readInt() != 0) {
+ mDataUri = in.readParcelable(Uri.class.getClassLoader());
+ }
+ }
+
+ /**
+ * Get the text to be used for this message, or the fallback text if a type and content
+ * Uri have been set
+ */
+ public CharSequence getText() {
+ return mText;
+ }
+
+ /**
+ * Get the time at which this message arrived
+ */
+ public long getTimestamp() {
+ return mTimestamp;
+ }
+
+ /**
+ * Get the text used to display the contact's name in the messaging experience
+ */
+ public CharSequence getSender() {
+ return mSender;
+ }
+
+ /**
+ * Get the MIME type of the data pointed to by the Uri
+ */
+ public String getDataMimeType() {
+ return mDataMimeType;
+ }
+
+ /**
+ * Get the the Uri pointing to the content of the message. Can be null, in which case
+ * {@see #getText()} is used.
+ */
+ public Uri getDataUri() {
+ return mDataUri;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ if (mText != null) {
+ out.writeInt(1);
+ TextUtils.writeToParcel(mText, out, flags);
+ } else {
+ out.writeInt(0);
+ }
+ out.writeLong(mTimestamp);
+ if (mSender != null) {
+ out.writeInt(1);
+ TextUtils.writeToParcel(mSender, out, flags);
+ } else {
+ out.writeInt(0);
+ }
+ if (mDataMimeType != null) {
+ out.writeInt(1);
+ out.writeString(mDataMimeType);
+ } else {
+ out.writeInt(0);
+ }
+ if (mDataUri != null) {
+ out.writeInt(1);
+ out.writeParcelable(mDataUri, flags);
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ public static final Parcelable.Creator<Message> CREATOR =
+ new Parcelable.Creator<Message>() {
+ public Message createFromParcel(Parcel in) {
+ return new Message(in);
+ }
+ public Message[] newArray(int size) {
+ return new Message[size];
+ }
+ };
+ }
+ }
+
+ /**
* Helper class for generating large-format notifications that include a list of (up to 5) strings.
*
* Here's how you'd set the <code>InboxStyle</code> on a notification:
@@ -4869,6 +5274,7 @@
private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
private static final int FLAG_HINT_AVOID_BACKGROUND_CLIPPING = 1 << 4;
+ private static final int FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY = 1 << 6;
// Default value for flags integer
private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE;
@@ -5435,6 +5841,29 @@
return mHintScreenTimeout;
}
+ /**
+ * Set a hint that this notification's content intent will launch an {@link Activity}
+ * directly, telling the platform that it can generate the appropriate transitions.
+ * @param hintContentIntentLaunchesActivity {@code true} if the content intent will launch
+ * an activity and transitions should be generated, false otherwise.
+ * @return this object for method chaining
+ */
+ public WearableExtender setHintContentIntentLaunchesActivity(
+ boolean hintContentIntentLaunchesActivity) {
+ setFlag(FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY, hintContentIntentLaunchesActivity);
+ return this;
+ }
+
+ /**
+ * Get a hint that this notification's content intent will launch an {@link Activity}
+ * directly, telling the platform that it can generate the appropriate transitions
+ * @return {@code true} if the content intent will launch an activity and transitions should
+ * be generated, false otherwise. The default value is {@code false} if this was never set.
+ */
+ public boolean getHintContentIntentLaunchesActivity() {
+ return (mFlags & FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY) != 0;
+ }
+
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f15b8fe..3f9629c8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2216,9 +2216,7 @@
* that uses {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD}
*/
public boolean resetPassword(String password, int flags) {
- if (mParentInstance) {
- throw new SecurityException("Reset password does not work across profiles.");
- }
+ throwIfParentInstance("resetPassword");
if (mService != null) {
try {
return mService.resetPassword(password, flags);
@@ -2288,6 +2286,23 @@
}
/**
+ * Returns maximum time to lock that applied by all profiles in this user. We do this because we
+ * do not have a separate timeout to lock for work challenge only.
+ *
+ * @hide
+ */
+ public long getMaximumTimeToLockForUserAndProfiles(int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getMaximumTimeToLockForUserAndProfiles(userHandle);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return 0;
+ }
+
+ /**
* Make the device lock immediately, as if the lock screen timeout has expired at the point of
* this call.
* <p>
@@ -2338,6 +2353,7 @@
* that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
*/
public void wipeData(int flags) {
+ throwIfParentInstance("wipeData");
if (mService != null) {
try {
mService.wipeData(flags);
@@ -2371,6 +2387,7 @@
*/
public ComponentName setGlobalProxy(@NonNull ComponentName admin, Proxy proxySpec,
List<String> exclusionList ) {
+ throwIfParentInstance("setGlobalProxy");
if (proxySpec == null) {
throw new NullPointerException();
}
@@ -2436,6 +2453,7 @@
*/
public void setRecommendedGlobalProxy(@NonNull ComponentName admin, @Nullable ProxyInfo
proxyInfo) {
+ throwIfParentInstance("setRecommendedGlobalProxy");
if (mService != null) {
try {
mService.setRecommendedGlobalProxy(admin, proxyInfo);
@@ -2586,6 +2604,7 @@
* {@link DeviceAdminInfo#USES_ENCRYPTED_STORAGE}
*/
public int setStorageEncryption(@NonNull ComponentName admin, boolean encrypt) {
+ throwIfParentInstance("setStorageEncryption");
if (mService != null) {
try {
return mService.setStorageEncryption(admin, encrypt);
@@ -2606,6 +2625,7 @@
* @return true if the admin(s) are requesting encryption, false if not.
*/
public boolean getStorageEncryption(@Nullable ComponentName admin) {
+ throwIfParentInstance("getStorageEncryption");
if (mService != null) {
try {
return mService.getStorageEncryption(admin, myUserId());
@@ -2701,6 +2721,7 @@
* owner.
*/
public boolean installCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
+ throwIfParentInstance("installCaCert");
if (mService != null) {
try {
return mService.installCaCert(admin, certBuffer);
@@ -2721,6 +2742,7 @@
* owner.
*/
public void uninstallCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
+ throwIfParentInstance("uninstallCaCert");
if (mService != null) {
try {
final String alias = getCaCertAlias(certBuffer);
@@ -2746,6 +2768,7 @@
*/
public List<byte[]> getInstalledCaCerts(@Nullable ComponentName admin) {
List<byte[]> certs = new ArrayList<byte[]>();
+ throwIfParentInstance("getInstalledCaCerts");
if (mService != null) {
try {
mService.enforceCanManageCaCerts(admin);
@@ -2774,6 +2797,7 @@
* owner.
*/
public void uninstallAllUserCaCerts(@Nullable ComponentName admin) {
+ throwIfParentInstance("uninstallAllUserCaCerts");
if (mService != null) {
try {
mService.uninstallCaCerts(admin, new TrustedCertificateStore().userAliases()
@@ -2794,6 +2818,7 @@
* owner.
*/
public boolean hasCaCertInstalled(@Nullable ComponentName admin, byte[] certBuffer) {
+ throwIfParentInstance("hasCaCertInstalled");
if (mService != null) {
try {
mService.enforceCanManageCaCerts(admin);
@@ -2862,6 +2887,7 @@
*/
public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
@NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess) {
+ throwIfParentInstance("installKeyPair");
try {
final byte[] pemCert = Credentials.convertToPem(certs[0]);
byte[] pemChain = null;
@@ -2894,6 +2920,7 @@
* owner.
*/
public boolean removeKeyPair(@Nullable ComponentName admin, @NonNull String alias) {
+ throwIfParentInstance("removeKeyPair");
try {
return mService.removeKeyPair(admin, alias);
} catch (RemoteException e) {
@@ -2934,6 +2961,7 @@
*/
public void setCertInstallerPackage(@NonNull ComponentName admin, @Nullable String
installerPackage) throws SecurityException {
+ throwIfParentInstance("setCertInstallerPackage");
if (mService != null) {
try {
mService.setCertInstallerPackage(admin, installerPackage);
@@ -2953,6 +2981,7 @@
* @throws SecurityException if {@code admin} is not a device or a profile owner.
*/
public String getCertInstallerPackage(@NonNull ComponentName admin) throws SecurityException {
+ throwIfParentInstance("getCertInstallerPackage");
if (mService != null) {
try {
return mService.getCertInstallerPackage(admin);
@@ -2983,6 +3012,7 @@
*/
public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage)
throws NameNotFoundException, UnsupportedOperationException {
+ throwIfParentInstance("setAlwaysOnVpnPackage");
if (mService != null) {
try {
if (!mService.setAlwaysOnVpnPackage(admin, vpnPackage)) {
@@ -3004,6 +3034,7 @@
* @throws SecurityException if {@code admin} is not a device or a profile owner.
*/
public String getAlwaysOnVpnPackage(@NonNull ComponentName admin) {
+ throwIfParentInstance("getAlwaysOnVpnPackage");
if (mService != null) {
try {
return mService.getAlwaysOnVpnPackage(admin);
@@ -3031,6 +3062,7 @@
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA}.
*/
public void setCameraDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setCameraDisabled");
if (mService != null) {
try {
mService.setCameraDisabled(admin, disabled);
@@ -3047,6 +3079,7 @@
* have disabled the camera
*/
public boolean getCameraDisabled(@Nullable ComponentName admin) {
+ throwIfParentInstance("getCameraDisabled");
return getCameraDisabled(admin, myUserId());
}
@@ -3076,6 +3109,7 @@
* than the one managed by the device owner.
*/
public boolean requestBugreport(@NonNull ComponentName admin) {
+ throwIfParentInstance("requestBugreport");
if (mService != null) {
try {
return mService.requestBugreport(admin);
@@ -3114,6 +3148,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setScreenCaptureDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setScreenCaptureDisabled");
if (mService != null) {
try {
mService.setScreenCaptureDisabled(admin, disabled);
@@ -3130,6 +3165,7 @@
* have disabled screen capture.
*/
public boolean getScreenCaptureDisabled(@Nullable ComponentName admin) {
+ throwIfParentInstance("getScreenCaptureDisabled");
return getScreenCaptureDisabled(admin, myUserId());
}
@@ -3159,6 +3195,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public void setAutoTimeRequired(@NonNull ComponentName admin, boolean required) {
+ throwIfParentInstance("setAutoTimeRequired");
if (mService != null) {
try {
mService.setAutoTimeRequired(admin, required);
@@ -3172,6 +3209,7 @@
* @return true if auto time is required.
*/
public boolean getAutoTimeRequired() {
+ throwIfParentInstance("getAutoTimeRequired");
if (mService != null) {
try {
return mService.getAutoTimeRequired();
@@ -3198,6 +3236,7 @@
*/
public void setForceEphemeralUsers(
@NonNull ComponentName admin, boolean forceEphemeralUsers) {
+ throwIfParentInstance("setForceEphemeralUsers");
if (mService != null) {
try {
mService.setForceEphemeralUsers(admin, forceEphemeralUsers);
@@ -3213,6 +3252,7 @@
* @hide
*/
public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
+ throwIfParentInstance("getForceEphemeralUsers");
if (mService != null) {
try {
return mService.getForceEphemeralUsers(admin);
@@ -3500,6 +3540,7 @@
* @return whether or not the package is registered as the device owner app.
*/
public boolean isDeviceOwnerApp(String packageName) {
+ throwIfParentInstance("isDeviceOwnerApp");
return isDeviceOwnerAppOnCallingUser(packageName);
}
@@ -3597,6 +3638,7 @@
* does not own the current device owner component.
*/
public void clearDeviceOwnerApp(String packageName) {
+ throwIfParentInstance("clearDeviceOwnerApp");
if (mService != null) {
try {
mService.clearDeviceOwner(packageName);
@@ -3714,6 +3756,7 @@
* @throws SecurityException if {@code admin} is not an active profile owner.
*/
public void clearProfileOwner(@NonNull ComponentName admin) {
+ throwIfParentInstance("clearProfileOwner");
if (mService != null) {
try {
mService.clearProfileOwner(admin);
@@ -3787,6 +3830,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public void setDeviceOwnerLockScreenInfo(@NonNull ComponentName admin, CharSequence info) {
+ throwIfParentInstance("setDeviceOwnerLockScreenInfo");
if (mService != null) {
try {
mService.setDeviceOwnerLockScreenInfo(admin, info);
@@ -3800,6 +3844,7 @@
* @return The device owner information. If it is not set returns {@code null}.
*/
public CharSequence getDeviceOwnerLockScreenInfo() {
+ throwIfParentInstance("getDeviceOwnerLockScreenInfo");
if (mService != null) {
try {
return mService.getDeviceOwnerLockScreenInfo();
@@ -3831,6 +3876,7 @@
*/
public String[] setPackagesSuspended(@NonNull ComponentName admin, String[] packageNames,
boolean suspended) {
+ throwIfParentInstance("setPackagesSuspended");
if (mService != null) {
try {
return mService.setPackagesSuspended(admin, packageNames, suspended);
@@ -3853,6 +3899,7 @@
*/
public boolean isPackageSuspended(@NonNull ComponentName admin, String packageName)
throws NameNotFoundException {
+ throwIfParentInstance("isPackageSuspended");
if (mService != null) {
try {
return mService.isPackageSuspended(admin, packageName);
@@ -3874,6 +3921,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public void setProfileEnabled(@NonNull ComponentName admin) {
+ throwIfParentInstance("setProfileEnabled");
if (mService != null) {
try {
mService.setProfileEnabled(admin);
@@ -3895,6 +3943,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setProfileName(@NonNull ComponentName admin, String profileName) {
+ throwIfParentInstance("setProfileName");
if (mService != null) {
try {
mService.setProfileName(admin, profileName);
@@ -3913,6 +3962,7 @@
* @return Whether or not the package is registered as the profile owner.
*/
public boolean isProfileOwnerApp(String packageName) {
+ throwIfParentInstance("isProfileOwnerApp");
if (mService != null) {
try {
ComponentName profileOwner = mService.getProfileOwner(myUserId());
@@ -4007,6 +4057,7 @@
*/
public void addPersistentPreferredActivity(@NonNull ComponentName admin, IntentFilter filter,
@NonNull ComponentName activity) {
+ throwIfParentInstance("addPersistentPreferredActivity");
if (mService != null) {
try {
mService.addPersistentPreferredActivity(admin, filter, activity);
@@ -4029,6 +4080,7 @@
*/
public void clearPackagePersistentPreferredActivities(@NonNull ComponentName admin,
String packageName) {
+ throwIfParentInstance("clearPackagePersistentPreferredActivities");
if (mService != null) {
try {
mService.clearPackagePersistentPreferredActivities(admin, packageName);
@@ -4057,6 +4109,7 @@
*/
public void setApplicationRestrictionsManagingPackage(@NonNull ComponentName admin,
@Nullable String packageName) throws NameNotFoundException {
+ throwIfParentInstance("setApplicationRestrictionsManagingPackage");
if (mService != null) {
try {
if (!mService.setApplicationRestrictionsManagingPackage(admin, packageName)) {
@@ -4078,6 +4131,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public String getApplicationRestrictionsManagingPackage(@NonNull ComponentName admin) {
+ throwIfParentInstance("getApplicationRestrictionsManagingPackage");
if (mService != null) {
try {
return mService.getApplicationRestrictionsManagingPackage(admin);
@@ -4097,6 +4151,7 @@
* that method.
*/
public boolean isCallerApplicationRestrictionsManagingPackage() {
+ throwIfParentInstance("isCallerApplicationRestrictionsManagingPackage");
if (mService != null) {
try {
return mService.isCallerApplicationRestrictionsManagingPackage();
@@ -4142,6 +4197,7 @@
*/
public void setApplicationRestrictions(@Nullable ComponentName admin, String packageName,
Bundle settings) {
+ throwIfParentInstance("setApplicationRestrictions");
if (mService != null) {
try {
mService.setApplicationRestrictions(admin, packageName, settings);
@@ -4240,6 +4296,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setCrossProfileCallerIdDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setCrossProfileCallerIdDisabled");
if (mService != null) {
try {
mService.setCrossProfileCallerIdDisabled(admin, disabled);
@@ -4260,6 +4317,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean getCrossProfileCallerIdDisabled(@NonNull ComponentName admin) {
+ throwIfParentInstance("getCrossProfileCallerIdDisabled");
if (mService != null) {
try {
return mService.getCrossProfileCallerIdDisabled(admin);
@@ -4300,6 +4358,7 @@
*/
public void setCrossProfileContactsSearchDisabled(@NonNull ComponentName admin,
boolean disabled) {
+ throwIfParentInstance("setCrossProfileContactsSearchDisabled");
if (mService != null) {
try {
mService.setCrossProfileContactsSearchDisabled(admin, disabled);
@@ -4320,6 +4379,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean getCrossProfileContactsSearchDisabled(@NonNull ComponentName admin) {
+ throwIfParentInstance("getCrossProfileContactsSearchDisabled");
if (mService != null) {
try {
return mService.getCrossProfileContactsSearchDisabled(admin);
@@ -4390,6 +4450,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setBluetoothContactSharingDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setBluetoothContactSharingDisabled");
if (mService != null) {
try {
mService.setBluetoothContactSharingDisabled(admin, disabled);
@@ -4412,6 +4473,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean getBluetoothContactSharingDisabled(@NonNull ComponentName admin) {
+ throwIfParentInstance("getBluetoothContactSharingDisabled");
if (mService != null) {
try {
return mService.getBluetoothContactSharingDisabled(admin);
@@ -4455,6 +4517,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void addCrossProfileIntentFilter(@NonNull ComponentName admin, IntentFilter filter, int flags) {
+ throwIfParentInstance("addCrossProfileIntentFilter");
if (mService != null) {
try {
mService.addCrossProfileIntentFilter(admin, filter, flags);
@@ -4473,6 +4536,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void clearCrossProfileIntentFilters(@NonNull ComponentName admin) {
+ throwIfParentInstance("clearCrossProfileIntentFilters");
if (mService != null) {
try {
mService.clearCrossProfileIntentFilters(admin);
@@ -4502,6 +4566,7 @@
*/
public boolean setPermittedAccessibilityServices(@NonNull ComponentName admin,
List<String> packageNames) {
+ throwIfParentInstance("setPermittedAccessibilityServices");
if (mService != null) {
try {
return mService.setPermittedAccessibilityServices(admin, packageNames);
@@ -4523,6 +4588,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public List<String> getPermittedAccessibilityServices(@NonNull ComponentName admin) {
+ throwIfParentInstance("getPermittedAccessibilityServices");
if (mService != null) {
try {
return mService.getPermittedAccessibilityServices(admin);
@@ -4600,6 +4666,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean setPermittedInputMethods(@NonNull ComponentName admin, List<String> packageNames) {
+ throwIfParentInstance("setPermittedInputMethods");
if (mService != null) {
try {
return mService.setPermittedInputMethods(admin, packageNames);
@@ -4622,6 +4689,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public List<String> getPermittedInputMethods(@NonNull ComponentName admin) {
+ throwIfParentInstance("getPermittedInputMethods");
if (mService != null) {
try {
return mService.getPermittedInputMethods(admin);
@@ -4817,6 +4885,7 @@
public UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name,
@NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras,
int flags) {
+ throwIfParentInstance("createAndManageUser");
try {
return mService.createAndManageUser(admin, name, profileOwner, adminExtras, flags);
} catch (RemoteException re) {
@@ -4834,6 +4903,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) {
+ throwIfParentInstance("removeUser");
try {
return mService.removeUser(admin, userHandle);
} catch (RemoteException re) {
@@ -4851,6 +4921,7 @@
* @see Intent#ACTION_USER_FOREGROUND
*/
public boolean switchUser(@NonNull ComponentName admin, @Nullable UserHandle userHandle) {
+ throwIfParentInstance("switchUser");
try {
return mService.switchUser(admin, userHandle);
} catch (RemoteException re) {
@@ -4876,6 +4947,7 @@
* @see {@link #setApplicationRestrictionsManagingPackage}
*/
public Bundle getApplicationRestrictions(@Nullable ComponentName admin, String packageName) {
+ throwIfParentInstance("getApplicationRestrictions");
if (mService != null) {
try {
return mService.getApplicationRestrictions(admin, packageName);
@@ -4898,6 +4970,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void addUserRestriction(@NonNull ComponentName admin, String key) {
+ throwIfParentInstance("addUserRestriction");
if (mService != null) {
try {
mService.setUserRestriction(admin, key, true);
@@ -4919,6 +4992,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void clearUserRestriction(@NonNull ComponentName admin, String key) {
+ throwIfParentInstance("clearUserRestriction");
if (mService != null) {
try {
mService.setUserRestriction(admin, key, false);
@@ -4940,6 +5014,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public Bundle getUserRestrictions(@NonNull ComponentName admin) {
+ throwIfParentInstance("getUserRestrictions");
Bundle ret = null;
if (mService != null) {
try {
@@ -4984,6 +5059,7 @@
*/
public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName,
boolean hidden) {
+ throwIfParentInstance("setApplicationHidden");
if (mService != null) {
try {
return mService.setApplicationHidden(admin, packageName, hidden);
@@ -5003,6 +5079,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) {
+ throwIfParentInstance("isApplicationHidden");
if (mService != null) {
try {
return mService.isApplicationHidden(admin, packageName);
@@ -5022,6 +5099,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void enableSystemApp(@NonNull ComponentName admin, String packageName) {
+ throwIfParentInstance("enableSystemApp");
if (mService != null) {
try {
mService.enableSystemApp(admin, packageName);
@@ -5042,6 +5120,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public int enableSystemApp(@NonNull ComponentName admin, Intent intent) {
+ throwIfParentInstance("enableSystemApp");
if (mService != null) {
try {
return mService.enableSystemAppWithIntent(admin, intent);
@@ -5074,6 +5153,7 @@
*/
public void setAccountManagementDisabled(@NonNull ComponentName admin, String accountType,
boolean disabled) {
+ throwIfParentInstance("setAccountManagementDisabled");
if (mService != null) {
try {
mService.setAccountManagementDisabled(admin, accountType, disabled);
@@ -5094,6 +5174,7 @@
* @see #setAccountManagementDisabled
*/
public String[] getAccountTypesWithManagementDisabled() {
+ throwIfParentInstance("getAccountTypesWithManagementDisabled");
return getAccountTypesWithManagementDisabledAsUser(myUserId());
}
@@ -5131,6 +5212,7 @@
*/
public void setLockTaskPackages(@NonNull ComponentName admin, String[] packages)
throws SecurityException {
+ throwIfParentInstance("setLockTaskPackages");
if (mService != null) {
try {
mService.setLockTaskPackages(admin, packages);
@@ -5147,6 +5229,7 @@
* @hide
*/
public String[] getLockTaskPackages(@NonNull ComponentName admin) {
+ throwIfParentInstance("getLockTaskPackages");
if (mService != null) {
try {
return mService.getLockTaskPackages(admin);
@@ -5163,6 +5246,7 @@
* @param pkg The package to check
*/
public boolean isLockTaskPermitted(String pkg) {
+ throwIfParentInstance("isLockTaskPermitted");
if (mService != null) {
try {
return mService.isLockTaskPermitted(pkg);
@@ -5211,6 +5295,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public void setGlobalSetting(@NonNull ComponentName admin, String setting, String value) {
+ throwIfParentInstance("setGlobalSetting");
if (mService != null) {
try {
mService.setGlobalSetting(admin, setting, value);
@@ -5243,6 +5328,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setSecureSetting(@NonNull ComponentName admin, String setting, String value) {
+ throwIfParentInstance("setSecureSetting");
if (mService != null) {
try {
mService.setSecureSetting(admin, setting, value);
@@ -5266,6 +5352,7 @@
*/
public void setRestrictionsProvider(@NonNull ComponentName admin,
@Nullable ComponentName provider) {
+ throwIfParentInstance("setRestrictionsProvider");
if (mService != null) {
try {
mService.setRestrictionsProvider(admin, provider);
@@ -5283,6 +5370,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setMasterVolumeMuted(@NonNull ComponentName admin, boolean on) {
+ throwIfParentInstance("setMasterVolumeMuted");
if (mService != null) {
try {
mService.setMasterVolumeMuted(admin, on);
@@ -5300,6 +5388,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean isMasterVolumeMuted(@NonNull ComponentName admin) {
+ throwIfParentInstance("isMasterVolumeMuted");
if (mService != null) {
try {
return mService.isMasterVolumeMuted(admin);
@@ -5320,6 +5409,7 @@
*/
public void setUninstallBlocked(@NonNull ComponentName admin, String packageName,
boolean uninstallBlocked) {
+ throwIfParentInstance("setUninstallBlocked");
if (mService != null) {
try {
mService.setUninstallBlocked(admin, packageName, uninstallBlocked);
@@ -5345,6 +5435,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public boolean isUninstallBlocked(@Nullable ComponentName admin, String packageName) {
+ throwIfParentInstance("isUninstallBlocked");
if (mService != null) {
try {
return mService.isUninstallBlocked(admin, packageName);
@@ -5372,6 +5463,7 @@
* @see #getCrossProfileWidgetProviders(android.content.ComponentName)
*/
public boolean addCrossProfileWidgetProvider(@NonNull ComponentName admin, String packageName) {
+ throwIfParentInstance("addCrossProfileWidgetProvider");
if (mService != null) {
try {
return mService.addCrossProfileWidgetProvider(admin, packageName);
@@ -5399,6 +5491,7 @@
*/
public boolean removeCrossProfileWidgetProvider(
@NonNull ComponentName admin, String packageName) {
+ throwIfParentInstance("removeCrossProfileWidgetProvider");
if (mService != null) {
try {
return mService.removeCrossProfileWidgetProvider(admin, packageName);
@@ -5420,6 +5513,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public List<String> getCrossProfileWidgetProviders(@NonNull ComponentName admin) {
+ throwIfParentInstance("getCrossProfileWidgetProviders");
if (mService != null) {
try {
List<String> providers = mService.getCrossProfileWidgetProviders(admin);
@@ -5441,6 +5535,7 @@
* @throws SecurityException if {@code admin} is not a device or profile owner.
*/
public void setUserIcon(@NonNull ComponentName admin, Bitmap icon) {
+ throwIfParentInstance("setUserIcon");
try {
mService.setUserIcon(admin, icon);
} catch (RemoteException re) {
@@ -5460,6 +5555,7 @@
* @see SystemUpdatePolicy
*/
public void setSystemUpdatePolicy(@NonNull ComponentName admin, SystemUpdatePolicy policy) {
+ throwIfParentInstance("setSystemUpdatePolicy");
if (mService != null) {
try {
mService.setSystemUpdatePolicy(admin, policy);
@@ -5475,6 +5571,7 @@
* @return The current policy object, or {@code null} if no policy is set.
*/
public SystemUpdatePolicy getSystemUpdatePolicy() {
+ throwIfParentInstance("getSystemUpdatePolicy");
if (mService != null) {
try {
return mService.getSystemUpdatePolicy();
@@ -5500,6 +5597,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean setKeyguardDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setKeyguardDisabled");
try {
return mService.setKeyguardDisabled(admin, disabled);
} catch (RemoteException re) {
@@ -5518,6 +5616,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean setStatusBarDisabled(@NonNull ComponentName admin, boolean disabled) {
+ throwIfParentInstance("setStatusBarDisabled");
try {
return mService.setStatusBarDisabled(admin, disabled);
} catch (RemoteException re) {
@@ -5563,6 +5662,7 @@
* @see #setPermissionGrantState
*/
public void setPermissionPolicy(@NonNull ComponentName admin, int policy) {
+ throwIfParentInstance("setPermissionPolicy");
try {
mService.setPermissionPolicy(admin, policy);
} catch (RemoteException re) {
@@ -5577,6 +5677,7 @@
* @return the current policy for future permission requests.
*/
public int getPermissionPolicy(ComponentName admin) {
+ throwIfParentInstance("getPermissionPolicy");
try {
return mService.getPermissionPolicy(admin);
} catch (RemoteException re) {
@@ -5613,6 +5714,7 @@
*/
public boolean setPermissionGrantState(@NonNull ComponentName admin, String packageName,
String permission, int grantState) {
+ throwIfParentInstance("setPermissionGrantState");
try {
return mService.setPermissionGrantState(admin, packageName, permission, grantState);
} catch (RemoteException re) {
@@ -5641,6 +5743,7 @@
*/
public int getPermissionGrantState(@NonNull ComponentName admin, String packageName,
String permission) {
+ throwIfParentInstance("getPermissionGrantState");
try {
return mService.getPermissionGrantState(admin, packageName, permission);
} catch (RemoteException re) {
@@ -5656,6 +5759,7 @@
* @throws IllegalArgumentException if the supplied action is not valid.
*/
public boolean isProvisioningAllowed(String action) {
+ throwIfParentInstance("isProvisioningAllowed");
try {
return mService.isProvisioningAllowed(action);
} catch (RemoteException re) {
@@ -5671,6 +5775,7 @@
* @return if this user is a managed profile of another user.
*/
public boolean isManagedProfile(@NonNull ComponentName admin) {
+ throwIfParentInstance("isManagedProfile");
try {
return mService.isManagedProfile(admin);
} catch (RemoteException re) {
@@ -5704,6 +5809,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public String getWifiMacAddress(@NonNull ComponentName admin) {
+ throwIfParentInstance("getWifiMacAddress");
try {
return mService.getWifiMacAddress(admin);
} catch (RemoteException re) {
@@ -5720,6 +5826,7 @@
* @see TelephonyManager#CALL_STATE_IDLE
*/
public void reboot(@NonNull ComponentName admin) {
+ throwIfParentInstance("reboot");
try {
mService.reboot(admin);
} catch (RemoteException re) {
@@ -5746,6 +5853,7 @@
*/
public void setShortSupportMessage(@NonNull ComponentName admin,
@Nullable String message) {
+ throwIfParentInstance("setShortSupportMessage");
if (mService != null) {
try {
mService.setShortSupportMessage(admin, message);
@@ -5764,6 +5872,7 @@
* @throws SecurityException if {@code admin} is not an active administrator.
*/
public String getShortSupportMessage(@NonNull ComponentName admin) {
+ throwIfParentInstance("getShortSupportMessage");
if (mService != null) {
try {
return mService.getShortSupportMessage(admin);
@@ -5790,6 +5899,7 @@
*/
public void setLongSupportMessage(@NonNull ComponentName admin,
@Nullable String message) {
+ throwIfParentInstance("setLongSupportMessage");
if (mService != null) {
try {
mService.setLongSupportMessage(admin, message);
@@ -5808,6 +5918,7 @@
* @throws SecurityException if {@code admin} is not an active administrator.
*/
public String getLongSupportMessage(@NonNull ComponentName admin) {
+ throwIfParentInstance("getLongSupportMessage");
if (mService != null) {
try {
return mService.getLongSupportMessage(admin);
@@ -5904,6 +6015,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
+ throwIfParentInstance("getParentProfileInstance");
try {
if (!mService.isManagedProfile(admin)) {
throw new SecurityException("The current user does not have a parent profile.");
@@ -5930,6 +6042,7 @@
* @see #retrieveSecurityLogs
*/
public void setSecurityLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
+ throwIfParentInstance("setSecurityLoggingEnabled");
try {
mService.setSecurityLoggingEnabled(admin, enabled);
} catch (RemoteException re) {
@@ -5948,6 +6061,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean isSecurityLoggingEnabled(@NonNull ComponentName admin) {
+ throwIfParentInstance("isSecurityLoggingEnabled");
try {
return mService.isSecurityLoggingEnabled(admin);
} catch (RemoteException re) {
@@ -5971,6 +6085,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) {
+ throwIfParentInstance("retrieveSecurityLogs");
try {
ParceledListSlice<SecurityEvent> list = mService.retrieveSecurityLogs(admin);
if (list != null) {
@@ -6016,6 +6131,7 @@
* @throws SecurityException if {@code admin} is not a device owner.
*/
public List<SecurityEvent> retrievePreRebootSecurityLogs(@NonNull ComponentName admin) {
+ throwIfParentInstance("retrievePreRebootSecurityLogs");
try {
ParceledListSlice<SecurityEvent> list = mService.retrievePreRebootSecurityLogs(admin);
return list.getList();
@@ -6037,6 +6153,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public void setOrganizationColor(@NonNull ComponentName admin, int color) {
+ throwIfParentInstance("setOrganizationColor");
try {
mService.setOrganizationColor(admin, color);
} catch (RemoteException re) {
@@ -6072,6 +6189,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public int getOrganizationColor(@NonNull ComponentName admin) {
+ throwIfParentInstance("getOrganizationColor");
try {
return mService.getOrganizationColor(admin);
} catch (RemoteException re) {
@@ -6107,6 +6225,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public void setOrganizationName(@NonNull ComponentName admin, @Nullable String title) {
+ throwIfParentInstance("setOrganizationName");
try {
mService.setOrganizationName(admin, title);
} catch (RemoteException re) {
@@ -6123,6 +6242,7 @@
* @throws SecurityException if {@code admin} is not a profile owner.
*/
public String getOrganizationName(@NonNull ComponentName admin) {
+ throwIfParentInstance("getOrganizationName");
try {
return mService.getOrganizationName(admin);
} catch (RemoteException re) {
@@ -6248,4 +6368,10 @@
throw re.rethrowFromSystemServer();
}
}
+
+ private void throwIfParentInstance(String functionName) {
+ if (mParentInstance) {
+ throw new SecurityException(functionName + " cannot be called on the parent instance");
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1fb2283..6df1038 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -80,6 +80,7 @@
void setMaximumTimeToLock(in ComponentName who, long timeMs, boolean parent);
long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent);
+ long getMaximumTimeToLockForUserAndProfiles(int userHandle);
void lockNow(boolean parent);
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
index 95a8ccf..77307b7 100644
--- a/core/java/android/app/job/JobService.java
+++ b/core/java/android/app/job/JobService.java
@@ -27,6 +27,8 @@
import com.android.internal.annotations.GuardedBy;
+import java.lang.ref.WeakReference;
+
/**
* <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
* <p>This is the base class that handles asynchronous requests that were previously scheduled. You
@@ -62,15 +64,15 @@
* Identifier for a message that will result in a call to
* {@link #onStartJob(android.app.job.JobParameters)}.
*/
- private final int MSG_EXECUTE_JOB = 0;
+ private static final int MSG_EXECUTE_JOB = 0;
/**
* Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}.
*/
- private final int MSG_STOP_JOB = 1;
+ private static final int MSG_STOP_JOB = 1;
/**
* Message that the client has completed execution of this job.
*/
- private final int MSG_JOB_FINISHED = 2;
+ private static final int MSG_JOB_FINISHED = 2;
/** Lock object for {@link #mHandler}. */
private final Object mHandlerLock = new Object();
@@ -82,21 +84,36 @@
@GuardedBy("mHandlerLock")
JobHandler mHandler;
- /** Binder for this service. */
- IJobService mBinder = new IJobService.Stub() {
- @Override
- public void startJob(JobParameters jobParams) {
- ensureHandler();
- Message m = Message.obtain(mHandler, MSG_EXECUTE_JOB, jobParams);
- m.sendToTarget();
+ static final class JobInterface extends IJobService.Stub {
+ final WeakReference<JobService> mService;
+
+ JobInterface(JobService service) {
+ mService = new WeakReference<>(service);
}
+
@Override
- public void stopJob(JobParameters jobParams) {
- ensureHandler();
- Message m = Message.obtain(mHandler, MSG_STOP_JOB, jobParams);
- m.sendToTarget();
+ public void startJob(JobParameters jobParams) throws RemoteException {
+ JobService service = mService.get();
+ if (service != null) {
+ service.ensureHandler();
+ Message m = Message.obtain(service.mHandler, MSG_EXECUTE_JOB, jobParams);
+ m.sendToTarget();
+ }
}
- };
+
+ @Override
+ public void stopJob(JobParameters jobParams) throws RemoteException {
+ JobService service = mService.get();
+ if (service != null) {
+ service.ensureHandler();
+ Message m = Message.obtain(service.mHandler, MSG_STOP_JOB, jobParams);
+ m.sendToTarget();
+ }
+
+ }
+ }
+
+ IJobService mBinder;
/** @hide */
void ensureHandler() {
@@ -194,6 +211,9 @@
/** @hide */
public final IBinder onBind(Intent intent) {
+ if (mBinder == null) {
+ mBinder = new JobInterface(this);
+ }
return mBinder.asBinder();
}
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 1b024e2..461d1e0 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -71,6 +71,7 @@
* and {@link ComponentName#flattenToString()} to convert the extra value
* to/from {@link ComponentName}.
* </p>
+ * @hide
*/
public static final String EXTRA_TARGET_COMPONENT_NAME =
"android.content.extra.TARGET_COMPONENT_NAME";
@@ -81,6 +82,7 @@
* <p>
* Type: long
* </p>
+ * @hide
*/
public static final String EXTRA_USER_SERIAL_NUMBER =
"android.content.extra.USER_SERIAL_NUMBER";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f060a1c..7e67e8d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3740,6 +3740,31 @@
public static final String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
/**
+ * A {@link ComponentName ComponentName[]} describing components that should be filtered out
+ * and omitted from a list of components presented to the user.
+ *
+ * <p>When used with {@link #ACTION_CHOOSER}, the chooser will omit any of the components
+ * in this array if it otherwise would have shown them. Useful for omitting specific targets
+ * from your own package or other apps from your organization if the idea of sending to those
+ * targets would be redundant with other app functionality. Filtered components will not
+ * be able to present targets from an associated <code>ChooserTargetService</code>.</p>
+ */
+ public static final String EXTRA_EXCLUDE_COMPONENTS
+ = "android.intent.extra.EXCLUDE_COMPONENTS";
+
+ /**
+ * A {@link android.service.chooser.ChooserTarget ChooserTarget[]} for {@link #ACTION_CHOOSER}
+ * describing additional high-priority deep-link targets for the chooser to present to the user.
+ *
+ * <p>Targets provided in this way will be presented inline with all other targets provided
+ * by services from other apps. They will be prioritized before other service targets, but
+ * after those targets provided by sources that the user has manually pinned to the front.</p>
+ *
+ * @see #ACTION_CHOOSER
+ */
+ public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
+
+ /**
* An {@link IntentSender} for an Activity that will be invoked when the user makes a selection
* from the chooser activity presented by {@link #ACTION_CHOOSER}.
*
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 7671f72..9ee6fa2 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -48,6 +48,9 @@
* <p>
* If this object represents a feature requested by an app, this is the
* minimum version of the feature required by the app.
+ * <p>
+ * When a feature version is undefined by a device, it's assumed to be
+ * version 0.
*/
public int version;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index fe8db9f..aa1e372 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -385,6 +385,7 @@
public final int installLocation;
public final VerifierInfo[] verifiers;
public final Signature[] signatures;
+ public final Certificate[][] certificates;
public final boolean coreApp;
public final boolean multiArch;
public final boolean use32bitAbi;
@@ -392,8 +393,8 @@
public ApkLite(String codePath, String packageName, String splitName, int versionCode,
int revisionCode, int installLocation, List<VerifierInfo> verifiers,
- Signature[] signatures, boolean coreApp, boolean multiArch, boolean use32bitAbi,
- boolean extractNativeLibs) {
+ Signature[] signatures, Certificate[][] certificates, boolean coreApp,
+ boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs) {
this.codePath = codePath;
this.packageName = packageName;
this.splitName = splitName;
@@ -402,6 +403,7 @@
this.installLocation = installLocation;
this.verifiers = verifiers.toArray(new VerifierInfo[verifiers.size()]);
this.signatures = signatures;
+ this.certificates = certificates;
this.coreApp = coreApp;
this.multiArch = multiArch;
this.use32bitAbi = use32bitAbi;
@@ -1074,6 +1076,43 @@
}
/**
+ * Populates the correct packages fields with the given certificates.
+ * <p>
+ * This is useful when we've already processed the certificates [such as during package
+ * installation through an installer session]. We don't re-process the archive and
+ * simply populate the correct fields.
+ */
+ public static void populateCertificates(Package pkg, Certificate[][] certificates)
+ throws PackageParserException {
+ pkg.mCertificates = null;
+ pkg.mSignatures = null;
+ pkg.mSigningKeys = null;
+
+ pkg.mCertificates = certificates;
+ try {
+ pkg.mSignatures = convertToSignatures(certificates);
+ } catch (CertificateEncodingException e) {
+ // certificates weren't encoded properly; something went wrong
+ throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "Failed to collect certificates from " + pkg.baseCodePath, e);
+ }
+ pkg.mSigningKeys = new ArraySet<>(certificates.length);
+ for (int i = 0; i < certificates.length; i++) {
+ Certificate[] signerCerts = certificates[i];
+ Certificate signerCert = signerCerts[0];
+ pkg.mSigningKeys.add(signerCert.getPublicKey());
+ }
+ // add signatures to child packages
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ Package childPkg = pkg.childPackages.get(i);
+ childPkg.mCertificates = pkg.mCertificates;
+ childPkg.mSignatures = pkg.mSignatures;
+ childPkg.mSigningKeys = pkg.mSigningKeys;
+ }
+ }
+
+ /**
* Collect certificates from all the APKs described in the given package,
* populating {@link Package#mSignatures}. Also asserts that all APK
* contents are signed correctly and consistently.
@@ -1304,6 +1343,7 @@
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
final Signature[] signatures;
+ final Certificate[][] certificates;
if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
// TODO: factor signature related items out of Package object
final Package tempPkg = new Package(null);
@@ -1314,12 +1354,14 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
signatures = tempPkg.mSignatures;
+ certificates = tempPkg.mCertificates;
} else {
signatures = null;
+ certificates = null;
}
final AttributeSet attrs = parser;
- return parseApkLite(apkPath, res, parser, attrs, flags, signatures);
+ return parseApkLite(apkPath, res, parser, attrs, flags, signatures, certificates);
} catch (XmlPullParserException | IOException | RuntimeException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
@@ -1405,8 +1447,8 @@
}
private static ApkLite parseApkLite(String codePath, Resources res, XmlPullParser parser,
- AttributeSet attrs, int flags, Signature[] signatures) throws IOException,
- XmlPullParserException, PackageParserException {
+ AttributeSet attrs, int flags, Signature[] signatures, Certificate[][] certificates)
+ throws IOException, XmlPullParserException, PackageParserException {
final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
@@ -1466,8 +1508,8 @@
}
return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
- revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
- use32bitAbi, extractNativeLibs);
+ revisionCode, installLocation, verifiers, signatures, certificates, coreApp,
+ multiArch, use32bitAbi, extractNativeLibs);
}
/**
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index e85311d..8236f55 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -36,22 +36,21 @@
* @hide
*/
public class PackageUserState {
+ public long ceDataInode;
+ public boolean installed;
public boolean stopped;
public boolean notLaunched;
- public boolean installed;
public boolean hidden; // Is the app restricted by owner / admin
public boolean suspended;
- public int enabled;
public boolean blockUninstall;
-
+ public int enabled;
public String lastDisableAppCaller;
+ public int domainVerificationStatus;
+ public int appLinkGeneration;
public ArraySet<String> disabledComponents;
public ArraySet<String> enabledComponents;
- public int domainVerificationStatus;
- public int appLinkGeneration;
-
public PackageUserState() {
installed = true;
hidden = false;
@@ -62,18 +61,19 @@
}
public PackageUserState(PackageUserState o) {
+ ceDataInode = o.ceDataInode;
installed = o.installed;
stopped = o.stopped;
notLaunched = o.notLaunched;
- enabled = o.enabled;
hidden = o.hidden;
suspended = o.suspended;
- lastDisableAppCaller = o.lastDisableAppCaller;
- disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
- enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
blockUninstall = o.blockUninstall;
+ enabled = o.enabled;
+ lastDisableAppCaller = o.lastDisableAppCaller;
domainVerificationStatus = o.domainVerificationStatus;
appLinkGeneration = o.appLinkGeneration;
+ disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
+ enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index a762f59..34a9523 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -26,6 +26,7 @@
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
import android.os.Trace;
import android.util.Log;
import android.util.LruCache;
@@ -1311,7 +1312,8 @@
operation.mBindArgs.clear();
}
}
- operation.mStartTime = System.currentTimeMillis();
+ operation.mStartWallTime = System.currentTimeMillis();
+ operation.mStartTime = SystemClock.uptimeMillis();
operation.mKind = kind;
operation.mSql = sql;
if (bindArgs != null) {
@@ -1376,7 +1378,7 @@
Trace.asyncTraceEnd(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(),
operation.mCookie);
}
- operation.mEndTime = System.currentTimeMillis();
+ operation.mEndTime = SystemClock.uptimeMillis();
operation.mFinished = true;
return SQLiteDebug.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
operation.mEndTime - operation.mStartTime);
@@ -1454,8 +1456,9 @@
// marker for us, potentially losing metadata in the process).
private static final int MAX_TRACE_METHOD_NAME_LEN = 256;
- public long mStartTime;
- public long mEndTime;
+ public long mStartWallTime; // in System.currentTimeMillis()
+ public long mStartTime; // in SystemClock.uptimeMillis();
+ public long mEndTime; // in SystemClock.uptimeMillis();
public String mKind;
public String mSql;
public ArrayList<Object> mBindArgs;
@@ -1468,7 +1471,7 @@
if (mFinished) {
msg.append(" took ").append(mEndTime - mStartTime).append("ms");
} else {
- msg.append(" started ").append(System.currentTimeMillis() - mStartTime)
+ msg.append(" started ").append(System.currentTimeMillis() - mStartWallTime)
.append("ms ago");
}
msg.append(" - ").append(getStatus());
@@ -1519,7 +1522,7 @@
// relatively expensive to create during preloading. This method is only used
// when dumping a connection, which is a rare (mainly error) case. So:
// DO NOT CACHE.
- return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartTime));
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartWallTime));
}
}
}
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 6aacc9c..c54d1e1 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -438,7 +438,7 @@
* @see #createCaptureSession
* @see OutputConfiguration
*/
- public abstract void createCaptureSessionByOutputConfiguration(
+ public abstract void createCaptureSessionByOutputConfigurations(
List<OutputConfiguration> outputConfigurations,
CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException;
@@ -627,7 +627,7 @@
* @see OutputConfiguration
*
*/
- public abstract void createReprocessableCaptureSessionWithConfigurations(
+ public abstract void createReprocessableCaptureSessionByConfigurations(
@NonNull InputConfiguration inputConfig,
@NonNull List<OutputConfiguration> outputs,
@NonNull CameraCaptureSession.StateCallback callback,
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d2e820e..18a155d 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -493,7 +493,7 @@
}
@Override
- public void createCaptureSessionByOutputConfiguration(
+ public void createCaptureSessionByOutputConfigurations(
List<OutputConfiguration> outputConfigurations,
CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException {
@@ -532,7 +532,7 @@
}
@Override
- public void createReprocessableCaptureSessionWithConfigurations(InputConfiguration inputConfig,
+ public void createReprocessableCaptureSessionByConfigurations(InputConfiguration inputConfig,
List<OutputConfiguration> outputs,
android.hardware.camera2.CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException {
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index b8088f3..4756b372 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -815,7 +815,8 @@
if (groupId != reqGroupId) {
Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
}
- mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
+ mRemovalCallback.onRemovalSucceeded(new Fingerprint(null, groupId, fingerId,
+ deviceId));
}
}
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index ae44f1d..194b9ee 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -345,6 +345,24 @@
mMemoryRegions = Arrays.copyOf(memoryRegions, memoryRegions.length);
}
+ @Override
+ public String toString() {
+ String retVal = "";
+ retVal += "Id : " + mId;
+ retVal += ", Name : " + mName;
+ retVal += "\n\tVendor : " + mVendor;
+ retVal += ", ToolChain : " + mToolchain;
+ retVal += "\n\tPlatformVersion : " + mPlatformVersion;
+ retVal += ", StaticSwVersion : " + mStaticSwVersion;
+ retVal += "\n\tPeakMips : " + mPeakMips;
+ retVal += ", StoppedPowerDraw : " + mStoppedPowerDrawMw + " mW";
+ retVal += ", PeakPowerDraw : " + mPeakPowerDrawMw + " mW";
+ retVal += "\n\tSupported sensors : " + Arrays.toString(mSupportedSensors);
+ retVal += "\n\tMemory Regions : " + Arrays.toString(mMemoryRegions);
+
+ return retVal;
+ }
+
private ContextHubInfo(Parcel in) {
mId = in.readInt();
mName = in.readString();
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index 3e6cb63..2b9b974 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -18,9 +18,12 @@
import android.Manifest;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -28,13 +31,12 @@
* @hide
*/
public class ContextHubService extends IContextHubService.Stub {
-
public static final String CONTEXTHUB_SERVICE = "contexthub_service";
private static final String TAG = "ContextHubService";
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
- + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
+ + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
public static final int ANY_HUB = -1;
@@ -78,8 +80,8 @@
@Override
public int registerCallback(IContextHubCallback callback) throws RemoteException {
checkPermissions();
- synchronized(this) {
- mCallback = callback;
+ synchronized (this) {
+ mCallback = callback;
}
return 0;
}
@@ -87,10 +89,10 @@
@Override
public int[] getContextHubHandles() throws RemoteException {
checkPermissions();
- int [] returnArray = new int[mContextHubInfo.length];
+ int[] returnArray = new int[mContextHubInfo.length];
for (int i = 0; i < returnArray.length; ++i) {
- returnArray[i] = i + 1; //valid handles from 1...n
+ returnArray[i] = i;
Log.d(TAG, String.format("Hub %s is mapped to %d",
mContextHubInfo[i].getName(), returnArray[i]));
}
@@ -101,7 +103,6 @@
@Override
public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
checkPermissions();
- contextHubHandle -= 1;
if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
return null; // null means fail
}
@@ -112,13 +113,12 @@
@Override
public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException {
checkPermissions();
- contextHubHandle -= 1;
if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
- return -1; // negative handle are invalid, means failed
+ Log.e(TAG, "Invalid contextHubhandle " + contextHubHandle);
+ return -1;
}
- // Call Native interface here
int[] msgHeader = new int[MSG_HEADER_SIZE];
msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle;
msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
@@ -147,7 +147,7 @@
msgHeader[MSG_FIELD_VERSION] = 0;
msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP;
- if(nativeSendMessage(msgHeader, null) != 0) {
+ if (nativeSendMessage(msgHeader, null) != 0) {
return -1;
}
@@ -157,7 +157,7 @@
@Override
public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle)
- throws RemoteException {
+ throws RemoteException {
checkPermissions();
// This assumes that all the nanoAppInfo is current. This is reasonable
// for the use cases for tightly controlled nanoApps.
@@ -173,10 +173,10 @@
checkPermissions();
ArrayList<Integer> foundInstances = new ArrayList<Integer>();
- for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
+ for (Integer nanoAppInstance: mNanoAppHash.keySet()) {
NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
- if (filter.testMatch(info)){
+ if (filter.testMatch(info)) {
foundInstances.add(nanoAppInstance);
}
}
@@ -191,7 +191,7 @@
@Override
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
- throws RemoteException {
+ throws RemoteException {
checkPermissions();
int[] msgHeader = new int[MSG_HEADER_SIZE];
@@ -203,6 +203,32 @@
return nativeSendMessage(msgHeader, msg.getData());
}
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump contexthub_service");
+ return;
+ }
+
+ pw.println("Dumping ContextHub Service");
+
+ pw.println("");
+ // dump ContextHubInfo
+ pw.println("=================== CONTEXT HUBS ====================");
+ for (int i = 0; i < mContextHubInfo.length; i++) {
+ pw.println("Handle " + i + " : " + mContextHubInfo[i].toString());
+ }
+ pw.println("");
+ pw.println("=================== NANOAPPS ====================");
+ // Dump nanoAppHash
+ for (Integer nanoAppInstance: mNanoAppHash.keySet()) {
+ pw.println(nanoAppInstance + " : " + mNanoAppHash.get(nanoAppInstance).toString());
+ }
+
+ // dump eventLog
+ }
+
private void checkPermissions() {
mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
}
@@ -212,16 +238,16 @@
return -1;
}
- synchronized(this) {
+ synchronized (this) {
if (mCallback != null) {
ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE],
- header[MSG_FIELD_VERSION],
- data);
+ header[MSG_FIELD_VERSION],
+ data);
try {
mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE],
- header[MSG_FIELD_APP_INSTANCE],
- msg);
+ header[MSG_FIELD_APP_INSTANCE],
+ msg);
} catch (Exception e) {
Log.w(TAG, "Exception " + e + " when calling remote callback");
return -1;
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
index d100de2..857434e 100644
--- a/core/java/android/hardware/location/MemoryRegion.java
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -79,6 +79,33 @@
}
@Override
+ public String toString() {
+ String mask = "";
+
+ if (isReadable()) {
+ mask += "r";
+ } else {
+ mask += "-";
+ }
+
+ if (isWritable()) {
+ mask += "w";
+ } else {
+ mask += "-";
+ }
+
+ if (isExecutable()) {
+ mask += "x";
+ } else {
+ mask += "-";
+ }
+
+ String retVal = "[ " + mSizeBytesFree + "/ " + mSizeBytes + " ] : " + mask;
+
+ return retVal;
+ }
+
+ @Override
public int describeContents() {
return 0;
}
diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java
index b447b62..c8f3439 100644
--- a/core/java/android/hardware/location/NanoApp.java
+++ b/core/java/android/hardware/location/NanoApp.java
@@ -284,4 +284,14 @@
return new NanoApp[size];
}
};
+
+ @Override
+ public String toString() {
+ String retVal = "Id : " + mAppId;
+ retVal += ", Version : " + mAppVersion;
+ retVal += ", Name : " + mName;
+ retVal += ", Publisher : " + mPublisher;
+
+ return retVal;
+ }
}
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
index 977f645..e842ec6 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.java
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -320,4 +320,15 @@
return new NanoAppInstanceInfo[size];
}
};
+
+ @Override
+ public String toString() {
+ String retVal = "handle : " + mHandle;
+ retVal += ", Id : 0x" + Long.toHexString(mAppId);
+ retVal += ", Version : " + mAppVersion;
+ retVal += ", Name : " + mName;
+ retVal += ", Publisher : " + mPublisher;
+
+ return retVal;
+ }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b452341..a025337 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -767,6 +767,28 @@
}
/**
+ * Returns a {@link Network} object corresponding to the currently active
+ * default data network for a specific UID. In the event that the default data
+ * network disconnects, the returned {@code Network} object will no longer
+ * be usable. This will return {@code null} when there is no default
+ * network for the UID.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
+ *
+ * @return a {@link Network} object for the current default network for the
+ * given UID or {@code null} if no default network is currently active
+ *
+ * @hide
+ */
+ public Network getActiveNetworkForUid(int uid) {
+ try {
+ return mService.getActiveNetworkForUid(uid);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Configures an always-on VPN connection through a specific application.
* This connection is automatically granted and persisted after a reboot.
*
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 1a9c9ea..c897c45 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -44,6 +44,7 @@
interface IConnectivityManager
{
Network getActiveNetwork();
+ Network getActiveNetworkForUid(int uid);
NetworkInfo getActiveNetworkInfo();
NetworkInfo getActiveNetworkInfoForUid(int uid);
NetworkInfo getNetworkInfo(int networkType);
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a9de23e..9cd563e 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -55,19 +55,22 @@
final String mSubscriberId;
final String mNetworkId;
final boolean mRoaming;
+ final boolean mMetered;
public NetworkIdentity(
- int type, int subType, String subscriberId, String networkId, boolean roaming) {
+ int type, int subType, String subscriberId, String networkId, boolean roaming,
+ boolean metered) {
mType = type;
mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
mSubscriberId = subscriberId;
mNetworkId = networkId;
mRoaming = roaming;
+ mMetered = metered;
}
@Override
public int hashCode() {
- return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming);
+ return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered);
}
@Override
@@ -76,7 +79,8 @@
final NetworkIdentity ident = (NetworkIdentity) obj;
return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming
&& Objects.equals(mSubscriberId, ident.mSubscriberId)
- && Objects.equals(mNetworkId, ident.mNetworkId);
+ && Objects.equals(mNetworkId, ident.mNetworkId)
+ && mMetered == ident.mMetered;
}
return false;
}
@@ -102,6 +106,7 @@
if (mRoaming) {
builder.append(", ROAMING");
}
+ builder.append(", metered=").append(mMetered);
return builder.append("}").toString();
}
@@ -125,6 +130,10 @@
return mRoaming;
}
+ public boolean getMetered() {
+ return mMetered;
+ }
+
/**
* Scrub given IMSI on production builds.
*/
@@ -162,6 +171,7 @@
String subscriberId = null;
String networkId = null;
boolean roaming = false;
+ boolean metered = false;
if (isNetworkTypeMobile(type)) {
if (state.subscriberId == null) {
@@ -171,6 +181,9 @@
subscriberId = state.subscriberId;
roaming = state.networkInfo.isRoaming();
+ metered = !state.networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+
} else if (type == TYPE_WIFI) {
if (state.networkId != null) {
networkId = state.networkId;
@@ -182,7 +195,7 @@
}
}
- return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
+ return new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered);
}
@Override
@@ -200,6 +213,9 @@
if (res == 0) {
res = Boolean.compare(mRoaming, another.mRoaming);
}
+ if (res == 0) {
+ res = Boolean.compare(mMetered, another.mMetered);
+ }
return res;
}
}
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index b32b2cc..caf7982 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -19,6 +19,7 @@
import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_PROXY;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
import static android.net.ConnectivityManager.TYPE_WIMAX;
@@ -30,9 +31,6 @@
import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
import static android.telephony.TelephonyManager.getNetworkClass;
-import static com.android.internal.util.ArrayUtils.contains;
-
-import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.BackupUtils;
@@ -71,16 +69,6 @@
public static final int MATCH_BLUETOOTH = 8;
public static final int MATCH_PROXY = 9;
- /**
- * Set of {@link NetworkInfo#getType()} that reflect data usage.
- */
- private static final int[] DATA_USAGE_NETWORK_TYPES;
-
- static {
- DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray(
- com.android.internal.R.array.config_data_usage_network_types);
- }
-
private static boolean sForceAllNetworkTypes = false;
@VisibleForTesting
@@ -318,9 +306,8 @@
// TODO: consider matching against WiMAX subscriber identity
return true;
} else {
- final boolean matchesType = (sForceAllNetworkTypes
- || contains(DATA_USAGE_NETWORK_TYPES, ident.mType));
- return matchesType && !ArrayUtils.isEmpty(mMatchSubscriberIds)
+ return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered))
+ && !ArrayUtils.isEmpty(mMatchSubscriberIds)
&& ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
}
}
@@ -389,7 +376,7 @@
if (ident.mType == TYPE_WIMAX) {
return true;
} else {
- return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
+ return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered);
}
}
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index e40ebf7..d39968a 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -115,6 +115,13 @@
*/
public static final String EXTRA_MAX_CHARGING_VOLTAGE = "max_charging_voltage";
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the charge counter present in the battery.
+ * {@hide}
+ */
+ public static final String EXTRA_CHARGE_COUNTER = "charge_counter";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = 1;
public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index c3e0f24..b509d76 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -30,6 +30,7 @@
public int batteryLevel;
public int batteryVoltage;
public int batteryTemperature;
+ public int batteryChargeCounter;
public String batteryTechnology;
public BatteryProperties() {
@@ -47,6 +48,7 @@
batteryLevel = other.batteryLevel;
batteryVoltage = other.batteryVoltage;
batteryTemperature = other.batteryTemperature;
+ batteryChargeCounter = other.batteryChargeCounter;
batteryTechnology = other.batteryTechnology;
}
@@ -67,6 +69,7 @@
batteryLevel = p.readInt();
batteryVoltage = p.readInt();
batteryTemperature = p.readInt();
+ batteryChargeCounter = p.readInt();
batteryTechnology = p.readString();
}
@@ -82,6 +85,7 @@
p.writeInt(batteryLevel);
p.writeInt(batteryVoltage);
p.writeInt(batteryTemperature);
+ p.writeInt(batteryChargeCounter);
p.writeString(batteryTechnology);
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f2e316c..ece1228 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -83,6 +83,8 @@
public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable";
/** {@hide} */
public static final String PROP_EMULATE_FBE = "persist.sys.emulate_fbe";
+ /** {@hide} */
+ public static final String PROP_SDCARDFS = "persist.sys.sdcardfs";
/** {@hide} */
public static final String UUID_PRIVATE_INTERNAL = null;
@@ -93,6 +95,10 @@
public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
/** {@hide} */
public static final int DEBUG_EMULATE_FBE = 1 << 1;
+ /** {@hide} */
+ public static final int DEBUG_SDCARDFS_FORCE_ON = 1 << 2;
+ /** {@hide} */
+ public static final int DEBUG_SDCARDFS_FORCE_OFF = 1 << 3;
// NOTE: keep in sync with installd
/** {@hide} */
@@ -1178,7 +1184,23 @@
/** {@hide} */
public static File maybeTranslateEmulatedPathToInternal(File path) {
- // Disabled now that FUSE has been replaced by sdcardfs
+ final IMountService mountService = IMountService.Stub.asInterface(
+ ServiceManager.getService("mount"));
+ try {
+ final VolumeInfo[] vols = mountService.getVolumes(0);
+ for (VolumeInfo vol : vols) {
+ if ((vol.getType() == VolumeInfo.TYPE_EMULATED
+ || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
+ final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
+ vol.getInternalPath(), path);
+ if (internalPath != null && internalPath.exists()) {
+ return internalPath;
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
return path;
}
diff --git a/core/java/android/service/notification/Adjustment.aidl b/core/java/android/service/notification/Adjustment.aidl
new file mode 100644
index 0000000..8bd814a
--- /dev/null
+++ b/core/java/android/service/notification/Adjustment.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.notification;
+
+parcelable Adjustment;
\ No newline at end of file
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
new file mode 100644
index 0000000..2e4f48d
--- /dev/null
+++ b/core/java/android/service/notification/Adjustment.java
@@ -0,0 +1,150 @@
+/*
+ * 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.service.notification;
+
+import android.annotation.SystemApi;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Ranking updates from the Ranker.
+ *
+ * @hide
+ */
+@SystemApi
+public final class Adjustment implements Parcelable {
+ private final String mPackage;
+ private final String mKey;
+ private final int mImportance;
+ private final CharSequence mExplanation;
+ private final Uri mReference;
+ private final Bundle mSignals;
+
+ public static final String GROUP_KEY_OVERRIDE_KEY = "group_key_override";
+ public static final String NEEDS_AUTOGROUPING_KEY = "autogroup_needed";
+
+ /**
+ * Create a notification adjustment.
+ *
+ * @param pkg The package of the notification.
+ * @param key The notification key.
+ * @param importance The recommended importance of the notification.
+ * @param signals A bundle of signals that should inform notification grouping and ordering.
+ * @param explanation A human-readable justification for the adjustment.
+ * @param reference A reference to an external object that augments the
+ * explanation, such as a
+ * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI},
+ * or null.
+ */
+ public Adjustment(String pkg, String key, int importance, Bundle signals,
+ CharSequence explanation, Uri reference) {
+ mPackage = pkg;
+ mKey = key;
+ mImportance = importance;
+ mSignals = signals;
+ mExplanation = explanation;
+ mReference = reference;
+ }
+
+ protected Adjustment(Parcel in) {
+ if (in.readInt() == 1) {
+ mPackage = in.readString();
+ } else {
+ mPackage = null;
+ }
+ if (in.readInt() == 1) {
+ mKey = in.readString();
+ } else {
+ mKey = null;
+ }
+ mImportance = in.readInt();
+ if (in.readInt() == 1) {
+ mExplanation = in.readCharSequence();
+ } else {
+ mExplanation = null;
+ }
+ mReference = in.readParcelable(Uri.class.getClassLoader());
+ mSignals = in.readBundle();
+ }
+
+ public static final Creator<Adjustment> CREATOR = new Creator<Adjustment>() {
+ @Override
+ public Adjustment createFromParcel(Parcel in) {
+ return new Adjustment(in);
+ }
+
+ @Override
+ public Adjustment[] newArray(int size) {
+ return new Adjustment[size];
+ }
+ };
+
+ public String getPackage() {
+ return mPackage;
+ }
+
+ public String getKey() {
+ return mKey;
+ }
+
+ public int getImportance() {
+ return mImportance;
+ }
+
+ public CharSequence getExplanation() {
+ return mExplanation;
+ }
+
+ public Uri getReference() {
+ return mReference;
+ }
+
+ public Bundle getSignals() {
+ return mSignals;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (mPackage != null) {
+ dest.writeInt(1);
+ dest.writeString(mPackage);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mKey != null) {
+ dest.writeInt(1);
+ dest.writeString(mKey);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mImportance);
+ if (mExplanation != null) {
+ dest.writeInt(1);
+ dest.writeCharSequence(mExplanation);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeParcelable(mReference, flags);
+ dest.writeBundle(mSignals);
+ }
+}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index afdd1d4..e708b0a 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -69,6 +69,12 @@
* <action android:name="android.service.notification.NotificationListenerService" />
* </intent-filter>
* </service></pre>
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing any operations. The {@link #requestRebind(ComponentName)}
+ * method is the <i>only</i> one that is safe to call before {@link #onListenerConnected()}
+ * or after {@link #onListenerDisconnected()}.
+ * </p>
*/
public abstract class NotificationListenerService extends Service {
// TAG = "NotificationListenerService[MySubclass]"
@@ -117,6 +123,16 @@
* This does not change the interruption filter, only the effects. **/
public static final int HINT_HOST_DISABLE_EFFECTS = 1;
+ /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
+ * should disable notification sound, but not phone calls.
+ * This does not change the interruption filter, only the effects. **/
+ public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 1 << 1;
+
+ /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
+ * should disable phone call sounds, buyt not notification sound.
+ * This does not change the interruption filter, only the effects. **/
+ public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 1 << 2;
+
/**
* Whether notification suppressed by DND should not interruption visually when the screen is
* off.
@@ -164,6 +180,7 @@
/** @hide */
protected NotificationListenerWrapper mWrapper = null;
+ private boolean isConnected = false;
@GuardedBy("mLock")
private RankingMap mRankingMap;
@@ -222,10 +239,10 @@
/**
* Implement this method to learn when notifications are removed.
- * <P>
+ * <p>
* This might occur because the user has dismissed the notification using system UI (or another
* notification listener) or because the app has withdrawn the notification.
- * <P>
+ * <p>
* NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
* result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
* fields such as {@link android.app.Notification#contentView} and
@@ -243,10 +260,10 @@
/**
* Implement this method to learn when notifications are removed.
- * <P>
+ * <p>
* This might occur because the user has dismissed the notification using system UI (or another
* notification listener) or because the app has withdrawn the notification.
- * <P>
+ * <p>
* NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
* result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
* fields such as {@link android.app.Notification#contentView} and
@@ -275,6 +292,15 @@
}
/**
+ * Implement this method to learn about when the listener is disconnected from the
+ * notification manager.You will not receive any events after this call, and may only
+ * call {@link #requestRebind(ComponentName)} at this time.
+ */
+ public void onListenerDisconnected() {
+ // optional
+ }
+
+ /**
* Implement this method to be notified when the notification ranking changes.
*
* @param rankingMap The current ranking map that can be used to retrieve ranking information
@@ -322,12 +348,15 @@
* It should be called after the user dismisses a single notification using your UI;
* upon being informed, the notification manager will actually remove the notification
* and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
- * <P>
+ * <p>
* <b>Note:</b> If your listener allows the user to fire a notification's
* {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
* this method at that time <i>if</i> the Notification in question has the
* {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param pkg Package of the notifying app.
* @param tag Tag of the notification as specified by the notifying app in
* {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
@@ -357,12 +386,16 @@
* It should be called after the user dismisses a single notification using your UI;
* upon being informed, the notification manager will actually remove the notification
* and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
- * <P>
+ * <p>
* <b>Note:</b> If your listener allows the user to fire a notification's
* {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
* this method at that time <i>if</i> the Notification in question has the
* {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
* <p>
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param key Notification to dismiss from {@link StatusBarNotification#getKey()}.
*/
public final void cancelNotification(String key) {
@@ -384,6 +417,9 @@
* upon being informed, the notification manager will actually remove all active notifications
* and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* {@see #cancelNotification(String, String, int)}
*/
public final void cancelAllNotifications() {
@@ -396,6 +432,9 @@
* Use this if your listener has a user interface that allows the user to dismiss
* multiple notifications at once.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param keys Notifications to dismiss, or {@code null} to dismiss all.
*
* {@see #cancelNotification(String, String, int)}
@@ -414,6 +453,10 @@
* user. This should only be called when there is sufficient confidence that the user is
* looking at the notifications, such as when the notifications appear on the screen due to
* an explicit user interaction.
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param keys Notifications to mark as seen.
*/
public final void setNotificationsShown(String[] keys) {
@@ -436,6 +479,9 @@
* <p>
* Set to {@link #TRIM_FULL} initially.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @hide
*
* @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
@@ -455,6 +501,9 @@
* Request the list of outstanding notifications (that is, those that are visible to the
* current user). Useful when you don't know what's already been posted.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @return An array of active notifications, sorted in natural order.
*/
public StatusBarNotification[] getActiveNotifications() {
@@ -480,6 +529,9 @@
* notifications but didn't want to retain the bits, and now need to go back and extract
* more data out of those notifications.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param keys the keys of the notifications to request
* @return An array of notifications corresponding to the requested keys, in the
* same order as the key list.
@@ -545,6 +597,9 @@
* shared across all listeners or a feature the notification host does not support or refuses
* to grant.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @return Zero or more of the HINT_ constants.
*/
public final int getCurrentListenerHints() {
@@ -572,6 +627,9 @@
* <p>
* Listen for updates using {@link #onInterruptionFilterChanged(int)}.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
* unavailable.
*/
@@ -594,6 +652,9 @@
* <p>
* Listen for updates using {@link #onListenerHintsChanged(int)}.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param hints One or more of the HINT_ constants.
*/
public final void requestListenerHints(int hints) {
@@ -614,6 +675,9 @@
* <p>
* Listen for updates using {@link #onInterruptionFilterChanged(int)}.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
*/
public final void requestInterruptionFilter(int interruptionFilter) {
@@ -640,6 +704,9 @@
* such events, for example to retrieve the RankingMap right after
* initialization.
*
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation.
+ *
* @return A {@link RankingMap} object providing access to ranking information
*/
public RankingMap getCurrentRanking() {
@@ -648,6 +715,12 @@
}
}
+ /**
+ * This is not the lifecycle event you are looking for.
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing any operations.
+ */
@Override
public IBinder onBind(Intent intent) {
if (mWrapper == null) {
@@ -665,6 +738,12 @@
return true;
}
+ @Override
+ public void onDestroy() {
+ onListenerDisconnected();
+ super.onDestroy();
+ }
+
/**
* Directly register this service with the Notification Manager.
*
@@ -693,7 +772,7 @@
/**
* Directly unregister this service from the Notification Manager.
*
- * <P>This method will fail for listeners that were not registered
+ * <p>This method will fail for listeners that were not registered
* with (@link registerAsService).
* @hide
*/
@@ -708,11 +787,8 @@
/**
* Request that the listener be rebound, after a previous call to (@link requestUnbind).
*
- * <P>This method will fail for listeners that have
+ * <p>This method will fail for listeners that have
* not been granted the permission by the user.
- *
- * <P>The service should wait for the {@link #onListenerConnected()} event
- * before performing any operations.
*/
public static void requestRebind(ComponentName componentName)
throws RemoteException {
@@ -724,14 +800,19 @@
/**
* Request that the service be unbound.
*
- * <P>This will no longer receive updates until
+ * <p>This will no longer receive updates until
* {@link #requestRebind(ComponentName)} is called.
* The service will likely be kiled by the system after this call.
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing this operation. I know it's tempting, but you must wait.
*/
public final void requestUnbind() throws RemoteException {
if (mWrapper != null) {
INotificationManager noMan = getNotificationInterface();
noMan.requestUnbindListener(mWrapper);
+ // Disable future messages.
+ isConnected = false;
}
}
@@ -842,6 +923,7 @@
synchronized (mLock) {
applyUpdateLocked(update);
}
+ isConnected = true;
mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
}
@@ -980,6 +1062,8 @@
private int mSuppressedVisualEffects;
private @Importance int mImportance;
private CharSequence mImportanceExplanation;
+ // System specified group key.
+ private String mOverrideGroupKey;
public Ranking() {}
@@ -1058,9 +1142,17 @@
return mImportanceExplanation;
}
+ /**
+ * If the system has overriden the group key, then this will be non-null, and this
+ * key should be used to bundle notifications.
+ */
+ public String getOverrideGroupKey() {
+ return mOverrideGroupKey;
+ }
+
private void populate(String key, int rank, boolean matchesInterruptionFilter,
int visibilityOverride, int suppressedVisualEffects, int importance,
- CharSequence explanation) {
+ CharSequence explanation, String overrideGroupKey) {
mKey = key;
mRank = rank;
mIsAmbient = importance < IMPORTANCE_LOW;
@@ -1069,6 +1161,7 @@
mSuppressedVisualEffects = suppressedVisualEffects;
mImportance = importance;
mImportanceExplanation = explanation;
+ mOverrideGroupKey = overrideGroupKey;
}
/**
@@ -1112,6 +1205,7 @@
private ArrayMap<String, Integer> mSuppressedVisualEffects;
private ArrayMap<String, Integer> mImportance;
private ArrayMap<String, String> mImportanceExplanation;
+ private ArrayMap<String, String> mOverrideGroupKeys;
private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
@@ -1138,7 +1232,7 @@
int rank = getRank(key);
outRanking.populate(key, rank, !isIntercepted(key),
getVisibilityOverride(key), getSuppressedVisualEffects(key),
- getImportance(key), getImportanceExplanation(key));
+ getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key));
return rank >= 0;
}
@@ -1209,6 +1303,15 @@
return mImportanceExplanation.get(key);
}
+ private String getOverrideGroupKey(String key) {
+ synchronized (this) {
+ if (mOverrideGroupKeys == null) {
+ buildOverrideGroupKeys();
+ }
+ }
+ return mOverrideGroupKeys.get(key);
+ }
+
// Locked by 'this'
private void buildRanksLocked() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
@@ -1263,6 +1366,15 @@
}
}
+ // Locked by 'this'
+ private void buildOverrideGroupKeys() {
+ Bundle overrideGroupKeys = mRankingUpdate.getOverrideGroupKeys();
+ mOverrideGroupKeys = new ArrayMap<>(overrideGroupKeys.size());
+ for (String key: overrideGroupKeys.keySet()) {
+ mOverrideGroupKeys.put(key, overrideGroupKeys.getString(key));
+ }
+ }
+
// ----------- Parcelable
@Override
@@ -1303,6 +1415,9 @@
@Override
public void handleMessage(Message msg) {
+ if (!isConnected) {
+ return;
+ }
switch (msg.what) {
case MSG_ON_NOTIFICATION_POSTED: {
SomeArgs args = (SomeArgs) msg.obj;
diff --git a/core/java/android/service/notification/NotificationRankerService.java b/core/java/android/service/notification/NotificationRankerService.java
index 47fdac6..ee5361a 100644
--- a/core/java/android/service/notification/NotificationRankerService.java
+++ b/core/java/android/service/notification/NotificationRankerService.java
@@ -22,14 +22,19 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.os.SomeArgs;
+import java.util.List;
+
/**
* A service that helps the user manage notifications. This class is only used to
* extend the framework service and may not be implemented by non-framework components.
@@ -91,27 +96,8 @@
/** Notification was canceled by the owning managed profile being turned off. */
public static final int REASON_PROFILE_TURNED_OFF = 15;
- public class Adjustment {
- int mImportance;
- CharSequence mExplanation;
- Uri mReference;
-
- /**
- * Create a notification importance adjustment.
- *
- * @param importance The final importance of the notification.
- * @param explanation A human-readable justification for the adjustment.
- * @param reference A reference to an external object that augments the
- * explanation, such as a
- * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI},
- * or null.
- */
- public Adjustment(int importance, CharSequence explanation, Uri reference) {
- mImportance = importance;
- mExplanation = explanation;
- mReference = reference;
- }
- }
+ /** Autobundled summary notification was canceled because its group was unbundled */
+ public static final int REASON_UNAUTOBUNDLED = 16;
private Handler mHandler;
@@ -200,18 +186,32 @@
}
/**
- * Change the importance of an existing notification. N.B. this won’t cause
+ * Updates a notification. N.B. this won’t cause
* an existing notification to alert, but might allow a future update to
* this notification to alert.
*
- * @param key the notification key
- * @param adjustment the new importance with an explanation
+ * @param adjustment the adjustment with an explanation
*/
- public final void adjustImportance(String key, Adjustment adjustment) {
+ public final void adjustNotification(Adjustment adjustment) {
if (!isBound()) return;
try {
- getNotificationInterface().setImportanceFromRankerService(mWrapper, key,
- adjustment.mImportance, adjustment.mExplanation);
+ getNotificationInterface().applyAdjustmentFromRankerService(mWrapper, adjustment);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
+ /**
+ * Updates existing notifications. Re-ranking won't occur until all adjustments are applied.
+ * N.B. this won’t cause an existing notification to alert, but might allow a future update to
+ * these notifications to alert.
+ *
+ * @param adjustments a list of adjustments with explanations
+ */
+ public final void adjustNotifications(List<Adjustment> adjustments) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface().applyAdjustmentsFromRankerService(mWrapper, adjustments);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
}
@@ -299,7 +299,7 @@
args.recycle();
Adjustment adjustment = onNotificationEnqueued(sbn, importance, user);
if (adjustment != null) {
- adjustImportance(sbn.getKey(), adjustment);
+ adjustNotification(adjustment);
}
} break;
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index 79f6fc4..788b5c0 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -30,16 +30,18 @@
private final Bundle mSuppressedVisualEffects;
private final int[] mImportance;
private final Bundle mImportanceExplanation;
+ private final Bundle mOverrideGroupKeys;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
- int[] importance, Bundle explanation) {
+ int[] importance, Bundle explanation, Bundle overrideGroupKeys) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
mSuppressedVisualEffects = suppressedVisualEffects;
mImportance = importance;
mImportanceExplanation = explanation;
+ mOverrideGroupKeys = overrideGroupKeys;
}
public NotificationRankingUpdate(Parcel in) {
@@ -50,6 +52,7 @@
mImportance = new int[mKeys.length];
in.readIntArray(mImportance);
mImportanceExplanation = in.readBundle();
+ mOverrideGroupKeys = in.readBundle();
}
@Override
@@ -65,6 +68,7 @@
out.writeBundle(mSuppressedVisualEffects);
out.writeIntArray(mImportance);
out.writeBundle(mImportanceExplanation);
+ out.writeBundle(mOverrideGroupKeys);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -101,4 +105,8 @@
public Bundle getImportanceExplanation() {
return mImportanceExplanation;
}
+
+ public Bundle getOverrideGroupKeys() {
+ return mOverrideGroupKeys;
+ }
}
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 198e43d..0221b66 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -33,7 +33,8 @@
private final int id;
private final String tag;
private final String key;
- private final String groupKey;
+ private String groupKey;
+ private String overrideGroupKey;
private final int uid;
private final String opPkg;
@@ -51,6 +52,27 @@
System.currentTimeMillis());
}
+ /** @hide */
+ public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
+ int initialPid, Notification notification, UserHandle user, String overrideGroupKey,
+ long postTime) {
+ if (pkg == null) throw new NullPointerException();
+ if (notification == null) throw new NullPointerException();
+
+ this.pkg = pkg;
+ this.opPkg = opPkg;
+ this.id = id;
+ this.tag = tag;
+ this.uid = uid;
+ this.initialPid = initialPid;
+ this.notification = notification;
+ this.user = user;
+ this.postTime = postTime;
+ this.overrideGroupKey = overrideGroupKey;
+ this.key = key();
+ this.groupKey = groupKey();
+ }
+
public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
int initialPid, int score, Notification notification, UserHandle user,
long postTime) {
@@ -84,15 +106,27 @@
this.notification = new Notification(in);
this.user = UserHandle.readFromParcel(in);
this.postTime = in.readLong();
+ if (in.readInt() != 0) {
+ this.overrideGroupKey = in.readString();
+ } else {
+ this.overrideGroupKey = null;
+ }
this.key = key();
this.groupKey = groupKey();
}
private String key() {
- return user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
+ String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
+ if (overrideGroupKey != null && getNotification().isGroupSummary()) {
+ sbnKey = sbnKey + "|" + overrideGroupKey;
+ }
+ return sbnKey;
}
private String groupKey() {
+ if (overrideGroupKey != null) {
+ return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+ }
final String group = getNotification().getGroup();
final String sortKey = getNotification().getSortKey();
if (group == null && sortKey == null) {
@@ -105,6 +139,17 @@
: "g:" + group);
}
+ /**
+ * Returns true if this notification is part of a group.
+ */
+ public boolean isGroup() {
+ if (overrideGroupKey != null || getNotification().getGroup() != null
+ || getNotification().getSortKey() != null) {
+ return true;
+ }
+ return false;
+ }
+
public void writeToParcel(Parcel out, int flags) {
out.writeString(this.pkg);
out.writeString(this.opPkg);
@@ -121,6 +166,12 @@
user.writeToParcel(out, flags);
out.writeLong(this.postTime);
+ if (this.overrideGroupKey != null) {
+ out.writeInt(1);
+ out.writeString(this.overrideGroupKey);
+ } else {
+ out.writeInt(0);
+ }
}
public int describeContents() {
@@ -149,22 +200,22 @@
this.notification.cloneInto(no, false); // light copy
return new StatusBarNotification(this.pkg, this.opPkg,
this.id, this.tag, this.uid, this.initialPid,
- 0, no, this.user, this.postTime);
+ no, this.user, this.overrideGroupKey, this.postTime);
}
@Override
public StatusBarNotification clone() {
return new StatusBarNotification(this.pkg, this.opPkg,
this.id, this.tag, this.uid, this.initialPid,
- 0, this.notification.clone(), this.user, this.postTime);
+ this.notification.clone(), this.user, this.overrideGroupKey, this.postTime);
}
@Override
public String toString() {
return String.format(
- "StatusBarNotification(pkg=%s user=%s id=%d tag=%s score=%d key=%s: %s)",
+ "StatusBarNotification(pkg=%s user=%s id=%d tag=%s key=%s: %s)",
this.pkg, this.user, this.id, this.tag,
- 0, this.key, this.notification);
+ this.key, this.notification);
}
/** Convenience method to check the notification's flags for
@@ -258,6 +309,21 @@
}
/**
+ * Sets the override group key.
+ */
+ public void setOverrideGroupKey(String overrideGroupKey) {
+ this.overrideGroupKey = overrideGroupKey;
+ groupKey = groupKey();
+ }
+
+ /**
+ * Returns the override group key.
+ */
+ public String getOverrideGroupKey() {
+ return overrideGroupKey;
+ }
+
+ /**
* @hide
*/
public Context getPackageContext(Context context) {
diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl
index 5434e2e..747f185 100644
--- a/core/java/android/service/quicksettings/IQSService.aidl
+++ b/core/java/android/service/quicksettings/IQSService.aidl
@@ -28,7 +28,6 @@
String contentDescription);
void onShowDialog(in Tile tile);
void onStartActivity(in Tile tile);
- void setTileMode(in ComponentName component, int mode);
boolean isLocked();
boolean isSecure();
void startUnlockAndRun(in Tile tile);
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 553d539..4e9a075 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -89,28 +89,24 @@
public static final String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
/**
- * The tile mode hasn't been set yet.
- * @hide
- */
- public static final int TILE_MODE_UNSET = 0;
-
- /**
- * Constant to be returned by {@link #onTileAdded}.
- * <p>
- * Passive mode is the default mode for tiles. The System will tell the tile
- * when it is most important to update by putting it in the listening state.
- */
- public static final int TILE_MODE_PASSIVE = 1;
-
- /**
- * Constant to be returned by {@link #onTileAdded}.
+ * Meta-data for tile definition to set a tile into active mode.
* <p>
* Active mode is for tiles which already listen and keep track of their state in their
* own process. These tiles may request to send an update to the System while their process
* is alive using {@link #requestListeningState}. The System will only bind these tiles
* on its own when a click needs to occur.
+ *
+ * To make a TileService an active tile, set this meta-data to true on the TileService's
+ * manifest declaration.
+ * <pre class="prettyprint">
+ * {@literal
+ * <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
+ * android:value="true" />
+ * }
+ * </pre>
*/
- public static final int TILE_MODE_ACTIVE = 2;
+ public static final String META_DATA_ACTIVE_TILE
+ = "android.service.quicksettings.ACTIVE_TILE";
/**
* Used to notify SysUI that Listening has be requested.
@@ -147,12 +143,8 @@
* Note that this is not guaranteed to be called between {@link #onCreate()}
* and {@link #onStartListening()}, it will only be called when the tile is added
* and not on subsequent binds.
- *
- * @see #TILE_MODE_PASSIVE
- * @see #TILE_MODE_ACTIVE
*/
- public int onTileAdded() {
- return TILE_MODE_PASSIVE;
+ public void onTileAdded() {
}
/**
@@ -386,15 +378,7 @@
}
break;
case MSG_TILE_ADDED:
- int mode = TileService.this.onTileAdded();
- if (mService == null) {
- return;
- }
- try {
- mService.setTileMode(new ComponentName(TileService.this,
- TileService.this.getClass()), mode);
- } catch (RemoteException e) {
- }
+ TileService.this.onTileAdded();
break;
case MSG_TILE_REMOVED:
if (mListening) {
@@ -431,8 +415,8 @@
/**
* Requests that a tile be put in the listening state so it can send an update.
*
- * This method is only applicable to tiles that return {@link #TILE_MODE_ACTIVE} from
- * {@link #onTileAdded()}, and will do nothing otherwise.
+ * This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
+ * as true on their TileService Manifest declaration, and will do nothing otherwise.
*/
public static final void requestListeningState(Context context, ComponentName component) {
Intent intent = new Intent(ACTION_REQUEST_LISTENING);
diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index 29a72fd..f1c8c7d 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -31,12 +31,7 @@
throw new IllegalArgumentException("Path string can not be null.");
}
Path path = new Path();
- boolean hasValidPathData = nParseStringForPath(path.mNativePath, pathString,
- pathString.length());
- if (!hasValidPathData) {
- throw new IllegalArgumentException("Path string: " + pathString +
- " does not contain valid path data");
- }
+ nParseStringForPath(path.mNativePath, pathString, pathString.length());
return path;
}
@@ -104,7 +99,6 @@
}
super.finalize();
}
-
}
/**
@@ -123,7 +117,7 @@
}
// Native functions are defined below.
- private static native boolean nParseStringForPath(long pathPtr, String pathString,
+ private static native void nParseStringForPath(long pathPtr, String pathString,
int stringLength);
private static native void nCreatePathFromPathData(long outPathPtr, long pathData);
private static native long nCreateEmptyPathData();
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index df774b4..f44d4c1a 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -485,15 +485,25 @@
}
/**
- * Stops any rendering into the surface. Use this if it is unclear whether
+ * Halts any current rendering into the surface. Use this if it is unclear whether
* or not the surface used by the HardwareRenderer will be changing. It
- * Suspends any rendering into the surface, but will not do any destruction
+ * Suspends any rendering into the surface, but will not do any destruction.
+ *
+ * Any subsequent draws will override the pause, resuming normal operation.
*/
boolean pauseSurface(Surface surface) {
return nPauseSurface(mNativeProxy, surface);
}
/**
+ * Hard stops or resumes rendering into the surface. This flag is used to
+ * determine whether or not it is safe to use the given surface *at all*
+ */
+ void setStopped(boolean stopped) {
+ nSetStopped(mNativeProxy, stopped);
+ }
+
+ /**
* Destroys all hardware rendering resources associated with the specified
* view hierarchy.
*
@@ -794,8 +804,7 @@
}
final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
- int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length,
- mRootNode.mNativeRenderNode);
+ int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
setEnabled(false);
attachInfo.mViewRootImpl.mSurface.release();
@@ -989,13 +998,13 @@
private static native void nInitialize(long nativeProxy, Surface window);
private static native void nUpdateSurface(long nativeProxy, Surface window);
private static native boolean nPauseSurface(long nativeProxy, Surface window);
+ private static native void nSetStopped(long nativeProxy, boolean stopped);
private static native void nSetup(long nativeProxy, int width, int height,
float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
private static native void nSetLightCenter(long nativeProxy,
float lightX, float lightY, float lightZ);
private static native void nSetOpaque(long nativeProxy, boolean opaque);
- private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size,
- long rootRenderNode);
+ private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy, long rootRenderNode);
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b95d830..7e51096 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8877,7 +8877,7 @@
* @hide
*/
public void clearAccessibilityFocus() {
- clearAccessibilityFocusNoCallbacks();
+ clearAccessibilityFocusNoCallbacks(0);
// Clear the global reference of accessibility focus if this view or
// any of its descendants had accessibility focus. This will NOT send
@@ -8920,14 +8920,27 @@
/**
* Clears accessibility focus without calling any callback methods
* normally invoked in {@link #clearAccessibilityFocus()}. This method
- * is used for clearing accessibility focus when giving this focus to
- * another view.
+ * is used separately from that one for clearing accessibility focus when
+ * giving this focus to another view.
+ *
+ * @param action The action, if any, that led to focus being cleared. Set to
+ * AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS to specify that focus is moving within
+ * the window.
*/
- void clearAccessibilityFocusNoCallbacks() {
+ void clearAccessibilityFocusNoCallbacks(int action) {
if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
invalidate();
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+ event.setAction(action);
+ if (mAccessibilityDelegate != null) {
+ mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
+ } else {
+ sendAccessibilityEventUnchecked(event);
+ }
+ }
}
}
@@ -20424,21 +20437,21 @@
* the touch point.
* </p>
*
- * @param shadowSize A {@link android.graphics.Point} containing the width and height
+ * @param outShadowSize A {@link android.graphics.Point} containing the width and height
* of the shadow image. Your application must set {@link android.graphics.Point#x} to the
* desired width and must set {@link android.graphics.Point#y} to the desired height of the
* image.
*
- * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
+ * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
* shadow image that should be underneath the touch point during the drag and drop
* operation. Your application must set {@link android.graphics.Point#x} to the
* X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
*/
- public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
+ public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) {
final View view = mView.get();
if (view != null) {
- shadowSize.set(view.getWidth(), view.getHeight());
- shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
+ outShadowSize.set(view.getWidth(), view.getHeight());
+ outShadowTouchPoint.set(outShadowSize.x / 2, outShadowSize.y / 2);
} else {
Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
}
diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java
index 4c75935..3e277eb 100644
--- a/core/java/android/view/ViewAnimationUtils.java
+++ b/core/java/android/view/ViewAnimationUtils.java
@@ -41,6 +41,22 @@
* As a result {@link AnimatorListener#onAnimationEnd(Animator)}
* will occur after the animation has ended, but it may be delayed depending
* on thread responsiveness.
+ * <p>
+ * Note that if any start delay is set on the reveal animator, the start radius
+ * will not be applied to the reveal circle until the start delay has passed.
+ * If it's desired to set a start radius on the reveal circle during the start
+ * delay, one workaround could be adding an animator with the same start and
+ * end radius. For example:
+ * <pre><code>
+ * public static Animator createRevealWithDelay(View view, int centerX, int centerY, float startRadius, float endRadius) {
+ * Animator delayAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, startRadius);
+ * delayAnimator.setDuration(delayTimeMS);
+ * Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
+ * AnimatorSet set = new AnimatorSet();
+ * set.playSequentially(delayAnimator, revealAnimator);
+ * return set;
+ * }
+ * </code></pre>
*
* @param view The View will be clipped to the animating circle.
* @param centerX The x coordinate of the center of the animating circle, relative to
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5b2877f..94c4cef 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1079,13 +1079,16 @@
void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
+ final ThreadedRenderer renderer = mAttachInfo.mHardwareRenderer;
+ if (renderer != null) {
+ if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
+ renderer.setStopped(mStopped);
+ }
if (!mStopped) {
scheduleTraversals();
} else {
- if (mAttachInfo.mHardwareRenderer != null) {
- if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle());
- mAttachInfo.mHardwareRenderer.updateSurface(null);
- mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
+ if (renderer != null) {
+ renderer.destroyHardwareResources(mView);
}
}
}
@@ -3071,7 +3074,8 @@
// Clear accessibility focus on the host after clearing state since
// this method may be reentrant.
- focusHost.clearAccessibilityFocusNoCallbacks();
+ focusHost.clearAccessibilityFocusNoCallbacks(
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
AccessibilityNodeProvider provider = focusHost.getAccessibilityNodeProvider();
if (provider != null) {
@@ -3088,7 +3092,8 @@
}
if (mAccessibilityFocusedHost != null) {
// Clear accessibility focus in the view.
- mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks();
+ mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks(
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
// Set the new focus host and node.
@@ -6623,7 +6628,7 @@
// Error state: virtual view with no provider. Clear focus.
mAccessibilityFocusedHost = null;
mAccessibilityFocusedVirtualView = null;
- focusedHost.clearAccessibilityFocusNoCallbacks();
+ focusedHost.clearAccessibilityFocusNoCallbacks(0);
return;
}
@@ -6673,7 +6678,7 @@
if (mAccessibilityFocusedVirtualView == null) {
// Error state: The node no longer exists. Clear focus.
mAccessibilityFocusedHost = null;
- focusedHost.clearAccessibilityFocusNoCallbacks();
+ focusedHost.clearAccessibilityFocusNoCallbacks(0);
// This will probably fail, but try to keep the provider's internal
// state consistent by clearing focus.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c372c30..584233c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1240,6 +1240,13 @@
public static final int PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME = 0x00010000;
/**
+ * Flag to indicate that this window is always drawing the status bar background, no matter
+ * what the other flags are.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND = 0x00020000;
+
+ /**
* Control flags that are private to the platform.
* @hide
*/
@@ -1701,6 +1708,14 @@
*/
public int accessibilityIdOfAnchor = -1;
+ /**
+ * The window title isn't kept in sync with what is displayed in the title bar, so we
+ * separately track the currently shown title to provide to accessibility.
+ *
+ * @hide
+ */
+ public CharSequence accessibilityTitle;
+
public LayoutParams() {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = TYPE_APPLICATION;
@@ -1749,6 +1764,7 @@
title = "";
mTitle = TextUtils.stringOrSpannedString(title);
+ accessibilityTitle = mTitle;
}
public final CharSequence getTitle() {
@@ -1808,6 +1824,7 @@
out.writeInt(hasManualSurfaceInsets ? 1 : 0);
out.writeInt(needsMenuKey);
out.writeInt(accessibilityIdOfAnchor);
+ TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
}
public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -1859,6 +1876,7 @@
hasManualSurfaceInsets = in.readInt() != 0;
needsMenuKey = in.readInt();
accessibilityIdOfAnchor = in.readInt();
+ accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
}
@SuppressWarnings({"PointlessBitwiseExpression"})
@@ -1900,6 +1918,8 @@
/** {@hide} */
public static final int ACCESSIBILITY_ANCHOR_CHANGED = 1 << 24;
/** {@hide} */
+ public static final int ACCESSIBILITY_TITLE_CHANGED = 1 << 25;
+ /** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
@@ -2065,6 +2085,13 @@
changes |= ACCESSIBILITY_ANCHOR_CHANGED;
}
+ if (!Objects.equals(accessibilityTitle, o.accessibilityTitle)
+ && o.accessibilityTitle != null) {
+ // NOTE: accessibilityTitle only copied if the originator set one.
+ accessibilityTitle = o.accessibilityTitle;
+ changes |= ACCESSIBILITY_TITLE_CHANGED;
+ }
+
return changes;
}
diff --git a/core/java/android/webkit/WebViewProviderResponse.java b/core/java/android/webkit/WebViewProviderResponse.java
index f5e09e2..c0aeb59 100644
--- a/core/java/android/webkit/WebViewProviderResponse.java
+++ b/core/java/android/webkit/WebViewProviderResponse.java
@@ -21,7 +21,7 @@
import android.os.Parcelable;
/** @hide */
-public class WebViewProviderResponse implements Parcelable {
+public final class WebViewProviderResponse implements Parcelable {
public WebViewProviderResponse(PackageInfo packageInfo, int status) {
this.packageInfo = packageInfo;
@@ -56,6 +56,6 @@
out.writeInt(status);
}
- PackageInfo packageInfo;
- int status;
+ public final PackageInfo packageInfo;
+ public final int status;
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a4e489c..ed6ab56 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -41,12 +41,12 @@
import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
-import android.provider.DocumentsContract;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.service.chooser.IChooserTargetResult;
@@ -70,6 +70,7 @@
import com.android.internal.R;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.google.android.collect.Lists;
import java.io.File;
import java.util.ArrayList;
@@ -89,6 +90,7 @@
private IntentSender mChosenComponentSender;
private IntentSender mRefinementIntentSender;
private RefinementResultReceiver mRefinementResultReceiver;
+ private ChooserTarget[] mCallerChooserTargets;
private Intent mReferrerFillInIntent;
@@ -97,6 +99,7 @@
private SharedPreferences mPinnedSharedPrefs;
private static final float PINNED_TARGET_SCORE_BOOST = 1000.f;
+ private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
private static final String PINNED_SHARED_PREFS_NAME = "chooser_pin_settings";
private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment";
@@ -219,6 +222,34 @@
Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER);
setSafeForwardingMode(true);
+ pa = intent.getParcelableArrayExtra(Intent.EXTRA_EXCLUDE_COMPONENTS);
+ if (pa != null) {
+ ComponentName[] names = new ComponentName[pa.length];
+ for (int i = 0; i < pa.length; i++) {
+ if (!(pa[i] instanceof ComponentName)) {
+ Log.w(TAG, "Filtered component #" + i + " not a ComponentName: " + pa[i]);
+ names = null;
+ break;
+ }
+ names[i] = (ComponentName) pa[i];
+ }
+ setFilteredComponents(names);
+ }
+
+ pa = intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_TARGETS);
+ if (pa != null) {
+ ChooserTarget[] targets = new ChooserTarget[pa.length];
+ for (int i = 0; i < pa.length; i++) {
+ if (!(pa[i] instanceof ChooserTarget)) {
+ Log.w(TAG, "Chooser target #" + i + " not a ChooserTarget: " + pa[i]);
+ targets = null;
+ break;
+ }
+ targets[i] = (ChooserTarget) pa[i];
+ }
+ mCallerChooserTargets = targets;
+ }
+
mPinnedSharedPrefs = getPinnedSharedPrefs(this);
super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
null, false);
@@ -292,6 +323,9 @@
boolean alwaysUseOption) {
final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
mChooserListAdapter = (ChooserListAdapter) adapter;
+ if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
+ mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets));
+ }
mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView));
adapterView.setAdapter(mChooserRowAdapter);
@@ -427,13 +461,19 @@
continue;
}
} catch (NameNotFoundException e) {
- Log.e(TAG, "Could not look up service " + serviceComponent, e);
+ Log.e(TAG, "Could not look up service " + serviceComponent
+ + "; component name not found");
continue;
}
final ChooserTargetServiceConnection conn =
new ChooserTargetServiceConnection(this, dri);
- if (bindService(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND)) {
+
+ // Explicitly specify Process.myUserHandle instead of calling bindService
+ // to avoid the warning from calling from the system process without an explicit
+ // user handle
+ if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND,
+ Process.myUserHandle())) {
if (DEBUG) {
Log.d(TAG, "Binding service connection for target " + dri
+ " intent " + serviceIntent);
@@ -635,7 +675,11 @@
if (mSourceInfo != null) {
return mSourceInfo.getResolvedIntent();
}
- return getTargetIntent();
+
+ final Intent targetIntent = new Intent(getTargetIntent());
+ targetIntent.setComponent(mChooserTarget.getComponentName());
+ targetIntent.putExtras(mChooserTarget.getIntentExtras());
+ return targetIntent;
}
@Override
@@ -650,8 +694,7 @@
}
private Intent getBaseIntentToSend() {
- Intent result = mSourceInfo != null
- ? mSourceInfo.getResolvedIntent() : getTargetIntent();
+ Intent result = getResolvedIntent();
if (result == null) {
Log.e(TAG, "ChooserTargetInfo: no base intent available to send");
} else {
@@ -677,7 +720,19 @@
}
intent.setComponent(mChooserTarget.getComponentName());
intent.putExtras(mChooserTarget.getIntentExtras());
- activity.startActivityAsCaller(intent, options, true, userId);
+
+ // Important: we will ignore the target security checks in ActivityManager
+ // if and only if the ChooserTarget's target package is the same package
+ // where we got the ChooserTargetService that provided it. This lets a
+ // ChooserTargetService provide a non-exported or permission-guarded target
+ // to the chooser for the user to pick.
+ //
+ // If mSourceInfo is null, we got this ChooserTarget from the caller or elsewhere
+ // so we'll obey the caller's normal security checks.
+ final boolean ignoreTargetSecurity = mSourceInfo != null
+ && mSourceInfo.getResolvedComponentName().getPackageName()
+ .equals(mChooserTarget.getComponentName().getPackageName());
+ activity.startActivityAsCaller(intent, options, ignoreTargetSecurity, userId);
return true;
}
@@ -810,6 +865,9 @@
@Override
public float getScore(DisplayResolveInfo target) {
+ if (target == null) {
+ return CALLER_TARGET_SCORE_BOOST;
+ }
float score = super.getScore(target);
if (target.isPinned()) {
score += PINNED_TARGET_SCORE_BOOST;
@@ -1281,7 +1339,7 @@
}
static class ChooserTargetServiceConnection implements ServiceConnection {
- private final DisplayResolveInfo mOriginalTarget;
+ private DisplayResolveInfo mOriginalTarget;
private ComponentName mConnectedComponent;
private ChooserActivity mChooserActivity;
private final Object mLock = new Object();
@@ -1359,6 +1417,7 @@
public void destroy() {
synchronized (mLock) {
mChooserActivity = null;
+ mOriginalTarget = null;
}
}
@@ -1366,7 +1425,9 @@
public String toString() {
return "ChooserTargetServiceConnection{service="
+ mConnectedComponent + ", activity="
- + mOriginalTarget.getResolveInfo().activityInfo.toString() + "}";
+ + (mOriginalTarget != null
+ ? mOriginalTarget.getResolveInfo().activityInfo.toString()
+ : "<connection destroyed>") + "}";
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ff680e2..f2bf9e1 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -105,6 +105,7 @@
private final ArrayList<Intent> mIntents = new ArrayList<>();
private ResolverComparator mResolverComparator;
private PickTargetOptionRequest mPickOptionRequest;
+ private ComponentName[] mFilteredComponents;
protected ResolverDrawerLayout mResolverDrawerLayout;
@@ -332,6 +333,24 @@
}
}
+ public final void setFilteredComponents(ComponentName[] components) {
+ mFilteredComponents = components;
+ }
+
+ public final boolean isComponentFiltered(ComponentInfo component) {
+ if (mFilteredComponents == null) {
+ return false;
+ }
+
+ final ComponentName checkName = component.getComponentName();
+ for (ComponentName name : mFilteredComponents) {
+ if (name.equals(checkName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Perform any initialization needed for voice interaction.
*/
@@ -1269,7 +1288,8 @@
ai.applicationInfo.uid, ai.exported);
boolean suspended = (ai.applicationInfo.flags
& ApplicationInfo.FLAG_SUSPENDED) != 0;
- if (granted != PackageManager.PERMISSION_GRANTED || suspended) {
+ if (granted != PackageManager.PERMISSION_GRANTED || suspended
+ || isComponentFiltered(ai)) {
// Access not allowed!
if (mOrigResolveList == currentResolveList) {
mOrigResolveList = new ArrayList<>(mOrigResolveList);
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index f6fbaab..27588e9 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -53,6 +54,7 @@
private int mUserId;
private int mReason;
+ private IntentSender mTarget;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -60,6 +62,7 @@
Intent intent = getIntent();
mReason = intent.getIntExtra(EXTRA_UNLAUNCHABLE_REASON, -1);
mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT);
if (mUserId == UserHandle.USER_NULL) {
Log.wtf(TAG, "Invalid user id: " + mUserId + ". Stopping.");
@@ -105,6 +108,14 @@
public void onClick(DialogInterface dialog, int which) {
if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE && which == DialogInterface.BUTTON_POSITIVE) {
UserManager.get(this).setQuietModeEnabled(mUserId, false);
+
+ if (mTarget != null) {
+ try {
+ startIntentSenderForResult(mTarget, -1, null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ /* ignore */
+ }
+ }
}
}
@@ -121,4 +132,10 @@
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
return intent;
}
+
+ public static Intent createInQuietModeDialogIntent(int userId, IntentSender target) {
+ Intent intent = createInQuietModeDialogIntent(userId);
+ intent.putExtra(Intent.EXTRA_INTENT, target);
+ return intent;
+ }
}
diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
index 7252276..76102af 100644
--- a/core/java/com/android/internal/app/procstats/SparseMappingTable.java
+++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
@@ -372,29 +372,35 @@
* 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. -- "
- + dumpInternalState());
- return;
- }
+ // Something with this checking isn't working and is triggering
+ // more problems than it's helping to debug.
+ // Original bug: b/27045736
+ // New bug: b/27960286
+ if (false) {
+ // Assert that our sequence 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. -- "
+ + dumpInternalState());
+ return;
+ }
- // 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());
- return;
- } else if (mSequence > mParent.mSequence) {
- logOrThrow("Sequence mismatch. Table.resetTable()"
- + " called but not SparseMappingTable.resetTable() -- "
- + dumpInternalState());
- return;
+ // 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());
+ return;
+ } else if (mSequence > mParent.mSequence) {
+ logOrThrow("Sequence mismatch. Table.resetTable()"
+ + " called but not SparseMappingTable.resetTable() -- "
+ + dumpInternalState());
+ return;
+ }
}
}
}
@@ -623,7 +629,7 @@
* this is an eng build.)
*/
private static void logOrThrow(String message, Throwable th) {
- Slog.wtf(TAG, message, th);
+ Slog.e(TAG, message, th);
if (Build.TYPE.equals("eng")) {
throw new RuntimeException(message, th);
}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index 85cc841..46b49de 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -285,7 +285,7 @@
}
public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
- InputMethodInfo imi, InputMethodSubtype subtype) {
+ InputMethodInfo imi, InputMethodSubtype subtype, boolean forward) {
if (imi == null) {
return null;
}
@@ -297,8 +297,9 @@
return null;
}
final int N = mImeSubtypeList.size();
- for (int offset = 1; offset < N; ++offset) {
+ for (int i = 1; i < N; ++i) {
// Start searching the next IME/subtype from the next of the current index.
+ final int offset = forward ? i : N - i;
final int candidateIndex = (currentIndex + offset) % N;
final ImeSubtypeListItem candidate = mImeSubtypeList.get(candidateIndex);
// Skip if searching inside the current IME only, but the candidate is not
@@ -371,7 +372,7 @@
}
public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
- InputMethodInfo imi, InputMethodSubtype subtype) {
+ InputMethodInfo imi, InputMethodSubtype subtype, boolean forward) {
int currentUsageRank = getUsageRank(imi, subtype);
if (currentUsageRank < 0) {
if (DEBUG) {
@@ -381,7 +382,8 @@
}
final int N = mUsageHistoryOfSubtypeListItemIndex.length;
for (int i = 1; i < N; i++) {
- final int subtypeListItemRank = (currentUsageRank + i) % N;
+ final int offset = forward ? i : N - i;
+ final int subtypeListItemRank = (currentUsageRank + offset) % N;
final int subtypeListItemIndex =
mUsageHistoryOfSubtypeListItemIndex[subtypeListItemRank];
final ImeSubtypeListItem subtypeListItem =
@@ -455,16 +457,16 @@
}
public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme, InputMethodInfo imi,
- InputMethodSubtype subtype) {
+ InputMethodSubtype subtype, boolean forward) {
if (imi == null) {
return null;
}
if (imi.supportsSwitchingToNextInputMethod()) {
return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
- subtype);
+ subtype, forward);
} else {
return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
- subtype);
+ subtype, forward);
}
}
@@ -532,14 +534,14 @@
}
public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
- InputMethodSubtype subtype) {
+ InputMethodSubtype subtype, boolean forward) {
if (mController == null) {
if (DEBUG) {
Log.e(TAG, "mController shouldn't be null.");
}
return null;
}
- return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
+ return mController.getNextInputMethod(onlyCurrentIme, imi, subtype, forward);
}
public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index 2a9264d..47f2c70 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -103,21 +103,7 @@
}
}
- public void execute(String cmd, Object... args) throws InstallerException {
- final String resRaw = executeForResult(cmd, args);
- int res = -1;
- try {
- res = Integer.parseInt(resRaw);
- } catch (NumberFormatException ignored) {
- }
- if (res != 0) {
- throw new InstallerException(
- "Failed to execute " + cmd + " " + Arrays.toString(args) + ": " + res);
- }
- }
-
- public String executeForResult(String cmd, Object... args)
- throws InstallerException {
+ public String[] execute(String cmd, Object... args) throws InstallerException {
final StringBuilder builder = new StringBuilder(cmd);
for (Object arg : args) {
String escaped;
@@ -135,7 +121,17 @@
}
builder.append(' ').append(escaped);
}
- return transact(builder.toString());
+ final String[] resRaw = transact(builder.toString()).split(" ");
+ int res = -1;
+ try {
+ res = Integer.parseInt(resRaw[0]);
+ } catch (ArrayIndexOutOfBoundsException | NumberFormatException ignored) {
+ }
+ if (res != 0) {
+ throw new InstallerException(
+ "Failed to execute " + cmd + " " + Arrays.toString(args) + ": " + res);
+ }
+ return resRaw;
}
public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
@@ -160,19 +156,15 @@
}
public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
- String rawReply = executeForResult("merge_profiles", uid, pkgName);
- if (rawReply == null) {
- throw new IllegalStateException("Unexpected null reply");
- }
- final String res[] = rawReply.split(" ");
+ final String[] res = execute("merge_profiles", uid, pkgName);
if ((res == null) || (res.length != 2)) {
- throw new InstallerException("Invalid size result: " + rawReply);
+ throw new InstallerException("Invalid size result: " + Arrays.toString(res));
}
// Just as a sanity check. Anything != "true" will be interpreted as false by parseBoolean.
if (!res[1].equals("true") && !res[1].equals("false")) {
- throw new InstallerException("Invalid boolean result: " + rawReply);
+ throw new InstallerException("Invalid boolean result: " + Arrays.toString(res));
}
return Boolean.parseBoolean(res[1]);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index ea0fbda..f9ac563 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -45,7 +45,6 @@
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -81,6 +80,8 @@
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.N;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getMode;
@@ -171,7 +172,7 @@
private final Interpolator mShowInterpolator;
private final Interpolator mHideInterpolator;
private final int mBarEnterExitDuration;
- private final boolean mForceWindowDrawsStatusBarBackground;
+ final boolean mForceWindowDrawsStatusBarBackground;
private final int mSemiTransparentStatusBarColor;
private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
@@ -236,7 +237,8 @@
mBarEnterExitDuration = context.getResources().getInteger(
R.integer.dock_enter_exit_duration);
mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean(
- R.bool.config_forceWindowDrawsStatusBarBackground);
+ R.bool.config_forceWindowDrawsStatusBarBackground)
+ && context.getApplicationInfo().targetSdkVersion >= N;
mSemiTransparentStatusBarColor = context.getResources().getColor(
R.color.system_bar_background_semi_transparent, null /* theme */);
@@ -1458,6 +1460,8 @@
st.menu.close();
}
+ releaseThreadedRenderer();
+
if (mWindowResizeCallbacksAdded) {
getViewRootImpl().removeWindowCallbacks(this);
mWindowResizeCallbacksAdded = false;
@@ -2208,7 +2212,7 @@
public void onDestroyActionMode(ActionMode mode) {
mWrapped.onDestroyActionMode(mode);
final boolean isMncApp = mContext.getApplicationInfo().targetSdkVersion
- >= Build.VERSION_CODES.M;
+ >= M;
final boolean isPrimary;
final boolean isFloating;
if (isMncApp) {
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 9907ea9..669e1ef 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -17,9 +17,13 @@
package com.android.internal.policy;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.util.Log;
+import android.view.Display;
+import android.view.DisplayInfo;
import java.util.ArrayList;
@@ -57,6 +61,7 @@
private final ArrayList<SnapTarget> mTargets = new ArrayList<>();
private final Rect mInsets = new Rect();
private final int mSnapMode;
+ private final int mMinimalSizeResizableTask;
private final float mFixedRatio;
private boolean mIsHorizontalDivision;
@@ -70,6 +75,22 @@
private final SnapTarget mDismissEndTarget;
private final SnapTarget mMiddleTarget;
+ public static DividerSnapAlgorithm create(Context ctx, Rect insets) {
+ DisplayInfo displayInfo = new DisplayInfo();
+ ctx.getSystemService(DisplayManager.class).getDisplay(
+ Display.DEFAULT_DISPLAY).getDisplayInfo(displayInfo);
+ int dividerWindowWidth = ctx.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.docked_stack_divider_thickness);
+ int dividerInsets = ctx.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.docked_stack_divider_insets);
+ return new DividerSnapAlgorithm(ctx.getResources(),
+ displayInfo.logicalWidth, displayInfo.logicalHeight,
+ dividerWindowWidth - 2 * dividerInsets,
+ ctx.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT,
+ insets);
+ }
+
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
boolean isHorizontalDivision, Rect insets) {
mMinFlingVelocityPxPerSecond =
@@ -85,6 +106,8 @@
com.android.internal.R.integer.config_dockedStackDividerSnapMode);
mFixedRatio = res.getFraction(
com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
+ mMinimalSizeResizableTask = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.default_minimal_size_resizable_task);
calculateTargets(isHorizontalDivision);
mFirstSplitTarget = mTargets.get(1);
mLastSplitTarget = mTargets.get(mTargets.size() - 2);
@@ -93,6 +116,20 @@
mMiddleTarget = mTargets.get(mTargets.size() / 2);
}
+ /**
+ * @return whether it's feasible to enable split screen in the current configuration, i.e. when
+ * snapping in the middle both tasks are larger than the minimal task size.
+ */
+ public boolean isSplitScreenFeasible() {
+ int statusBarSize = mInsets.top;
+ int navBarSize = mIsHorizontalDivision ? mInsets.bottom : mInsets.right;
+ int size = mIsHorizontalDivision
+ ? mDisplayHeight
+ : mDisplayWidth;
+ int availableSpace = size - navBarSize - statusBarSize - mDividerSize;
+ return availableSpace / 2 >= mMinimalSizeResizableTask;
+ }
+
public SnapTarget calculateSnapTarget(int position, float velocity) {
return calculateSnapTarget(position, velocity, true /* hardDismiss */);
}
@@ -212,10 +249,10 @@
mTargets.add(new SnapTarget(-mDividerSize, SnapTarget.FLAG_DISMISS_START, 0.35f));
switch (mSnapMode) {
case SNAP_MODE_16_9:
- addRatio16_9Targets(isHorizontalDivision);
+ addRatio16_9Targets(isHorizontalDivision, dividerMax);
break;
case SNAP_FIXED_RATIO:
- addFixedDivisionTargets(isHorizontalDivision);
+ addFixedDivisionTargets(isHorizontalDivision, dividerMax);
break;
case SNAP_ONLY_1_1:
addMiddleTarget(isHorizontalDivision);
@@ -225,19 +262,24 @@
mTargets.add(new SnapTarget(dividerMax - navBarSize, SnapTarget.FLAG_DISMISS_END, 0.35f));
}
- private void addFixedDivisionTargets(boolean isHorizontalDivision) {
+ private void addNonDismissingTargets(boolean isHorizontalDivision, int topPosition,
+ int bottomPosition, int dividerMax) {
+ maybeAddTarget(topPosition, topPosition - mInsets.top);
+ addMiddleTarget(isHorizontalDivision);
+ maybeAddTarget(bottomPosition, dividerMax - mInsets.bottom
+ - (bottomPosition + mDividerSize));
+ }
+ private void addFixedDivisionTargets(boolean isHorizontalDivision, int dividerMax) {
int start = isHorizontalDivision ? mInsets.top : mInsets.left;
int end = isHorizontalDivision
? mDisplayHeight - mInsets.bottom
: mDisplayWidth - mInsets.right;
- mTargets.add(new SnapTarget((int) (start + mFixedRatio * (end - start)) - mDividerSize / 2,
- SnapTarget.FLAG_NONE));
- addMiddleTarget(isHorizontalDivision);
- mTargets.add(new SnapTarget((int) (start + (1 - mFixedRatio) * (end - start))
- - mDividerSize / 2, SnapTarget.FLAG_NONE));
+ int topPosition = (int) (start + mFixedRatio * (end - start)) - mDividerSize / 2;
+ int bottomPosition = (int) (start + (1 - mFixedRatio) * (end - start)) - mDividerSize / 2;
+ addNonDismissingTargets(isHorizontalDivision, topPosition, bottomPosition, dividerMax);
}
- private void addRatio16_9Targets(boolean isHorizontalDivision) {
+ private void addRatio16_9Targets(boolean isHorizontalDivision, int dividerMax) {
int start = isHorizontalDivision ? mInsets.top : mInsets.left;
int end = isHorizontalDivision
? mDisplayHeight - mInsets.bottom
@@ -248,9 +290,19 @@
: mDisplayHeight - mInsets.bottom;
float size = 9.0f / 16.0f * (endOther - startOther);
int sizeInt = (int) Math.floor(size);
- mTargets.add(new SnapTarget(start + sizeInt, SnapTarget.FLAG_NONE));
- addMiddleTarget(isHorizontalDivision);
- mTargets.add(new SnapTarget(end - sizeInt - mDividerSize, SnapTarget.FLAG_NONE));
+ int topPosition = start + sizeInt;
+ int bottomPosition = end - sizeInt - mDividerSize;
+ addNonDismissingTargets(isHorizontalDivision, topPosition, bottomPosition, dividerMax);
+ }
+
+ /**
+ * Adds a target at {@param position} but only if the area with size of {@param smallerSize}
+ * meets the minimal size requirement.
+ */
+ private void maybeAddTarget(int position, int smallerSize) {
+ if (smallerSize >= mMinimalSizeResizableTask) {
+ mTargets.add(new SnapTarget(position, SnapTarget.FLAG_NONE));
+ }
}
private void addMiddleTarget(boolean isHorizontalDivision) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 0f257d7..d2ff9bc4 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -516,8 +516,8 @@
}
mTitle = title;
WindowManager.LayoutParams params = getAttributes();
- if (!TextUtils.equals(title, params.getTitle())) {
- params.setTitle(title);
+ if (!TextUtils.equals(title, params.accessibilityTitle)) {
+ params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
dispatchWindowAttributesChanged(getAttributes());
}
}
@@ -2435,6 +2435,8 @@
mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
}
+ WindowManager.LayoutParams params = getAttributes();
+
// Non-floating windows on high end devices must put up decor beneath the system bars and
// therefore must know about visibility changes of those.
if (!mIsFloating && ActivityManager.isHighEndGfx()) {
@@ -2444,6 +2446,9 @@
setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
}
+ if (mDecor.mForceWindowDrawsStatusBarBackground) {
+ params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+ }
}
if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
decor.setSystemUiVisibility(
@@ -2459,8 +2464,6 @@
}
}
- WindowManager.LayoutParams params = getAttributes();
-
if (!hasSoftInputMode()) {
params.softInputMode = a.getInt(
R.styleable.Window_windowSoftInputMode,
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index bed5a2e..18f715e 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -27,6 +27,7 @@
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -128,7 +129,7 @@
/**
* Checks if given array is null or has zero elements.
*/
- public static boolean isEmpty(@Nullable List<?> array) {
+ public static boolean isEmpty(@Nullable Collection<?> array) {
return array == null || array.isEmpty();
}
@@ -451,7 +452,7 @@
}
}
- public static <T> boolean contains(@Nullable ArrayList<T> cur, T val) {
+ public static <T> boolean contains(@Nullable Collection<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index 29a9c8e..ddca51f 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -346,7 +346,15 @@
private void showMenu(@NonNull MenuBuilder menu) {
final LayoutInflater inflater = LayoutInflater.from(mContext);
final MenuAdapter adapter = new MenuAdapter(menu, inflater, mOverflowOnly);
- adapter.setForceShowIcon(mForceShowIcon);
+
+ // Apply "force show icon" setting; if the menu being shown is the top level menu, apply the
+ // setting set on this CascadingMenuPopup by its creating code. If it's a submenu, or if no
+ // "force" setting was explicitly set, determine the setting by examining the items.
+ if (!isShowing() && mForceShowIcon) {
+ adapter.setForceShowIcon(mForceShowIcon);
+ } else {
+ adapter.setForceShowIcon(MenuPopup.shouldPreserveIconSpacing(menu));
+ }
final int menuWidth = measureIndividualMenuWidth(adapter, null, mContext, mMenuMaxWidth);
final MenuPopupWindow popupWindow = createPopupWindow();
diff --git a/core/java/com/android/internal/view/menu/MenuPopup.java b/core/java/com/android/internal/view/menu/MenuPopup.java
index 42b1a56..16e4156 100644
--- a/core/java/com/android/internal/view/menu/MenuPopup.java
+++ b/core/java/com/android/internal/view/menu/MenuPopup.java
@@ -183,4 +183,25 @@
}
return (MenuAdapter) adapter;
}
+
+ /**
+ * Returns whether icon spacing needs to be preserved for the given menu, based on whether any
+ * of its items contains an icon.
+ * @param menu
+ * @return Whether to preserve icon spacing.
+ */
+ protected static boolean shouldPreserveIconSpacing(MenuBuilder menu) {
+ boolean preserveIconSpacing = false;
+ final int count = menu.size();
+
+ for (int i = 0; i < count; i++) {
+ MenuItem childItem = menu.getItem(i);
+ if (childItem.isVisible() && childItem.getIcon() != null) {
+ preserveIconSpacing = true;
+ break;
+ }
+ }
+
+ return preserveIconSpacing;
+ }
}
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index 8ced36f..339c2bf 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -208,7 +208,7 @@
@Override
public void show() {
if (!tryShow()) {
- throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
+ throw new IllegalStateException("StandardMenuPopup cannot be used without an anchor");
}
}
@@ -266,14 +266,14 @@
final MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu,
mShownAnchorView, mOverflowOnly, mPopupStyleAttr, mPopupStyleRes);
subPopup.setPresenterCallback(mPresenterCallback);
- subPopup.setForceShowIcon(mAdapter.getForceShowIcon());
+ subPopup.setForceShowIcon(MenuPopup.shouldPreserveIconSpacing(subMenu));
// Pass responsibility for handling onDismiss to the submenu.
subPopup.setOnDismissListener(mOnDismissListener);
mOnDismissListener = null;
// Close this menu popup to make room for the submenu popup.
- dismiss();
+ mMenu.close(false /* closeAllMenus */);
// Show the new sub-menu popup at the same location as this popup.
if (subPopup.tryShow(mXOffset, mYOffset)) {
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index b07e36a..21c4d12 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -33,9 +33,12 @@
void setLockPassword(in String password, in String savedPassword, int userId);
VerifyCredentialResponse checkPassword(in String password, int userId);
VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId);
+ VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, int userId);
boolean checkVoldPassword(int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
+ void setSeparateProfileChallengeEnabled(int userId, boolean enabled, String managedUserPassword);
+ boolean getSeparateProfileChallengeEnabled(int userId);
void registerStrongAuthTracker(in IStrongAuthTracker tracker);
void unregisterStrongAuthTracker(in IStrongAuthTracker tracker);
void requireStrongAuth(int strongAuthReason, int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index 4880664..713f56f 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -145,6 +145,43 @@
}
/**
+ * Verify a password asynchronously.
+ *
+ * @param utils The LockPatternUtils instance to use.
+ * @param password The password to check.
+ * @param challenge The challenge to verify against the pattern.
+ * @param userId The user to check against the pattern.
+ * @param callback The callback to be invoked with the verification result.
+ */
+ public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils,
+ final String password,
+ final boolean isPattern,
+ final long challenge,
+ final int userId,
+ final OnVerifyCallback callback) {
+ AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
+ private int mThrottleTimeout;
+
+ @Override
+ protected byte[] doInBackground(Void... args) {
+ try {
+ return utils.verifyTiedProfileChallenge(password, isPattern, challenge, userId);
+ } catch (RequestThrottledException ex) {
+ mThrottleTimeout = ex.getTimeoutMs();
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(byte[] result) {
+ callback.onVerified(result, mThrottleTimeout);
+ }
+ };
+ task.execute();
+ return task;
+ }
+
+ /**
* Checks a password asynchronously.
*
* @param utils The LockPatternUtils instance to use.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3d892af..bceeaca 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -137,8 +137,6 @@
private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
- private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
-
// Maximum allowed number of repeated or ordered characters in a sequence before we'll
// consider it a complex PIN/password.
public static final int MAX_ALLOWED_SEQUENCE = 3;
@@ -377,6 +375,36 @@
}
}
+
+ /**
+ * Check to see if a password matches the saved password.
+ * If password matches, return an opaque attestation that the challenge
+ * was verified.
+ *
+ * @param password The password to check.
+ * @param challenge The challenge to verify against the password
+ * @return the attestation that the challenge was verified, or null.
+ */
+ public byte[] verifyTiedProfileChallenge(String password, boolean isPattern, long challenge,
+ int userId) throws RequestThrottledException {
+ throwIfCalledOnMainThread();
+ try {
+ VerifyCredentialResponse response =
+ getLockSettings().verifyTiedProfileChallenge(password, isPattern, challenge,
+ userId);
+
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ return response.getPayload();
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ throw new RequestThrottledException(response.getTimeout());
+ } else {
+ return null;
+ }
+ } catch (RemoteException re) {
+ return null;
+ }
+ }
+
/**
* Check to see if a password matches the saved password. If no password exists,
* always returns true.
@@ -785,6 +813,7 @@
}
getLockSettings().setLockPassword(password, savedPassword, userHandle);
+ getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null);
int computedQuality = computePasswordQuality(password);
// Update the device encryption password.
@@ -919,11 +948,23 @@
/**
* Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op
* for user handles that do not belong to a managed profile.
+ *
+ * @param userHandle Managed profile user id
+ * @param enabled True if separate challenge is enabled
+ * @param managedUserPassword Managed profile previous password. Null when {@param enabled} is
+ * true
*/
- public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled) {
+ public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled,
+ String managedUserPassword) {
UserInfo info = getUserManager().getUserInfo(userHandle);
if (info.isManagedProfile()) {
- setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userHandle);
+ try {
+ getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled,
+ managedUserPassword);
+ onAfterChangingPassword(userHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't update work profile challenge enabled");
+ }
}
}
@@ -935,7 +976,13 @@
if (info == null || !info.isManagedProfile()) {
return false;
}
- return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userHandle);
+ try {
+ return getLockSettings().getSeparateProfileChallengeEnabled(userHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get separate profile challenge enabled");
+ // Default value is false
+ return false;
+ }
}
/**
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 6dc251c..1c2d13d 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -53,36 +53,14 @@
fontFamily->Unref();
}
-static jboolean addSkTypeface(FontFamily* family, SkTypeface* face) {
- MinikinFont* minikinFont = new MinikinFontSkia(face);
+static jboolean addSkTypeface(FontFamily* family, SkTypeface* face, const void* fontData,
+ size_t fontSize, int ttcIndex) {
+ MinikinFont* minikinFont = new MinikinFontSkia(face, fontData, fontSize, ttcIndex);
bool result = family->addFont(minikinFont);
minikinFont->Unref();
return result;
}
-static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path,
- jint ttcIndex) {
- NPE_CHECK_RETURN_ZERO(env, path);
- ScopedUtfChars str(env, path);
- SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex);
- if (face == NULL) {
- ALOGE("addFont failed to create font %s", str.c_str());
- return false;
- }
- FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
- return addSkTypeface(fontFamily, face);
-}
-
-static struct {
- jmethodID mGet;
- jmethodID mSize;
-} gListClassInfo;
-
-static struct {
- jfieldID mTag;
- jfieldID mStyleValue;
-} gAxisClassInfo;
-
static void release_global_ref(const void* /*data*/, void* context) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
bool needToAttach = (env == NULL);
@@ -106,6 +84,47 @@
}
}
+static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jobject bytebuf,
+ jint ttcIndex) {
+ NPE_CHECK_RETURN_ZERO(env, bytebuf);
+ const void* fontPtr = env->GetDirectBufferAddress(bytebuf);
+ if (fontPtr == NULL) {
+ ALOGE("addFont failed to create font, buffer invalid");
+ return false;
+ }
+ jlong fontSize = env->GetDirectBufferCapacity(bytebuf);
+ if (fontSize < 0) {
+ ALOGE("addFont failed to create font, buffer size invalid");
+ return false;
+ }
+ jobject fontRef = MakeGlobalRefOrDie(env, bytebuf);
+ SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize,
+ release_global_ref, reinterpret_cast<void*>(fontRef)));
+ std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data));
+
+ SkFontMgr::FontParameters params;
+ params.setCollectionIndex(ttcIndex);
+
+ SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+ SkTypeface* face = fm->createFromStream(fontData.release(), params);
+ if (face == NULL) {
+ ALOGE("addFont failed to create font");
+ return false;
+ }
+ FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
+ return addSkTypeface(fontFamily, face, fontPtr, (size_t)fontSize, ttcIndex);
+}
+
+static struct {
+ jmethodID mGet;
+ jmethodID mSize;
+} gListClassInfo;
+
+static struct {
+ jfieldID mTag;
+ jfieldID mStyleValue;
+} gAxisClassInfo;
+
static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr,
jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
NPE_CHECK_RETURN_ZERO(env, font);
@@ -133,7 +152,7 @@
}
}
- void* fontPtr = env->GetDirectBufferAddress(font);
+ const void* fontPtr = env->GetDirectBufferAddress(font);
if (fontPtr == NULL) {
ALOGE("addFont failed to create font, buffer invalid");
return false;
@@ -159,7 +178,7 @@
return false;
}
FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
- MinikinFont* minikinFont = new MinikinFontSkia(face);
+ MinikinFont* minikinFont = new MinikinFontSkia(face, fontPtr, (size_t)fontSize, ttcIndex);
fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic));
minikinFont->Unref();
return true;
@@ -191,6 +210,7 @@
return false;
}
+ size_t bufSize = asset->getLength();
SkAutoTUnref<SkData> data(SkData::NewWithProc(buf, asset->getLength(), releaseAsset, asset));
SkMemoryStream* stream = new SkMemoryStream(data);
// CreateFromStream takes ownership of stream.
@@ -200,7 +220,7 @@
return false;
}
FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
- return addSkTypeface(fontFamily, face);
+ return addSkTypeface(fontFamily, face, buf, bufSize, /* ttcIndex */ 0);
}
///////////////////////////////////////////////////////////////////////////////
@@ -208,7 +228,7 @@
static const JNINativeMethod gFontFamilyMethods[] = {
{ "nCreateFamily", "(Ljava/lang/String;I)J", (void*)FontFamily_create },
{ "nUnrefFamily", "(J)V", (void*)FontFamily_unref },
- { "nAddFont", "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont },
+ { "nAddFont", "(JLjava/nio/ByteBuffer;I)Z", (void*)FontFamily_addFont },
{ "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z",
(void*)FontFamily_addFontWeightStyle },
{ "nAddFontFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp
index b04293e..e5c4a2d 100644
--- a/core/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -176,6 +176,9 @@
PathParser::ParseResult result;
PathData data;
PathParser::getPathDataFromString(&data, &result, pathString, stringLength);
+ if (result.failureOccurred) {
+ doThrowIAE(env, result.failureMessage.c_str());
+ }
path->mutateStagingProperties()->setData(data);
env->ReleaseStringUTFChars(inputStr, pathString);
}
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index 80ae550..91a3b4f 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -382,6 +382,9 @@
char *msg, int msgLen) {
int retVal;
+ //ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d",
+ // hubHandle, msgType, msgLen);
+
switch(msgType) {
case CONTEXT_HUB_APPS_ENABLE:
retVal = 0;
@@ -633,7 +636,7 @@
if (numHeaderElements >= MSG_HEADER_SIZE) {
- int setAddressSuccess;
+ bool setAddressSuccess;
int hubId;
hub_message_t msg;
@@ -654,7 +657,7 @@
ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d",
header[HEADER_FIELD_APP_INSTANCE],
header[HEADER_FIELD_HUB_HANDLE],
- setAddressSuccess);
+ (int)setAddressSuccess);
}
} else {
ALOGD("Malformed header len");
diff --git a/core/jni/android_util_PathParser.cpp b/core/jni/android_util_PathParser.cpp
index 0927120..0c867f1 100644
--- a/core/jni/android_util_PathParser.cpp
+++ b/core/jni/android_util_PathParser.cpp
@@ -15,6 +15,7 @@
*/
#include "jni.h"
+#include "GraphicsJNI.h"
#include <PathParser.h>
#include <SkPath.h>
@@ -27,7 +28,7 @@
using namespace uirenderer;
-static bool parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
+static void parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
jint strLength) {
const char* pathString = env->GetStringUTFChars(inputPathStr, NULL);
SkPath* skPath = reinterpret_cast<SkPath*>(skPathHandle);
@@ -36,9 +37,8 @@
PathParser::parseStringForSkPath(skPath, &result, pathString, strLength);
env->ReleaseStringUTFChars(inputPathStr, pathString);
if (result.failureOccurred) {
- ALOGE(result.failureMessage.c_str());
+ doThrowIAE(env, result.failureMessage.c_str());
}
- return !result.failureOccurred;
}
static long createEmptyPathData(JNIEnv*, jobject) {
@@ -62,7 +62,7 @@
return reinterpret_cast<jlong>(pathData);
} else {
delete pathData;
- ALOGE(result.failureMessage.c_str());
+ doThrowIAE(env, result.failureMessage.c_str());
return NULL;
}
}
@@ -100,7 +100,7 @@
}
static const JNINativeMethod gMethods[] = {
- {"nParseStringForPath", "(JLjava/lang/String;I)Z", (void*)parseStringForPath},
+ {"nParseStringForPath", "(JLjava/lang/String;I)V", (void*)parseStringForPath},
{"nCreateEmptyPathData", "!()J", (void*)createEmptyPathData},
{"nCreatePathData", "!(J)J", (void*)createPathData},
{"nCreatePathDataFromString", "(Ljava/lang/String;I)J", (void*)createPathDataFromStringPath},
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 27e2ee8..4459f32 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -128,9 +128,22 @@
static void android_view_RenderNode_setDisplayList(JNIEnv* env,
jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
+ class RemovedObserver : public TreeObserver {
+ public:
+ virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+ maybeRemovedNodes.insert(sp<RenderNode>(node));
+ }
+ std::set< sp<RenderNode> > maybeRemovedNodes;
+ };
+
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
- renderNode->setStagingDisplayList(newData);
+ RemovedObserver observer;
+ renderNode->setStagingDisplayList(newData, &observer);
+ for (auto& node : observer.maybeRemovedNodes) {
+ if (node->hasParents()) continue;
+ onRenderNodeRemoved(env, node.get());
+ }
}
// ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 14252dc..21e4d2f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -525,7 +525,7 @@
UiFrameInfoBuilder(proxy->frameInfo())
.setVsync(vsync, vsync)
.addFlag(FrameInfoFlags::SurfaceCanvas);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) {
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 8019326..ef45c87 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -72,6 +72,31 @@
return env;
}
+// TODO: Clean this up, it's a bit odd to need to call over to
+// rendernode's jni layer. Probably means RootRenderNode should be pulled
+// into HWUI with appropriate callbacks for the various JNI hooks so
+// that RenderNode's JNI layer can handle its own thing
+void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
+
+class ScopedRemovedRenderNodeObserver : public TreeObserver {
+public:
+ ScopedRemovedRenderNodeObserver(JNIEnv* env) : mEnv(env) {}
+ ~ScopedRemovedRenderNodeObserver() {
+ for (auto& node : mMaybeRemovedNodes) {
+ if (node->hasParents()) continue;
+ onRenderNodeRemoved(mEnv, node.get());
+ }
+ }
+
+ virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+ mMaybeRemovedNodes.insert(sp<RenderNode>(node));
+ }
+
+private:
+ JNIEnv* mEnv;
+ std::set< sp<RenderNode> > mMaybeRemovedNodes;
+};
+
class OnFinishedEvent {
public:
OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
@@ -120,13 +145,7 @@
std::string mMessage;
};
-// TODO: Clean this up, it's a bit odd to need to call over to
-// rendernode's jni layer. Probably means RootRenderNode should be pulled
-// into HWUI with appropriate callbacks for the various JNI hooks so
-// that RenderNode's JNI layer can handle its own thing
-void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
-
-class RootRenderNode : public RenderNode, ErrorHandler, TreeObserver {
+class RootRenderNode : public RenderNode, ErrorHandler {
public:
RootRenderNode(JNIEnv* env) : RenderNode() {
mLooper = Looper::getForThread();
@@ -143,9 +162,6 @@
virtual void prepareTree(TreeInfo& info) override {
info.errorHandler = this;
- if (info.mode == TreeInfo::MODE_FULL) {
- info.observer = this;
- }
// TODO: This is hacky
info.windowInsetLeft = -stagingProperties().getLeft();
info.windowInsetTop = -stagingProperties().getTop();
@@ -155,7 +171,6 @@
info.windowInsetLeft = 0;
info.windowInsetTop = 0;
info.errorHandler = nullptr;
- info.observer = nullptr;
}
void sendMessage(const sp<MessageHandler>& handler) {
@@ -181,27 +196,10 @@
mPendingAnimatingRenderNodes.clear();
}
- virtual void onMaybeRemovedFromTree(RenderNode* node) override {
- mMaybeRemovedNodes.insert(sp<RenderNode>(node));
- }
-
- void processMaybeRemovedNodes(JNIEnv* env) {
- // We can safely access mMaybeRemovedNodes here because
- // we will only modify it in prepareTree calls that are
- // MODE_FULL
-
- for (auto& node : mMaybeRemovedNodes) {
- if (node->hasParents()) continue;
- onRenderNodeRemoved(env, node.get());
- }
- mMaybeRemovedNodes.clear();
- }
-
private:
sp<Looper> mLooper;
JavaVM* mVm;
std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
- std::set< sp<RenderNode> > mMaybeRemovedNodes;
};
class AnimationContextBridge : public AnimationContext {
@@ -481,6 +479,12 @@
return proxy->pauseSurface(surface);
}
+static void android_view_ThreadedRenderer_setStopped(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jboolean stopped) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->setStopped(stopped);
+}
+
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
jint width, jint height, jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -500,24 +504,23 @@
}
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize, jlong rootNodePtr) {
+ jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
"Mismatched size expectations, given %d expected %d",
frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
+ ScopedRemovedRenderNodeObserver observer(env);
env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
- int ret = proxy->syncAndDrawFrame();
- rootRenderNode->processMaybeRemovedNodes(env);
- return ret;
+ return proxy->syncAndDrawFrame(&observer);
}
static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong rootNodePtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
rootRenderNode->destroy();
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->destroy();
+ proxy->destroy(&observer);
}
static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
@@ -542,9 +545,10 @@
static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong nodePtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
- proxy->buildLayer(node);
+ proxy->buildLayer(node, &observer);
}
static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
@@ -579,8 +583,9 @@
static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->destroyHardwareResources();
+ proxy->destroyHardwareResources(&observer);
}
static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
@@ -733,10 +738,11 @@
{ "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize },
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
{ "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
+ { "nSetStopped", "(JZ)V", (void*) android_view_ThreadedRenderer_setStopped },
{ "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
- { "nSyncAndDrawFrame", "(J[JIJ)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
+ { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
{ "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
diff --git a/core/res/res/drawable/ic_corp_user_badge.xml b/core/res/res/drawable/ic_corp_user_badge.xml
new file mode 100644
index 0000000..23809d5
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_user_badge.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="36dp"
+ android:height="36dp"
+ android:viewportWidth="36.0"
+ android:viewportHeight="36.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18,0C8.06,-0 0,8.06 0,18C0,27.94 8.06,36 18,36C27.94,36 36,27.94 36,18C36,8.06 27.94,0 18,0zM15.5,10.5L20.5,10.5L21.75,11.75L21.75,13L24.66,13C25.57,13 26.34,13.74 26.34,14.66L26.34,18C26.34,18.92 25.57,19.66 24.66,19.66L19.66,19.66L19.66,18.41L16.34,18.41L16.34,19.66L11.34,19.66C10.43,19.66 9.66,18.92 9.66,18L9.66,14.66C9.66,13.74 10.43,13 11.34,13L14.25,13L14.25,11.78L15.5,10.5zM15.5,11.75L15.5,13L20.5,13L20.5,11.75L15.5,11.75zM10.5,20.5L16.34,20.5L16.34,21.75L19.66,21.75L19.66,20.5L25.5,20.5L25.5,23.84C25.5,24.76 24.76,25.5 23.84,25.5L12.16,25.5C11.24,25.5 10.5,24.76 10.5,23.84L10.5,20.5z"/>
+</vector>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 2a16a1e..6a85537 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vra PIN voordat jy ontspeld"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vra ontsluitpatroon voordat jy ontspeld"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vra wagwoord voordat jy ontspeld"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Program sal dalk nie met verdeelde skerm werk nie."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Program steun nie verdeelde skerm nie."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Deur jou administrateur geïnstalleer"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Opgedateer deur jou administrateur"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Deur jou administrateur uitgevee"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0668c35..7a3673f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ከመንቀል በፊት ፒን ጠይቅ"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"በእርስዎ አስተዳዳሪ ተጭኗል"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"በአስተዳዳሪዎ ተዘምኗል"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 6a7c76c..70ebba16 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -56,8 +56,8 @@
<string name="badPin" msgid="9015277645546710014">"رمز PIN القديم الذي كتبته غير صحيح."</string>
<string name="badPuk" msgid="5487257647081132201">"رمز PUK الذي كتبته غير صحيح."</string>
<string name="mismatchPin" msgid="609379054496863419">"أرقام التعريف الشخصية التي كتبتها غير مطابقة."</string>
- <string name="invalidPin" msgid="3850018445187475377">"اكتب رقم تعريف شخصيًا مكونًا من 4 إلى ثمانية أعداد."</string>
- <string name="invalidPuk" msgid="8761456210898036513">"اكتب رمز PUK مكونًا من 8 أرقام أو أكثر."</string>
+ <string name="invalidPin" msgid="3850018445187475377">"ادخل رقم تعريف شخصي مكون من ٤ إلى ٨ أرقام."</string>
+ <string name="invalidPuk" msgid="8761456210898036513">"اكتب رمز PUK مكونًا من ٨ أرقام أو أكثر."</string>
<string name="needPuk" msgid="919668385956251611">"شريحة SIM مؤمّنة بكود PUK. اكتب كود PUK لإلغاء تأمينها."</string>
<string name="needPuk2" msgid="4526033371987193070">"اكتب PUK2 لإلغاء تأمين شريحة SIM."</string>
<string name="enablePin" msgid="209412020907207950">"محاولة غير ناجحة، مكّن قفل SIM/RUIM."</string>
@@ -904,7 +904,7 @@
<string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"مساحة التخزين منخفضة"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"قد لا تعمل بعض وظائف النظام"</string>
- <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ليست هناك سعة تخزينية كافية للنظام. تأكد من أنه لديك مساحة خالية تبلغ 250 ميغابايت وأعد التشغيل."</string>
+ <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ليست هناك سعة تخزينية كافية للنظام. تأكد من أنه لديك مساحة خالية تبلغ ۲۵۰ ميغابايت وأعد التشغيل."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> قيد التشغيل"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"المس للحصول على مزيد من المعلومات أو لإيقاف التطبيق."</string>
<string name="ok" msgid="5970060430562524910">"موافق"</string>
@@ -1343,8 +1343,8 @@
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"تأكيد رمز رمز PIN المراد"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"جارٍ إلغاء تأمين شريحة SIM…"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"رمز PIN غير صحيح."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رمز PIN المكون من 4 إلى 8 أرقام."</string>
- <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"يجب أن يتكون رمز PUK من 8 أرقام."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رقم التعريف الشخصي المكون من ٤ إلى ٨ أرقام."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"يجب أن يتكون رمز PUK من ۸ أرقام."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى تعطيل شريحة SIM نهائيًا."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"لا يتطابق رمزا رمز PIN"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"محاولات النقش كثيرة جدًا"</string>
@@ -1478,7 +1478,7 @@
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"تأكيد رمز PIN الجديد"</string>
<string name="restr_pin_create_pin" msgid="8017600000263450337">"إنشاء رقم تعريف شخصي لتعديل القيود"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"أرقام التعريف الشخصية لا تتطابق، أعد المحاولة."</string>
- <string name="restr_pin_error_too_short" msgid="8173982756265777792">"رمز PIN أقصر مما يلزم، يجب ألا يقل عن 4 أرقام. "</string>
+ <string name="restr_pin_error_too_short" msgid="8173982756265777792">"رقم التعريف الشخصي أقصر مما يلزم، يجب ألا يقل عن ٤ أرقام. "</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
<item quantity="zero">حاول مرة أخرى خلال أقل من ثانية <xliff:g id="COUNT">%d</xliff:g></item>
<item quantity="two">حاول مرة أخرى خلال ثانيتين (<xliff:g id="COUNT">%d</xliff:g>)</item>
@@ -1508,8 +1508,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"المطالبة برقم التعريف الشخصي قبل إزالة التثبيت"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"المطالبة بنقش إلغاء القفل قبل إزالة التثبيت"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"يمكن ألا يعمل التطبيق مع وضع تقسيم الشاشة."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"التطبيق لا يتيح تقسيم الشاشة."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"تم تثبيت الحزمة عن طريق المشرف"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"تم التحديث بواسطة المشرف"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"تم حذف الحزمة عن طريق المشرف"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index e76ce87..2e4c10d 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ayırmadan öncə PIN istənilsin"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ayırmadan öncə kilid modeli istənilsin"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ayırmadan öncə parol istənilsin"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Tətbiq ekran bölünməsini dəstəkləmir."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Administratorunuz tərəfindən quraşdırılıb"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Sizin administrator tərəfindən yeniləndi"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratorunuz tərəfindən silinib"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9231e9a..b1d086e 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN pre otkačinjanja"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži šablon za otključavanje pre otkačinjanja"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku pre otkačinjanja"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podeljeni ekran."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao je vaš administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao je administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao je vaš admiistrator"</string>
diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml
index 8a23529..3152943 100644
--- a/core/res/res/values-be-rBY/strings.xml
+++ b/core/res/res/values-be-rBY/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запытваць PIN-код перад адмацаваннем"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запытваць пароль перад адмацаваннем"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Усталявана вашым адміністратарам"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Абноўлена вашым адміністратарам"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Выдалена вашым адміністратарам"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 76c7002..ec7ba3a 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запитване за ПИН код преди освобождаване"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запитване за фигура за отключване преди освобождаване"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитване за парола преди освобождаване"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Приложението може да не работи в режим на разделен екран."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Приложението не поддържа разделен екран."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано от администратора ви"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Актуализирано от администратора ви"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Изтрито от администратора ви"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 620e532..491b3a2 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"আনপিন করার আগে পিন চান"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"অ্যাপ্লিকেশানটি বিভক্ত স্ক্রীনে কাজ নাও করতে পারে৷"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রীন সমর্থন করে না৷"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"আপনার প্রশাসক দ্বারা ইনস্টল করা হয়েছে"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"আপনার প্রশাসক দ্বারা আপডেট করা হয়েছে"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"আপনার প্রশাসক দ্বারা মুছে ফেলা হয়েছে"</string>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index 82639af..ba164ee 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN prije nego se otkači"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje prije nego se otkači"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku prije nego se otkači"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće raditi na podijeljenom ekranu"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava dijeljenje ekrana."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 6fcadfa..6980cd5 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per anul·lar"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per anul·lar"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'aplicació no admet la pantalla dividida."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"L\'administrador ho ha instal·lat"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"L\'administrador l\'ha actualitzat"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"L\'administrador ho ha suprimit"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 127d38b..612475a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Před uvolněním požádat o PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Před uvolněním požádat o bezpečnostní gesto"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Před uvolněním požádat o heslo"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikace nepodporuje režim rozdělené obrazovky."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Nainstalováno administrátorem"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Aktualizováno administrátorem"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Smazáno administrátorem"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 407f1f8..f25492b 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1194,8 +1194,8 @@
<string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Sænk minuttal"</string>
<string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Forøg timetal"</string>
<string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Sænk timetal"</string>
- <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Indstil PM"</string>
- <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Indstil AM"</string>
+ <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Indstil e.m."</string>
+ <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Indstil f.m."</string>
<string name="date_picker_increment_month_button" msgid="5369998479067934110">"Senere måned"</string>
<string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Tidligere måned"</string>
<string name="date_picker_increment_day_button" msgid="7130465412308173903">"Senere dag"</string>
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Bed om pinkode inden frigørelse"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bed om oplåsningsmønster ved deaktivering"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bed om adgangskode inden frigørelse"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i delt skærm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke delt skærm."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installeret af din administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Opdateret af administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet af din administrator"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index e539a28..898883e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vor dem Beenden nach PIN fragen"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vor dem Beenden nach Passwort fragen"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Die App funktioniert unter Umständen bei geteiltem Bildschirm nicht."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Von deinem Administrator installiert"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Von deinem Administrator aktualisiert"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Von deinem Administrator gelöscht"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1e891d0..58ff631 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Να γίνεται ερώτηση για το PIN, πριν από το ξεκαρφίτσωμα"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Δεν είναι δυνατή η λειτουργία της εφαρμογής με διαχωρισμό οθόνης."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Εγκαταστάθηκε από το διαχειριστή σας"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ενημερώθηκε από το διαχειριστή σας"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Διαγράφηκε από το διαχειριστή σας"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b94222c..fe9d8dbd6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index b94222c..fe9d8dbd6 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index b94222c..fe9d8dbd6 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 0bfb9e0..289c6ba 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar PIN para quitar fijación"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para quitar fijación"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para quitar fijación"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Es posible que la app no funcione en el modo de pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"La app no es compatible con la función de pantalla dividida."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Lo instaló el administrador."</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por el administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Lo eliminó el administrador."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 99202ab..8bd955b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar PIN para desactivar"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para desactivar"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para desactivar"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Es posible que la aplicación no funcione con la pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"La aplicación no admite la pantalla dividida."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado por tu administrador"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por tu administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado por tu administrador"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index b1cc971..1aaf4ae 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Enne vabastamist küsi PIN-koodi"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Enne vabastamist küsi avamismustrit"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Enne vabastamist küsi parooli"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Rakendus ei toeta jagatud ekraani."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installis teie administraator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Värskendas administraator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Kustutas teie administraator"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index ea666d9..4601ff8 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Eskatu PIN kodea aingura kendu aurretik"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Eskatu pasahitza aingura kendu aurretik"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikazioak ez du onartzen pantaila zatitua"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Administratzaileak instalatu du"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Administratzaileak eguneratu du"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratzaileak ezabatu du"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index df9d78f..064055e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"درخواست کد پین قبل از برداشتن پین"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"درخواست الگوی باز کردن قفل قبل از برداشتن پین"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"درخواست گذرواژه قبل از برداشتن پین"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ممکن است برنامه با تقسیم صفحه کار نکند."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"توسط سرپرستتان نصب شد"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"توسط سرپرست شما بهروزرسانی شد"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c869961..41c583f 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pyydä PIN ennen irrotusta"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pyydä salasana ennen irrotusta"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Sovellus ei ehkä toimi jaetulla näytöllä."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Sovellus ei tue jaetun näytön tilaa."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Järjestelmänvalvoja on asentanut paketin."</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Järjestelmänvalvojasi on päivittänyt paketin."</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Järjestelmänvalvoja on poistanut paketin."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index efc8af3..3607382 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Demander le NIP avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'application n\'est pas compatible avec l\'écran partagé."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4e83fa96..27e1b70 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Demander le code PIN avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Application incompatible avec l\'écran partagé."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 2fa6087..c724f8c 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar un PIN antes de soltar a pantalla"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar un padrón de desbloqueo antes de soltar a pantalla"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar un contrasinal antes de soltar a pantalla"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Pode que a aplicación non funcione coa pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"A aplicación non é compatible coa función de pantalla dividida."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado polo administrador"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado polo administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado polo administrador"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 0b9f4ad..49acd99 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"અનપિન કરતાં પહેલાં PIN માટે પૂછો"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"અનપિન કરતા પહેલાં અનલૉક પેટર્ન માટે પૂછો"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"વિભાજિત-સ્ક્રીન સાથે ઍપ્લિકેશન કદાચ કામ ન કરે."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"તમારા વ્યવસ્થાપક દ્વારા ઇન્સ્ટોલ કરેલ"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ થયેલ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખેલ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 474e81e..b621005 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"अनपिन करने से पहले पिन के लिए पूछें"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करने से पहले अनलॉक पैटर्न के लिए पूछें"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"आपके नियंत्रक द्वारा इंस्टॉल किया गया"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"आपके नियंत्रक द्वारा अपडेट किया गया"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"आपके नियंत्रक द्वारा हटाया गया"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 837aa56..6bc0d6e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN radi otkvačivanja"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje radi otkvačivanja"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži zaporku radi otkvačivanja"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podijeljeni zaslon."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurira vaš administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0c4705d..dd39cca 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-kód kérése a rögzítés feloldásához"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Feloldási minta kérése a rögzítés feloldásához"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Jelszó kérése a rögzítés feloldásához"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"A rendszergazda telepítette"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Frissítette a rendszergazda"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"A rendszergazda törölte"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 4be90da..e41bf64 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ապաամրացնելուց առաջ հարցնել PIN-կոդը"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ապաամրացնելուց առաջ հարցնել ապակողպող նախշը"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ապաամրացնելուց առաջ հարցնել գաղտնաբառը"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում:"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Ադմինիստրատորը տեղադրել է այն"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ադմինիստրատորը թարմացրել է այն"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Ադմինիստրատորը ջնջել է այն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7218617..8940875 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Meminta PIN sebelum melepas sematan"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Meminta pola pembukaan kunci sebelum melepas sematan"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Meminta sandi sebelum melepas sematan"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App tidak mendukung layar terpisah."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Diperbarui oleh administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Dihapus oleh administrator"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index cebc4cc..546af60 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Biðja um PIN-númer til að losa"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Biðja um opnunarmynstur til að losa"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Biðja um aðgangsorð til að losa"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Hugsanlega virkar forritið ekki ef skjánum er skipt upp."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Forritið styður ekki að skjánum sé skipt."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Uppsett af kerfisstjóra"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Uppfært af kerfisstjóranum"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Eytt af kerfisstjóra"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2a73990..fc13359 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Richiedi il PIN per lo sblocco"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Richiedi sequenza di sblocco prima di sbloccare"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Richiedi password prima di sbloccare"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"L\'app potrebbe non funzionare con lo schermo diviso."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'app non supporta la modalità Schermo diviso."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installato dall\'amministratore"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Aggiornato dall\'amministratore"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminato dall\'amministratore"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 80435b6..5b9b5e1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"בקש PIN לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"בקש קו ביטול נעילה לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ייתכן שהיישום לא יפעל עם מסך מפוצל."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"האפליקציה אינה תומכת במסך מפוצל."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"הותקנה על ידי מנהל המערכת שלך"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"עודכן על ידי מנהל המערכת שלך"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"נמחקה על ידי מנהל המערכת שלך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 394775f..d3ecef8 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"オフライン再生を解除する前にPINの入力を求める"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"画面固定を解除する前にロック解除パターンの入力を求める"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"オフライン再生を解除する前にパスワードの入力を求める"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"アプリは分割画面では動作しないことがあります。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"アプリで分割画面がサポートされていません。"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"管理者によってインストールされました"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"管理者によって更新されています"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"管理者によって削除されました"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index fcc56da..20b1055 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ფიქსაციის მოხსნამდე PIN-ის მოთხოვნა"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"თქვენი ადმინისტრატორის მიერ დაყენებული"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"თქვენი ადმინისტრატორის მიერ წაშლილი"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 6eaa770..1372064 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Босату алдында PIN кодын сұрау"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Босату алдында бекітпесін ашу өрнегін сұрау"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Босату алдында құпия сөзді сұрау"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Қолданба бөлінген экранда жұмыс істемеуі мүмкін."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Қодланба бөлінген экранды қолдамайды."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Әкімші орнатқан"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Әкімші жаңартты"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Әкімші жойған"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 30d3c0a..d57659c 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1470,8 +1470,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"សួររកកូដ PIN មុនពេលផ្ដាច់"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"សួររកលំនាំដោះសោមុនពេលផ្ដាច់"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"សួររកពាក្យសម្ងាត់មុនពេលផ្ដាច់"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"កម្មវិធីអាចនឹងមិនដំណើរការនៅលើអេក្រង់បំបែកទេ"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"បានធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"បានលុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 087b399..7f94a1d 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಿನ್ ಕೇಳು"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ಅನ್ಪಿನ್ ಮಾಡಲು ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳು"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ವಿಭಜಿಸಿದ ಪರದೆಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ನವೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಳಿಸಲಾಗಿದೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 52de5ba..4f6d602 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"고정 해제 이전에 PIN 요청"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"고정 해제 이전에 잠금해제 패턴 요청"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"고정 해제 이전에 비밀번호 요청"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"앱이 화면 분할을 지원하지 않습니다."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"관리자가 설치함"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"관리자에 의해 업데이트됨"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"관리자가 삭제함"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 34cc7e5..c7d32d11 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1469,8 +1469,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Бошотуудан мурун PIN суралсын"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Бошотуудан мурун кулпуну ачкан үлгү суралсын"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Бошотуудан мурун сырсөз суралсын"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Колдонмодо экран бөлүнбөшү мүмкүн."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Колдонмодо экран бөлүнбөйт."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Администраторуңуз тарабынан орнотулган"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Администраторуңуз жаңырткан"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Администраторуңуз тарабынан жок кылынган"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index ea62f9b..a69ccb7 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ຖາມຫາ PIN ກ່ອນຍົກເລີກການປັກໝຸດ"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ຖາມຫາຮູບແບບປົດລັອກກ່ອນຍົກເລີກການປັກໝຸດ"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ຖາມຫາລະຫັດຜ່ານກ່ອນຍົກເລີກການປັກໝຸດ"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ຜູ້ຄວບຄຸມຂອງທ່ານຕິດຕັ້ງໃສ່ແລ້ວ"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"ອັບເດດໂດຍຜູ້ຄວບຄຸມຂອງທ່ານແລ້ວ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ຖືກຜູ້ຄວບຄຸມຂອງທ່ານລຶບໄປແລ້ວ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 3e815ec..9130d2c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Prašyti PIN kodo prieš atsegant"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Prašyti atrakinimo piešinio prieš atsegant"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Prašyti slaptažodžio prieš atsegant"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Programa gali neveikti naudojant skaidytą ekraną."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programoje nepalaikomas skaidytas ekranas."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Įdiegė administratorius"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atnaujino administratorius"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Ištrynė administratorius"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 56001fc..19aa282 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Prasīt PIN kodu pirms atspraušanas"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pirms atspraušanas pieprasīt grafisko atslēgu"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pirms atspraušanas pieprasīt paroli"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Iespējams, lietotnē nedarbosies ekrāna sadalīšana."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalēja jūsu administrators"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atjaunināja administrators"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Izdzēsa jūsu administrators"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 060a9fa..425722d 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1470,8 +1470,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Прашај за ПИН пред откачување"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Прашај за шема за отклучување пред откачување"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Прашај за лозинка пред откачување"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Апликацијата можеби нема да работи во поделен екран."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Апликацијата не поддржува поделен екран."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано од администраторот"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирано од администраторот"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Избришано од администраторот"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index f6ff1d8..1e24d01 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ചെയ്യുംമുമ്പ് പിൻ ചോദിക്കൂ"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടുക"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് പാസ്വേഡ് ആവശ്യപ്പെടുക"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"സ്പ്ലിറ്റ്-സ്ക്രീനിനൊപ്പം ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ഇൻസ്റ്റാളുചെയ്തു"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ അപ്ഡേറ്റുചെയ്തു"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ഇല്ലാതാക്കി"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 75105e6..0e2f8af 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Тогтоосныг суллахаас өмнө PIN асуух"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тогтоосныг суллахаас өмнө түгжээ тайлах хээ асуух"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Апп хуваагдсан дэлгэцэд ажиллахгүй."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Таны админ суулгасан байна"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Танай админ шинэчилсэн"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Таны админ устгасан байна"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 8a3e564..5dc9721 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"अनपिन करण्यापूर्वी पिन साठी विचारा"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करण्यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"आपल्या प्रशासकाद्वारे स्थापित केले आहे"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"आपल्या प्रशासकाद्वारे अद्यतनित केले"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"आपल्या प्रशासकाद्वारे हटविले आहे"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 5db9c77..ced967b 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Minta PIN sebelum menyahsemat"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Minta corak buka kunci sebelum menyahsemat"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Minta kata laluan sebelum menyahsemat"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Apl mungkin tidak berfungsi dengan skrin pisah."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Apl tidak menyokong skrin pisah."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh pentadbir anda"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Dikemas kini oleh pentadbir anda"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Dipadamkan oleh pentadbir anda"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 5e5ec4e..4e88bb40 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ပင်မဖြုတ်မီမှာ PIN ကို မေးကြည့်ရန်"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"မျက်နှာပြင် ခွဲခြမ်းပြသမှုဖြင့် အက်ပ်သည် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"သင့် အက်ဒမင်မှ သွင်းယူထား၏"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"သင့်စီမံခန့်ခွဲသူမှ အဆင့်မြှင့်ထားပါသည်။"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"သင့် အက်ဒမင်အား ဖျက်ပစ်ရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index cfccdeb..ff28307 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-kode for å løsne apper"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Krev bruk av opplåsningsmønster for å løsne apper"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Krev passord for å løsne apper"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Det kan hende at appen ikke fungerer med delt skjerm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen støtter ikke delt skjerm."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installert av administratoren"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Oppdatert av administratoren"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet av administratoren"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index fb817b5..878eff9f 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1474,8 +1474,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"पिन निकाल्नुअघि PIN सोध्नुहोस्"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"पिन निकाल्नुअघि खोल्ने रूपरेखा सोध्नुहोस्"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"अनुप्रयोगले विभाजित-स्क्रिनमा काम नगर्न सक्छ।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"तपाईँको प्रशासकद्वारा स्थापना गरिएको"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"तपाईँको प्रशासकद्वारा अद्यावधिक गरिएको"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"तपाईँको प्रशासकद्वारा हटाइएको"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3de8496..f76d185 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vraag pin voor losmaken"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vraag patroon voor losmaken"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vraag wachtwoord voor losmaken"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"App werkt mogelijk niet met gesplitst scherm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App biedt geen ondersteuning voor gesplitst scherm."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door je beheerder"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door je beheerder"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door je beheerder"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 87f973f..26d5af9 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ PIN ਮੰਗੋ"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪੈਟਰਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਪੁੱਛੋ"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ਤੁਹਾਡੇ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤਾ ਗਿਆ"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ਤੁਹਾਡੇ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6be9a9d..6bfac83 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Podaj PIN, aby odpiąć"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Aby odpiąć, poproś o wzór odblokowania"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Aby odpiąć, poproś o hasło"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacja może nie działać przy podzielonym ekranie."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacja nie obsługuje dzielonego ekranu."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Zainstalowany przez administratora"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Zaktualizowane przez administratora"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Usunięty przez administratora"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index c8004bf..241ee823 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -254,7 +254,7 @@
<string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com a qual você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Itens tocados serão falados em voz alta e a tela poderá ser explorada por meio de gestos."</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Ativar acessibilidade na Web aprimorada"</string>
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de liberar"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"É possível que o app não funcione com o recurso de divisão de tela."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"O app não é compatível com a divisão de tela."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c2ba8ad..ebe6efb 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de soltar"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir sequência de desbloqueio antes de soltar"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"A aplicação pode não funcionar com o ecrã dividido."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"A aplicação não é compatível com o ecrã dividido."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo administrador"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado pelo administrador"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c8004bf..241ee823 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -254,7 +254,7 @@
<string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com a qual você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Itens tocados serão falados em voz alta e a tela poderá ser explorada por meio de gestos."</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Ativar acessibilidade na Web aprimorada"</string>
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de liberar"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"É possível que o app não funcione com o recurso de divisão de tela."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"O app não é compatível com a divisão de tela."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7485e65..951e365 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicită codul PIN înainte de a anula fixarea"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicită modelul pentru deblocare înainte de a anula fixarea"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicită parola înainte de a anula fixarea"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplicația nu acceptă ecranul împărțit."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalat de administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizat de un administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Șters de administrator"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5926bfd..a012a95 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-код для отключения"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запрашивать графический ключ для отключения блокировки"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запрашивать пароль для отключения блокировки"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Приложение не поддерживает разделение экрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Приложение не поддерживает разделение экрана."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Установлено администратором"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Обновлено администратором"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Удалено администратором"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 6c76da0..9175e7e 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1470,8 +1470,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ගැලවීමට පෙර PIN විමසන්න"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"යෙදුම බෙදුම්-තිරය සමග ක්රියා නොකළ හැකිය."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ඔබගේ පරිපාලක විසින් ස්ථාපනය කරන ලද"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"ඔබගේ පරිපාලක විසින් යාවත්කාලීන කරන ලදී"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ඔබගේ පරිපාලක විසින් මකන ලද"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ec45070..e09ed27 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pred uvoľnením požiadať o číslo PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred uvoľnením požiadať o heslo"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikácia nemusí fungovať so zapnutou rozdelenou obrazovkou."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikácia nepodporuje rozdelenú obrazovku."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Inštalovaný správcom"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Aktualizované správcom"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Odstránený správcom"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index b2dba7e0..6cdcf31 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Zahtevaj PIN pred odpenjanjem"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred odpenjanjem vprašaj za geslo"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podpira načina razdeljenega zaslona."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Namestil skrbnik"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Posodobil skrbnik"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisal skrbnik"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 1846399..e5d8eaa 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Zhgozhdimi kërkon PIN-in"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Kërko model shkyçjeje para heqjes së gozhdimit"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacioni nuk mbështet ekranin e ndarë."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"U instalua nga administratori yt"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Përditësuar nga administratori"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"U fshi nga administratori yt"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 2112dbb..5ebe971c 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1478,8 +1478,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Тражи PIN пре откачињања"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тражи шаблон за откључавање пре откачињања"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тражи лозинку пре откачињања"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Апликација можда неће функционисати са подељеним екраном."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Апликација не подржава подељени екран."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирао је ваш администратор"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирао је администратор"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Избрисао је ваш адмиистратор"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 832d4a2..bf64512 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Be om pinkod innan skärmen slutar fästas"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Be om upplåsningsmönster innan skärmen slutar fästas"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Be om lösenord innan skärmen slutar fästas"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen kanske inte fungerar med delad skärm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen har inte stöd för delad skärm."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Paketet har installerats av administratören"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Uppdaterat av administratören"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Paketet har raderats av administratören"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index e0a32f6..6c2952a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1470,8 +1470,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Omba PIN kabla hujabandua"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Omba mchoro wa kufungua kabla hujabandua"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Omba nenosiri kabla hujabandua"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programu haiwezi kutumia skrini iliyogawanywa."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Kilisakinishwa na msimamizi wako"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Kimesasiswa na msimamizi wako"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Kilifutwa na msimamizi wako"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 773301f..e805360 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"அகற்றும் முன் PINஐக் கேள்"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"அகற்றும் முன் திறத்தல் வடிவத்தைக் கேள்"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"திரைப் பிரிப்பில் பயன்பாடு வேலைசெய்யாமல் போகக்கூடும்."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"திரையைப் பிரிப்பதைப் பயன்பாடு ஆதரிக்கவில்லை."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"நிர்வாகி நிறுவினார்"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"நிர்வாகி நீக்கிவிட்டார்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 4809c98..8585c07 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"అన్పిన్ చేయడానికి ముందు పిన్ కోసం అడుగు"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"అన్పిన్ చేయడానికి ముందు అన్లాక్ నమూనా కోసం అడుగు"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"స్క్రీన్ విభజనతో అనువర్తనం పని చేయకపోవచ్చు."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"మీ నిర్వాహకులు ఇన్స్టాల్ చేసారు"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"మీ నిర్వాహకుడు నవీకరించారు"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"మీ నిర్వాహకులు తొలగించారు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0ea2e52..17a732f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ขอ PIN ก่อนเลิกตรึง"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ขอรูปแบบการปลดล็อกก่อนเลิกตรึง"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ขอรหัสผ่านก่อนเลิกตรึง"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"แอปอาจใช้ไม่ได้กับโหมดแยกหน้าจอ"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"แอปไม่สนับสนุนการแยกหน้าจอ"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ติดตั้งโดยผู้ดูแลระบบของคุณ"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"อัปเดตโดยผู้ดูแลระบบ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ลบโดยผู้ดูแลระบบของคุณ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 00918a4..7f4393e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Humingi ng PIN bago mag-unpin"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Humingi ng password bago mag-unpin"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Maaaring hindi gumana ang app sa split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Hindi sinusuportahan ng app ang split-screen."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Na-install ng iyong administrator"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Na-update ng iyong administrator"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Na-delete ng iyong administrator"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 4db8264..1dbf7f3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Uygulama bölünmüş ekranda çalışmayabilir."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Uygulama bölünmüş ekranı desteklemiyor."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Yöneticiniz tarafından yüklendi"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Yöneticiniz tarafından güncellendi"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Yöneticiniz tarafından silindi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index fe7be12..78a2947 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1488,8 +1488,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-код для відкріплення"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запитувати ключ розблокування перед відкріпленням"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитувати пароль перед відкріпленням"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Додаток може не працювати в режимі розділеного екрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Додаток не підтримує розділення екрана."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Установив адміністратор"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Оновлено адміністратором"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Видалив адміністратор"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 5236b7f..f5ffbdeb 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"پن ہٹانے سے پہلے PIN طلب کریں"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"ممکن ہے کہ ایپ سپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"آپ کے منتظم کی جانب سے انسٹال کر دیا گیا"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"آپ کے منتظم نے اپ ڈيٹ کر دیا"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"آپ کے منتظم کی جانب سے حذف کر دیا گیا"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 6cb65a3..0b6a0cc 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Yechishda PIN-kod so‘ralsin"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bo‘shatishdan oldin chizmali parol so‘ralsin"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Ilova ekranni ikkiga bo‘lish rejimini qo‘llab-quvvatlamaydi."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Administratoringiz tomonidan o‘rnatilgan"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Administratoringiz tomonidan yangilandi"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratoringiz tomonidan o‘chirilgan"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 29eef92..6236153 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Hỏi mã PIN trước khi bỏ ghim"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Hỏi mật khẩu trước khi bỏ ghim"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Ứng dụng không hỗ trợ chia đôi màn hình."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Được cài đặt bởi quản trị viên của bạn"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Được cập nhật bởi quản trị viên của bạn"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Đã bị xóa bởi quản trị viên của bạn"</string>
diff --git a/core/res/res/values-w320dp/dimens.xml b/core/res/res/values-w320dp/dimens.xml
new file mode 100644
index 0000000..ad6d2ec
--- /dev/null
+++ b/core/res/res/values-w320dp/dimens.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.
+-->
+<resources>
+ <!-- The platform's desired fixed width for a dialog along the major axis
+ (the screen is in landscape). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_major">320dp</item>
+ <!-- The platform's desired fixed width for a dialog along the minor axis
+ (the screen is in portrait). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_minor">320dp</item>
+</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 3b26e46..708f1be 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消时要求输入PIN码"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消时要求绘制解锁图案"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消时要求输入密码"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"应用可能无法在分屏模式下正常运行。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"应用不支持分屏。"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理员安装"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"由您单位的管理员更新"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"已被管理员删除"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 28f2bac..95b7244 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消固定時必須輸入 PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖案"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"應用程式不支援分割畫面。"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"已由您的管理員更新"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"已由管理員刪除"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index dfc7890..7c980bd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消固定時必須輸入 PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖案"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"這個應用程式不支援分割畫面。"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"由您的管理員更新"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"已遭管理員刪除"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e32f26b..d64e79c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1468,8 +1468,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Cela iphinikhodi ngaphambi kokuphina"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string>
- <string name="dock_forced_resizable" msgid="5914261505436217520">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Ifakwe ngumlawuli wakho"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Ibuyekezwe ngumqondisi wakho"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Isuswe ngumlawuli wakho"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b4371c1..dfa5143b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -265,19 +265,6 @@
<item>"0,1"</item>
</string-array>
- <!-- Set of NetworkInfo.getType() that reflect data usage. -->
- <integer-array translatable="false" name="config_data_usage_network_types">
- <item>0</item> <!-- TYPE_MOBILE -->
- <item>2</item> <!-- TYPE_MOBILE_MMS -->
- <item>3</item> <!-- TYPE_MOBILE_SUPL -->
- <item>4</item> <!-- TYPE_MOBILE_DUN -->
- <item>5</item> <!-- TYPE_MOBILE_HIPRI -->
- <item>10</item> <!-- TYPE_MOBILE_FOTA -->
- <item>11</item> <!-- TYPE_MOBILE_IMS -->
- <item>12</item> <!-- TYPE_MOBILE_CBS -->
- <item>14</item> <!-- TYPE_MOBILE_IA -->
- </integer-array>
-
<!-- The maximum duration (in milliseconds) we expect a network transition to take -->
<integer name="config_networkTransitionTimeout">60000</integer>
@@ -2434,10 +2421,6 @@
disables NetworkPolicyManagerService's presentation of data-usage notifications. -->
<string translatable="false" name="config_networkPolicyNotificationComponent"></string>
- <!-- The fraction of display size (lower of height and width) that will be used to determine
- the default minimal size for resizeable tasks. -->
- <fraction name="config_displayFractionForDefaultMinimalSizeOfResizeableTask">25%</fraction>
-
<!-- The BT name of the keyboard packaged with the device. If this is defined, SystemUI will
automatically try to pair with it when the device exits tablet mode. -->
<string translatable="false" name="config_packagedKeyboardName"></string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index a21f276..dd54d57 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -112,10 +112,10 @@
<!-- The platform's desired fixed width for a dialog along the major axis
(the screen is in landscape). This may be either a fraction or a dimension.-->
- <item type="dimen" name="dialog_fixed_width_major">320dp</item>
+ <item type="dimen" name="dialog_fixed_width_major">100%</item>
<!-- The platform's desired fixed width for a dialog along the minor axis
(the screen is in portrait). This may be either a fraction or a dimension.-->
- <item type="dimen" name="dialog_fixed_width_minor">320dp</item>
+ <item type="dimen" name="dialog_fixed_width_minor">100%</item>
<!-- The platform's desired fixed height for a dialog along the major axis
(the screen is in portrait). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_height_major">80%</item>
@@ -455,4 +455,7 @@
<item type="fraction" name="docked_stack_divider_fixed_ratio">34.15%</item>
<dimen name="resize_shadow_size">5dp</dimen>
+
+ <!-- The default minimal size of a resizable task, in both dimensions. -->
+ <dimen name="default_minimal_size_resizable_task">220dp</dimen>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b4f95dc..96731cf 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4018,12 +4018,6 @@
<!-- Lock-to-app unlock password string -->
<string name="lock_to_app_unlock_password">Ask for password before unpinning</string>
- <!-- Multi-Window strings -->
- <!-- Warning message when an app that got forced to be resizable gets shown in split-screen -->
- <string name="dock_forced_resizable">App may not work with split-screen.</string>
- <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
- <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
-
<!-- Notification shown when device owner silently installs a package [CHAR LIMIT=NONE] -->
<string name="package_installed_device_owner">Installed by your administrator</string>
<!-- Notification shown when device owner silently updates a package [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2215bd4..8d8b832 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -613,8 +613,6 @@
<java-symbol type="string" name="display_manager_overlay_display_name" />
<java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
<java-symbol type="string" name="display_manager_overlay_display_title" />
- <java-symbol type="string" name="dock_forced_resizable" />
- <java-symbol type="string" name="dock_non_resizeble_failed_to_dock_text" />
<java-symbol type="string" name="double_tap_toast" />
<java-symbol type="string" name="durationDays" />
<java-symbol type="string" name="durationDayHours" />
@@ -1130,7 +1128,6 @@
<java-symbol type="plurals" name="pinpuk_attempts" />
<java-symbol type="array" name="carrier_properties" />
- <java-symbol type="array" name="config_data_usage_network_types" />
<java-symbol type="array" name="config_sms_enabled_locking_shift_tables" />
<java-symbol type="array" name="config_sms_enabled_single_shift_tables" />
<java-symbol type="array" name="config_twoDigitNumberPattern" />
@@ -1267,6 +1264,7 @@
<java-symbol type="drawable" name="ic_corp_badge" />
<java-symbol type="drawable" name="ic_corp_badge_off" />
<java-symbol type="drawable" name="ic_corp_icon_badge" />
+ <java-symbol type="drawable" name="ic_corp_user_badge" />
<java-symbol type="drawable" name="ic_corp_badge_no_background" />
<java-symbol type="drawable" name="ic_corp_icon" />
<java-symbol type="drawable" name="ic_corp_statusbar_icon" />
@@ -1728,7 +1726,7 @@
<java-symbol type="id" name="replace_app_icon" />
<java-symbol type="id" name="replace_message" />
<java-symbol type="fraction" name="config_dimBehindFadeDuration" />
- <java-symbol type="fraction" name="config_displayFractionForDefaultMinimalSizeOfResizeableTask" />
+ <java-symbol type="dimen" name="default_minimal_size_resizable_task" />
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
<java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
<java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index b7926cf..2452cfd 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1256,15 +1256,6 @@
<service android:name="android.os.BinderThreadPriorityService"
android:process=":BinderThreadPriorityService" />
- <!-- Used by ApplyOverrideConfigurationTest -->
- <activity android:name="android.app.activity.ApplyOverrideConfigurationActivity"
- android:configChanges="orientation|screenSize">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
- </intent-filter>
- </activity>
-
<!-- Application components used for search manager tests -->
<activity android:name="android.app.activity.SearchableActivity"
diff --git a/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationActivity.java b/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationActivity.java
deleted file mode 100644
index 3df522d..0000000
--- a/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.app.activity;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Configuration;
-
-public class ApplyOverrideConfigurationActivity extends Activity {
-
- @Override
- protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(newBase);
-
- Configuration overrideConfig = new Configuration();
- overrideConfig.smallestScreenWidthDp = ApplyOverrideConfigurationTest.OVERRIDE_WIDTH;
- applyOverrideConfiguration(overrideConfig);
- }
-}
diff --git a/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationTest.java b/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationTest.java
deleted file mode 100644
index 15ed77e..0000000
--- a/core/tests/coretests/src/android/app/activity/ApplyOverrideConfigurationTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.app.activity;
-
-import android.app.UiAutomation;
-import android.content.res.Configuration;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.ActivityInstrumentationTestCase2;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ApplyOverrideConfigurationTest extends
- ActivityInstrumentationTestCase2<ApplyOverrideConfigurationActivity> {
-
- public static final int OVERRIDE_WIDTH = 9999;
-
- public ApplyOverrideConfigurationTest() {
- super(ApplyOverrideConfigurationActivity.class);
- }
-
- @Before
- @Override
- public void setUp() throws Exception {
- super.setUp();
- injectInstrumentation(InstrumentationRegistry.getInstrumentation());
- getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_0);
- }
-
- @Test
- public void testConfigurationIsOverriden() throws Exception {
- Configuration config = getActivity().getResources().getConfiguration();
- assertEquals(OVERRIDE_WIDTH, config.smallestScreenWidthDp);
-
- getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_90);
-
- config = getActivity().getResources().getConfiguration();
- assertEquals(OVERRIDE_WIDTH, config.smallestScreenWidthDp);
- }
-
- @After
- @Override
- public void tearDown() throws Exception {
- getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_UNFREEZE);
- super.tearDown();
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index ec5220f..ba5206a 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -27,7 +27,6 @@
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
-import com.android.internal.inputmethod.InputMethodUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -68,7 +67,7 @@
ri.serviceInfo = si;
List<InputMethodSubtype> subtypes = null;
if (subtypeLocales != null) {
- subtypes = new ArrayList<InputMethodSubtype>();
+ subtypes = new ArrayList<>();
for (String subtypeLocale : subtypeLocales) {
subtypes.add(createDummySubtype(subtypeLocale));
}
@@ -89,7 +88,7 @@
}
private static List<ImeSubtypeListItem> createEnabledImeSubtypes() {
- final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
+ final List<ImeSubtypeListItem> items = new ArrayList<>();
addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme", Arrays.asList("en_US", "fr"),
true /* supportsSwitchingToNextInputMethod*/);
addDummyImeSubtypeListItems(items, "switchUnawareLatinIme", "switchUnawareLatinIme",
@@ -105,7 +104,7 @@
}
private static List<ImeSubtypeListItem> createDisabledImeSubtypes() {
- final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
+ final List<ImeSubtypeListItem> items = new ArrayList<>();
addDummyImeSubtypeListItems(items,
"UnknownIme", "UnknownIme",
Arrays.asList("en_US", "hi"),
@@ -121,15 +120,18 @@
}
private void assertNextInputMethod(final ControllerImpl controller,
- final boolean onlyCurrentIme,
- final ImeSubtypeListItem currentItem, final ImeSubtypeListItem nextItem) {
+ final boolean onlyCurrentIme, final ImeSubtypeListItem currentItem,
+ final ImeSubtypeListItem nextItem, final ImeSubtypeListItem prevItem) {
InputMethodSubtype subtype = null;
if (currentItem.mSubtypeName != null) {
subtype = createDummySubtype(currentItem.mSubtypeName.toString());
}
final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme,
- currentItem.mImi, subtype);
+ currentItem.mImi, subtype, true /* forward */);
assertEquals(nextItem, nextIme);
+ final ImeSubtypeListItem prevIme = controller.getNextInputMethod(onlyCurrentIme,
+ currentItem.mImi, subtype, false /* forward */);
+ assertEquals(prevItem, prevIme);
}
private void assertRotationOrder(final ControllerImpl controller,
@@ -138,11 +140,13 @@
final int N = expectedRotationOrderOfImeSubtypeList.length;
for (int i = 0; i < N; i++) {
final int currentIndex = i;
+ final int prevIndex = (currentIndex + N - 1) % N;
final int nextIndex = (currentIndex + 1) % N;
final ImeSubtypeListItem currentItem =
expectedRotationOrderOfImeSubtypeList[currentIndex];
final ImeSubtypeListItem nextItem = expectedRotationOrderOfImeSubtypeList[nextIndex];
- assertNextInputMethod(controller, onlyCurrentIme, currentItem, nextItem);
+ final ImeSubtypeListItem prevItem = expectedRotationOrderOfImeSubtypeList[prevIndex];
+ assertNextInputMethod(controller, onlyCurrentIme, currentItem, nextItem, prevItem);
}
}
@@ -190,29 +194,29 @@
assertRotationOrder(controller, true /* onlyCurrentIme */,
switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- subtypeUnawareIme, null);
+ subtypeUnawareIme, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_JP, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_JP, null, null);
// Make sure that disabled IMEs are not accepted.
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_US, null, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledIme_hi, null);
+ disabledIme_hi, null, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledSwitchingUnawareIme, null);
+ disabledSwitchingUnawareIme, null, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledSubtypeUnawareIme, null);
+ disabledSubtypeUnawareIme, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_US, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledIme_hi, null);
+ disabledIme_hi, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledSwitchingUnawareIme, null);
+ disabledSwitchingUnawareIme, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledSubtypeUnawareIme, null);
+ disabledSubtypeUnawareIme, null, null);
}
@SmallTest
@@ -246,7 +250,7 @@
japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
// Check onlyCurrentIme == true.
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_JP, null, null);
assertRotationOrder(controller, true /* onlyCurrentIme */,
latinIme_fr, latinIme_en_US);
assertRotationOrder(controller, true /* onlyCurrentIme */,
@@ -270,9 +274,9 @@
assertRotationOrder(controller, true /* onlyCurrentIme */,
switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- subtypeUnawareIme, null);
+ subtypeUnawareIme, null, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_JP, null, null);
// Rotation order should be preserved when created with the same subtype list.
final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
@@ -298,7 +302,7 @@
@SmallTest
public void testImeSubtypeListItem() throws Exception {
- final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
+ final List<ImeSubtypeListItem> items = new ArrayList<>();
addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme",
Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
true /* supportsSwitchingToNextInputMethod*/);
diff --git a/core/tests/notificationtests/Android.mk b/core/tests/notificationtests/Android.mk
index be2e6bf..702218c 100644
--- a/core/tests/notificationtests/Android.mk
+++ b/core/tests/notificationtests/Android.mk
@@ -11,6 +11,9 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := NotificationStressTests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ub-uiautomator
+
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/tests/notificationtests/src/android/app/NotificationStressTest.java b/core/tests/notificationtests/src/android/app/NotificationStressTest.java
index 4cb617e..6e86c37 100644
--- a/core/tests/notificationtests/src/android/app/NotificationStressTest.java
+++ b/core/tests/notificationtests/src/android/app/NotificationStressTest.java
@@ -16,15 +16,19 @@
package android.app;
-
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Build;
+import android.os.RemoteException;
import android.os.SystemClock;
+import android.support.test.uiautomator.UiDevice;
import android.test.InstrumentationTestCase;
import android.test.RepetitiveTest;
-import android.test.TimedTest;
+import android.util.Log;
+import java.lang.InterruptedException;
+import java.lang.reflect.Method;
import java.util.Random;
/**
@@ -34,51 +38,78 @@
public class NotificationStressTest extends InstrumentationTestCase {
private static final int NUM_ITERATIONS = 200;
+ private static final int NUM_ITERATIONS_2 = 30;
+ private static final int LONG_TIMEOUT = 2000;
+ // 50 notifications per app: defined as Variable MAX_PACKAGE_NOTIFICATIONS in
+ // NotificationManagerService.java
+ private static final int MAX_NOTIFCATIONS = 50;
private static final int[] ICONS = new int[] {
- android.R.drawable.stat_notify_call_mute,
- android.R.drawable.stat_notify_chat,
- android.R.drawable.stat_notify_error,
- android.R.drawable.stat_notify_missed_call,
- android.R.drawable.stat_notify_more,
- android.R.drawable.stat_notify_sdcard,
- android.R.drawable.stat_notify_sdcard_prepare,
- android.R.drawable.stat_notify_sdcard_usb,
- android.R.drawable.stat_notify_sync,
- android.R.drawable.stat_notify_sync_noanim,
- android.R.drawable.stat_notify_voicemail,
+ android.R.drawable.stat_notify_call_mute,
+ android.R.drawable.stat_notify_chat,
+ android.R.drawable.stat_notify_error,
+ android.R.drawable.stat_notify_missed_call,
+ android.R.drawable.stat_notify_more,
+ android.R.drawable.stat_notify_sdcard,
+ android.R.drawable.stat_notify_sdcard_prepare,
+ android.R.drawable.stat_notify_sdcard_usb,
+ android.R.drawable.stat_notify_sync,
+ android.R.drawable.stat_notify_sync_noanim,
+ android.R.drawable.stat_notify_voicemail,
};
private final Random mRandom = new Random();
private Context mContext;
private NotificationManager mNotificationManager;
- private int notifyId = 0;
+ private UiDevice mDevice = null;
+ private int mNotifyId = 0;
@Override
protected void setUp() throws Exception {
super.setUp();
+ mDevice = UiDevice.getInstance(getInstrumentation());
mContext = getInstrumentation().getContext();
mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
+ mDevice.setOrientationNatural();
+ mNotificationManager.cancelAll();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
+ mDevice.unfreezeRotation();
mNotificationManager.cancelAll();
}
- @RepetitiveTest(numIterations=NUM_ITERATIONS)
+ @RepetitiveTest(numIterations = NUM_ITERATIONS)
public void testNotificationStress() {
// Cancel one of every five notifications to vary load on notification manager
- if (notifyId % 5 == 4) {
- mNotificationManager.cancel(notifyId - 4);
+ if (mNotifyId % 5 == 4) {
+ mNotificationManager.cancel(mNotifyId - 4);
}
- sendNotification(notifyId++, "testNotificationStressNotify");
+ sendNotification(mNotifyId++, "testNotificationStressNotify");
+ }
+
+ @RepetitiveTest(numIterations = NUM_ITERATIONS_2)
+ public void testNotificationsWithShadeStress() throws Exception {
+ mDevice.openNotification();
+ Thread.sleep(LONG_TIMEOUT);
+ for (int j = 0; j < MAX_NOTIFCATIONS; j++) {
+ sendNotification(mNotifyId++, "testNotificationStressNotify");
+ }
+ Thread.sleep(500);
+ assertTrue(mNotificationManager.getActiveNotifications().length == MAX_NOTIFCATIONS);
+ for (int j = 0; j < MAX_NOTIFCATIONS; j++) {
+ mNotificationManager.cancel(--mNotifyId);
+ }
+ if (isLockScreen()) {
+ fail("Notification stress test failed, back to lockscreen");
+ }
}
private void sendNotification(int id, CharSequence text) {
// Fill in arbitrary content
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
+ Intent intent = new Intent(Intent.ACTION_VIEW);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
CharSequence title = text + " " + id;
CharSequence subtitle = String.valueOf(System.currentTimeMillis());
@@ -90,8 +121,19 @@
.setContentTitle(title)
.setContentText(subtitle)
.setContentIntent(pendingIntent)
+ .setPriority(Notification.PRIORITY_HIGH)
.build();
mNotificationManager.notify(id, notification);
SystemClock.sleep(10);
}
+
+ private boolean isLockScreen() {
+ KeyguardManager myKM = (KeyguardManager) mContext
+ .getSystemService(Context.KEYGUARD_SERVICE);
+ if (myKM.inKeyguardRestrictedInputMode()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index f741e3c..e48bf79 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -17,8 +17,12 @@
package android.graphics;
import android.content.res.AssetManager;
+import android.util.Log;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
import java.util.List;
/**
@@ -27,6 +31,9 @@
* @hide
*/
public class FontFamily {
+
+ private static String TAG = "FontFamily";
+
/**
* @hide
*/
@@ -62,7 +69,15 @@
}
public boolean addFont(String path, int ttcIndex) {
- return nAddFont(mNativePtr, path, ttcIndex);
+ try (FileInputStream file = new FileInputStream(path)) {
+ FileChannel fileChannel = file.getChannel();
+ long fontSize = fileChannel.size();
+ ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
+ return nAddFont(mNativePtr, fontBuffer, ttcIndex);
+ } catch (IOException e) {
+ Log.e(TAG, "Error mapping font file " + path);
+ return false;
+ }
}
public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontListParser.Axis> axes,
@@ -76,7 +91,7 @@
private static native long nCreateFamily(String lang, int variant);
private static native void nUnrefFamily(long nativePtr);
- private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex);
+ private static native boolean nAddFont(long nativeFamily, ByteBuffer font, int ttcIndex);
private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font,
int ttcIndex, List<FontListParser.Axis> listOfAxis,
int weight, boolean isItalic);
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index be816f78..0606b0b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -248,16 +248,17 @@
tests/unit/FatVectorTests.cpp \
tests/unit/GlopBuilderTests.cpp \
tests/unit/GpuMemoryTrackerTests.cpp \
+ tests/unit/GradientCacheTests.cpp \
tests/unit/LayerUpdateQueueTests.cpp \
tests/unit/LinearAllocatorTests.cpp \
tests/unit/MatrixTests.cpp \
tests/unit/OffscreenBufferPoolTests.cpp \
tests/unit/RenderNodeTests.cpp \
tests/unit/SkiaBehaviorTests.cpp \
+ tests/unit/SnapshotTests.cpp \
tests/unit/StringUtilsTests.cpp \
tests/unit/TextDropShadowCacheTests.cpp \
- tests/unit/VectorDrawableTests.cpp \
- tests/unit/GradientCacheTests.cpp
+ tests/unit/VectorDrawableTests.cpp
ifeq (true, $(HWUI_NEW_OPS))
LOCAL_SRC_FILES += \
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
index b70d586..9f98241 100644
--- a/libs/hwui/BakedOpState.cpp
+++ b/libs/hwui/BakedOpState.cpp
@@ -50,7 +50,7 @@
}
// resolvedClipRect = intersect(parentMatrix * localClip, parentClip)
- clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator,
+ clipState = snapshot.serializeIntersectedClip(allocator,
recordedOp.localClip, *(snapshot.transform));
LOG_ALWAYS_FATAL_IF(!clipState, "must clip!");
@@ -85,8 +85,7 @@
ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
const Matrix4& localTransform, const ClipBase* localClip) {
transform.loadMultiply(*snapshot.transform, localTransform);
- clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator,
- localClip, *(snapshot.transform));
+ clipState = snapshot.serializeIntersectedClip(allocator, localClip, *(snapshot.transform));
clippedBounds = clipState->rect;
clipSideFlags = OpClipSideFlags::Full;
localProjectionPathMask = nullptr;
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index f886dda..35fe06d 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -217,6 +217,7 @@
void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
SkRegion::Op op) {
+ if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
switch (mMode) {
@@ -233,6 +234,7 @@
}
void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
+ if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
enterRegionMode();
@@ -242,6 +244,7 @@
void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
SkRegion::Op op) {
+ if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
SkMatrix skTransform;
@@ -379,6 +382,7 @@
serialization->rect.set(mClipRegion.getBounds());
break;
}
+ serialization->intersectWithRoot = mReplaceOpObserved;
// TODO: this is only done for draw time, should eventually avoid for record time
serialization->rect.snapToPixelBoundaries();
mLastSerialization = serialization;
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 1654eb8..6eb2eef 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -103,6 +103,7 @@
: mode(ClipMode::Rectangle)
, rect(rect) {}
const ClipMode mode;
+ bool intersectWithRoot = false;
// Bounds of the clipping area, used to define the scissor, and define which
// portion of the stencil is updated/used
Rect rect;
@@ -173,8 +174,8 @@
return mMode == ClipMode::RectangleList;
}
- const ClipBase* serializeClip(LinearAllocator& allocator);
- const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
+ WARN_UNUSED_RESULT const ClipBase* serializeClip(LinearAllocator& allocator);
+ WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
void applyClip(const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
@@ -214,6 +215,7 @@
ClipMode mMode;
bool mPostViewportClipObserved = false;
+ bool mReplaceOpObserved = false;
/**
* If mLastSerialization is non-null, it represents an already serialized copy
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 0401f2d..f12e523 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -462,7 +462,7 @@
int count = mCanvasState.save(SaveFlags::MatrixClip);
// apply state from RecordedOp (clip first, since op's clip is transformed by current matrix)
- mCanvasState.writableSnapshot()->mutateClipArea().applyClip(op.localClip,
+ mCanvasState.writableSnapshot()->applyClip(op.localClip,
*mCanvasState.currentSnapshot()->transform);
mCanvasState.concatMatrix(op.localMatrix);
diff --git a/libs/hwui/OpDumper.cpp b/libs/hwui/OpDumper.cpp
index c34cfbe..cab93e8 100644
--- a/libs/hwui/OpDumper.cpp
+++ b/libs/hwui/OpDumper.cpp
@@ -33,10 +33,15 @@
op.localMatrix.mapRect(localBounds);
output << sOpNameLut[op.opId] << " " << localBounds;
- if (op.localClip && !op.localClip->rect.contains(localBounds)) {
+ if (op.localClip
+ && (!op.localClip->rect.contains(localBounds) || op.localClip->intersectWithRoot)) {
output << std::fixed << std::setprecision(0)
<< " clip=" << op.localClip->rect
<< " mode=" << (int)op.localClip->mode;
+
+ if (op.localClip->intersectWithRoot) {
+ output << " iwr";
+ }
}
}
diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp
index 4e9ac9c..7e85333 100644
--- a/libs/hwui/PathParser.cpp
+++ b/libs/hwui/PathParser.cpp
@@ -156,6 +156,12 @@
return;
}
+bool PathParser::isVerbValid(char verb) {
+ verb = tolower(verb);
+ return verb == 'a' || verb == 'c' || verb == 'h' || verb == 'l' || verb == 'm' || verb == 'q'
+ || verb == 's' || verb == 't' || verb == 'v' || verb == 'z';
+}
+
void PathParser::getPathDataFromString(PathData* data, ParseResult* result,
const char* pathStr, size_t strLen) {
if (pathStr == NULL) {
@@ -171,6 +177,12 @@
end = nextStart(pathStr, strLen, end);
std::vector<float> points;
getFloats(&points, result, pathStr, start, end);
+ if (!isVerbValid(pathStr[start])) {
+ result->failureOccurred = true;
+ result->failureMessage = "Invalid pathData. Failure occurred at position "
+ + std::to_string(start) + " of path: " + pathStr;
+ }
+ // If either verb or points is not valid, return immediately.
if (result->failureOccurred) {
return;
}
@@ -182,10 +194,15 @@
}
if ((end - start) == 1 && start < strLen) {
+ if (!isVerbValid(pathStr[start])) {
+ result->failureOccurred = true;
+ result->failureMessage = "Invalid pathData. Failure occurred at position "
+ + std::to_string(start) + " of path: " + pathStr;
+ return;
+ }
data->verbs.push_back(pathStr[start]);
data->verbSizes.push_back(0);
}
- return;
}
void PathParser::dump(const PathData& data) {
@@ -218,7 +235,8 @@
// Check if there is valid data coming out of parsing the string.
if (pathData.verbs.size() == 0) {
result->failureOccurred = true;
- result->failureMessage = "No verbs found in the string for pathData";
+ result->failureMessage = "No verbs found in the string for pathData: ";
+ result->failureMessage += pathStr;
return;
}
VectorDrawableUtils::verbsToPath(skPath, pathData);
diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h
index c4bbb74..180a7a3 100644
--- a/libs/hwui/PathParser.h
+++ b/libs/hwui/PathParser.h
@@ -44,6 +44,7 @@
ANDROID_API static void getPathDataFromString(PathData* outData, ParseResult* result,
const char* pathStr, size_t strLength);
static void dump(const PathData& data);
+ static bool isVerbValid(char verb);
};
}; // namespace uirenderer
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 9578486..ea06fcd 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -81,14 +81,14 @@
#endif
}
-void RenderNode::setStagingDisplayList(DisplayList* displayList) {
+void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) {
mNeedsDisplayListSync = true;
delete mStagingDisplayList;
mStagingDisplayList = displayList;
// If mParentCount == 0 we are the sole reference to this RenderNode,
// so immediately free the old display list
if (!mParentCount && !mStagingDisplayList) {
- deleteDisplayList(nullptr);
+ deleteDisplayList(observer);
}
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index b0136cf..acdc3d8 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -117,7 +117,7 @@
void debugDumpLayers(const char* prefix);
- ANDROID_API void setStagingDisplayList(DisplayList* newData);
+ ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
void computeOrdering();
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index d784280..2c9c9d9 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -242,6 +242,33 @@
#endif
}
+static Snapshot* getClipRoot(Snapshot* target) {
+ while (target->previous && target->previous->previous) {
+ target = target->previous;
+ }
+ return target;
+}
+
+const ClipBase* Snapshot::serializeIntersectedClip(LinearAllocator& allocator,
+ const ClipBase* recordedClip, const Matrix4& recordedClipTransform) {
+ auto target = this;
+ if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
+ // Clip must be intersected with root, instead of current clip.
+ target = getClipRoot(this);
+ }
+
+ return target->mClipArea->serializeIntersectedClip(allocator,
+ recordedClip, recordedClipTransform);
+}
+
+void Snapshot::applyClip(const ClipBase* recordedClip, const Matrix4& transform) {
+ if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
+ // current clip is being replaced, but must intersect with clip root
+ *mClipArea = *(getClipRoot(this)->mClipArea);
+ }
+ mClipArea->applyClip(recordedClip, transform);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Queries
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 3a01d04..d8f926e 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -170,6 +170,10 @@
const ClipArea& getClipArea() const { return *mClipArea; }
ClipArea& mutateClipArea() { return *mClipArea; }
+ WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
+ const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
+ void applyClip(const ClipBase* clip, const Matrix4& transform);
+
/**
* Resets the clip to the specified rect.
*/
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index b9e3358..b39de26 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -22,8 +22,9 @@
namespace android {
-MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
- mTypeface(typeface) {
+MinikinFontSkia::MinikinFontSkia(SkTypeface* typeface, const void* fontData, size_t fontSize,
+ int ttcIndex) :
+ mTypeface(typeface), mFontData(fontData), mFontSize(fontSize), mTtcIndex(ttcIndex) {
}
MinikinFontSkia::~MinikinFontSkia() {
@@ -66,22 +67,38 @@
bounds->mBottom = skBounds.fBottom;
}
-bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
- if (buf == NULL) {
- const size_t tableSize = mTypeface->getTableSize(tag);
- *size = tableSize;
- return tableSize != 0;
- } else {
- const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
- *size = actualSize;
- return actualSize != 0;
+const void* MinikinFontSkia::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) {
+ // we don't have a buffer to the font data, copy to own buffer
+ const size_t tableSize = mTypeface->getTableSize(tag);
+ *size = tableSize;
+ if (tableSize == 0) {
+ return nullptr;
}
+ void* buf = malloc(tableSize);
+ if (buf == nullptr) {
+ return nullptr;
+ }
+ mTypeface->getTableData(tag, 0, tableSize, buf);
+ *destroy = free;
+ return buf;
}
SkTypeface *MinikinFontSkia::GetSkTypeface() const {
return mTypeface;
}
+const void* MinikinFontSkia::GetFontData() const {
+ return mFontData;
+}
+
+size_t MinikinFontSkia::GetFontSize() const {
+ return mFontSize;
+}
+
+int MinikinFontSkia::GetFontIndex() const {
+ return mTtcIndex;
+}
+
int32_t MinikinFontSkia::GetUniqueId() const {
return mTypeface->uniqueID();
}
diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h
index 1d50168..dbc65f9 100644
--- a/libs/hwui/hwui/MinikinSkia.h
+++ b/libs/hwui/hwui/MinikinSkia.h
@@ -28,7 +28,8 @@
class ANDROID_API MinikinFontSkia : public MinikinFont {
public:
// Note: this takes ownership of the reference (will unref on dtor)
- explicit MinikinFontSkia(SkTypeface *typeface);
+ explicit MinikinFontSkia(SkTypeface *typeface, const void* fontData, size_t fontSize,
+ int ttcIndex);
~MinikinFontSkia();
@@ -38,20 +39,30 @@
void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
const MinikinPaint &paint) const;
- // If buf is NULL, just update size
- bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
+ const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy);
int32_t GetUniqueId() const;
SkTypeface* GetSkTypeface() const;
+ // Access to underlying raw font bytes
+ const void* GetFontData() const;
+ size_t GetFontSize() const;
+ int GetFontIndex() const;
+
static uint32_t packPaintFlags(const SkPaint* paint);
static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
// set typeface and fake bold/italic parameters
static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery);
private:
- SkTypeface *mTypeface;
+ SkTypeface* mTypeface;
+
+ // A raw pointer to the font data - it should be owned by some other object with
+ // lifetime at least as long as this object.
+ const void* mFontData;
+ size_t mFontSize;
+ int mTtcIndex;
};
} // namespace android
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index fa8ad5d..c583988 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -66,7 +66,10 @@
ALOGD("makeFontCollection adding %s", fn);
SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
if (skFace != NULL) {
- MinikinFont *font = new MinikinFontSkia(skFace);
+ // TODO: might be a nice optimization to get access to the underlying font
+ // data, but would require us opening the file ourselves and passing that
+ // to the appropriate Create method of SkTypeface.
+ MinikinFont *font = new MinikinFontSkia(skFace, NULL, 0, 0);
family->addFont(font);
font->Unref();
} else {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 63fa788..890d4a1 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -76,15 +76,15 @@
}
CanvasContext::~CanvasContext() {
- destroy();
+ destroy(nullptr);
mRenderThread.renderState().unregisterCanvasContext(this);
}
-void CanvasContext::destroy() {
+void CanvasContext::destroy(TreeObserver* observer) {
stopDrawing();
setSurface(nullptr);
- freePrefetechedLayers();
- destroyHardwareResources();
+ freePrefetchedLayers(observer);
+ destroyHardwareResources(observer);
mAnimationContext->destroy();
#if !HWUI_NEW_OPS
if (mCanvas) {
@@ -113,18 +113,11 @@
mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
mHaveNewSurface = true;
mSwapHistory.clear();
- makeCurrent();
} else {
mRenderThread.removeFrameCallback(this);
}
}
-void CanvasContext::requireSurface() {
- LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
- "requireSurface() called but no surface set!");
- makeCurrent();
-}
-
void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) {
mSwapBehavior = swapBehavior;
}
@@ -146,6 +139,18 @@
return mRenderThread.removeFrameCallback(this);
}
+void CanvasContext::setStopped(bool stopped) {
+ if (mStopped != stopped) {
+ mStopped = stopped;
+ if (mStopped) {
+ mRenderThread.removeFrameCallback(this);
+ if (mEglManager.isCurrent(mEglSurface)) {
+ mEglManager.makeCurrent(EGL_NO_SURFACE);
+ }
+ }
+ }
+}
+
// TODO: don't pass viewport size, it's automatic via EGL
void CanvasContext::setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
@@ -172,7 +177,9 @@
mOpaque = opaque;
}
-void CanvasContext::makeCurrent() {
+bool CanvasContext::makeCurrent() {
+ if (mStopped) return false;
+
// TODO: Figure out why this workaround is needed, see b/13913604
// In the meantime this matches the behavior of GLRenderer, so it is not a regression
EGLint error = 0;
@@ -180,6 +187,7 @@
if (error) {
setSurface(nullptr);
}
+ return !error;
}
static bool wasSkipped(FrameInfo* info) {
@@ -222,7 +230,7 @@
mAnimationContext->runRemainingAnimations(info);
GL_CHECKPOINT(MODERATE);
- freePrefetechedLayers();
+ freePrefetchedLayers(info.observer);
GL_CHECKPOINT(MODERATE);
if (CC_UNLIKELY(!mNativeSurface.get())) {
@@ -569,25 +577,24 @@
}
void CanvasContext::markLayerInUse(RenderNode* node) {
- if (mPrefetechedLayers.erase(node)) {
+ if (mPrefetchedLayers.erase(node)) {
node->decStrong(nullptr);
}
}
-static void destroyPrefetechedNode(RenderNode* node) {
- ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
- node->destroyHardwareResources(nullptr);
- node->decStrong(nullptr);
-}
-
-void CanvasContext::freePrefetechedLayers() {
- if (mPrefetechedLayers.size()) {
- std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
- mPrefetechedLayers.clear();
+void CanvasContext::freePrefetchedLayers(TreeObserver* observer) {
+ if (mPrefetchedLayers.size()) {
+ for (auto& node : mPrefetchedLayers) {
+ ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...",
+ node->getName());
+ node->destroyHardwareResources(observer);
+ node->decStrong(observer);
+ }
+ mPrefetchedLayers.clear();
}
}
-void CanvasContext::buildLayer(RenderNode* node) {
+void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
ATRACE_CALL();
if (!mEglManager.hasEglContext()) return;
#if !HWUI_NEW_OPS
@@ -599,6 +606,7 @@
TreeInfo info(TreeInfo::MODE_FULL, *this);
info.damageAccumulator = &mDamageAccumulator;
+ info.observer = observer;
#if HWUI_NEW_OPS
info.layerUpdateQueue = &mLayerUpdateQueue;
#else
@@ -628,7 +636,7 @@
#endif
node->incStrong(nullptr);
- mPrefetechedLayers.insert(node);
+ mPrefetchedLayers.insert(node);
}
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
@@ -636,12 +644,12 @@
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
}
-void CanvasContext::destroyHardwareResources() {
+void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
stopDrawing();
if (mEglManager.hasEglContext()) {
- freePrefetechedLayers();
+ freePrefetchedLayers(observer);
for (const sp<RenderNode>& node : mRenderNodes) {
- node->destroyHardwareResources(nullptr);
+ node->destroyHardwareResources(observer);
}
Caches& caches = Caches::getInstance();
// Make sure to release all the textures we were owning as there won't
@@ -671,7 +679,7 @@
}
Layer* CanvasContext::createTextureLayer() {
- requireSurface();
+ mEglManager.initialize();
return LayerRenderer::createTextureLayer(mRenderThread.renderState());
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6d0889e..52df3abe 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -82,27 +82,28 @@
void initialize(Surface* surface);
void updateSurface(Surface* surface);
bool pauseSurface(Surface* surface);
+ void setStopped(bool stopped);
bool hasSurface() { return mNativeSurface.get(); }
void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
void setLightCenter(const Vector3& lightCenter);
void setOpaque(bool opaque);
- void makeCurrent();
+ bool makeCurrent();
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
int64_t syncQueued, RenderNode* target);
void draw();
- void destroy();
+ void destroy(TreeObserver* observer);
// IFrameCallback, Choreographer-driven frame callback entry point
virtual void doFrame() override;
void prepareAndDraw(RenderNode* node);
- void buildLayer(RenderNode* node);
+ void buildLayer(RenderNode* node, TreeObserver* observer);
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
void markLayerInUse(RenderNode* node);
- void destroyHardwareResources();
+ void destroyHardwareResources(TreeObserver* observer);
static void trimMemory(RenderThread& thread, int level);
static void invokeFunctor(RenderThread& thread, Functor* functor);
@@ -172,9 +173,8 @@
friend class android::uirenderer::RenderState;
void setSurface(Surface* window);
- void requireSurface();
- void freePrefetechedLayers();
+ void freePrefetchedLayers(TreeObserver* observer);
void waitOnFences();
@@ -185,6 +185,7 @@
EglManager& mEglManager;
sp<Surface> mNativeSurface;
EGLSurface mEglSurface = EGL_NO_SURFACE;
+ bool mStopped = false;
bool mBufferPreserved = false;
SwapBehavior mSwapBehavior = kSwap_default;
struct SwapHistory {
@@ -218,7 +219,7 @@
FrameInfoVisualizer mProfiler;
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
- std::set<RenderNode*> mPrefetechedLayers;
+ std::set<RenderNode*> mPrefetchedLayers;
// Stores the bounds of the main content.
Rect mContentDrawBounds;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index e8b9725..ed472ac 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -65,11 +65,12 @@
}
}
-int DrawFrameTask::drawFrame() {
+int DrawFrameTask::drawFrame(TreeObserver* observer) {
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
mSyncResult = kSync_OK;
mSyncQueued = systemTime(CLOCK_MONOTONIC);
+ mObserver = observer;
postAndWait();
return mSyncResult;
@@ -88,6 +89,7 @@
bool canDrawThisFrame;
{
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
+ info.observer = mObserver;
canUnblockUiThread = syncFrameState(info);
canDrawThisFrame = info.out.canDrawThisFrame;
}
@@ -113,7 +115,7 @@
ATRACE_CALL();
int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
mRenderThread->timeLord().vsyncReceived(vsync);
- mContext->makeCurrent();
+ bool canDraw = mContext->makeCurrent();
Caches::getInstance().textureCache.resetMarkInUse(mContext);
for (size_t i = 0; i < mLayers.size(); i++) {
@@ -124,8 +126,9 @@
// This is after the prepareTree so that any pending operations
// (RenderNode tree state, prefetched layers, etc...) will be flushed.
- if (CC_UNLIKELY(!mContext->hasSurface())) {
+ if (CC_UNLIKELY(!mContext->hasSurface() || !canDraw)) {
mSyncResult |= kSync_LostSurfaceRewardIfFound;
+ info.out.canDrawThisFrame = false;
}
if (info.out.hasAnimations) {
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index cae251a9..9bba065 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -62,7 +62,7 @@
void pushLayerUpdate(DeferredLayerUpdater* layer);
void removeLayerUpdate(DeferredLayerUpdater* layer);
- int drawFrame();
+ int drawFrame(TreeObserver* observer);
int64_t* frameInfo() { return mFrameInfo; }
@@ -87,6 +87,7 @@
int mSyncResult;
int64_t mSyncQueued;
+ TreeObserver* mObserver;
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
};
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 8def7ad..ac6a28f 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -270,12 +270,6 @@
// Ensure we always have a valid surface & context
surface = mPBufferSurface;
}
- // TODO: Temporary to help diagnose b/27286867
- if (mCurrentSurface == mPBufferSurface || surface == mPBufferSurface) {
- ALOGD("Switching from surface %p%s to %p%s", mCurrentSurface,
- mCurrentSurface == mPBufferSurface ? " (pbuffer)" : "",
- surface, surface == mPBufferSurface ? " (pbuffer)" : "");
- }
if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
if (errOut) {
*errOut = eglGetError();
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 16dd108..c5a2dc7 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -52,14 +52,6 @@
MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \
ARGS(method) *args = (ARGS(method) *) task->payload()
-namespace DumpFlags {
- enum {
- FrameStats = 1 << 0,
- Reset = 1 << 1,
- JankStats = 1 << 2,
- };
-};
-
CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
return new CanvasContext(*args->thread, args->translucent,
@@ -175,6 +167,18 @@
return (bool) postAndWait(task);
}
+CREATE_BRIDGE2(setStopped, CanvasContext* context, bool stopped) {
+ args->context->setStopped(args->stopped);
+ return nullptr;
+}
+
+void RenderProxy::setStopped(bool stopped) {
+ SETUP_TASK(setStopped);
+ args->context = mContext;
+ args->stopped = stopped;
+ postAndWait(task);
+}
+
CREATE_BRIDGE6(setup, CanvasContext* context, int width, int height,
float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
args->context->setup(args->width, args->height, args->lightRadius,
@@ -222,18 +226,19 @@
return mDrawFrameTask.frameInfo();
}
-int RenderProxy::syncAndDrawFrame() {
- return mDrawFrameTask.drawFrame();
+int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
+ return mDrawFrameTask.drawFrame(observer);
}
-CREATE_BRIDGE1(destroy, CanvasContext* context) {
- args->context->destroy();
+CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
+ args->context->destroy(args->observer);
return nullptr;
}
-void RenderProxy::destroy() {
+void RenderProxy::destroy(TreeObserver* observer) {
SETUP_TASK(destroy);
args->context = mContext;
+ args->observer = observer;
// destroyCanvasAndSurface() needs a fence as when it returns the
// underlying BufferQueue is going to be released from under
// the render thread.
@@ -287,15 +292,16 @@
return layer;
}
-CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
- args->context->buildLayer(args->node);
+CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
+ args->context->buildLayer(args->node, args->observer);
return nullptr;
}
-void RenderProxy::buildLayer(RenderNode* node) {
+void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
SETUP_TASK(buildLayer);
args->context = mContext;
args->node = node;
+ args->observer = observer;
postAndWait(task);
}
@@ -332,15 +338,16 @@
postAndWait(task);
}
-CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
- args->context->destroyHardwareResources();
+CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
+ args->context->destroyHardwareResources(args->observer);
return nullptr;
}
-void RenderProxy::destroyHardwareResources() {
+void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
SETUP_TASK(destroyHardwareResources);
args->context = mContext;
- post(task);
+ args->observer = observer;
+ postAndWait(task);
}
CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
@@ -422,6 +429,9 @@
if (args->dumpFlags & DumpFlags::Reset) {
args->context->resetFrameStats();
}
+ if (args->dumpFlags & DumpFlags::JankStats) {
+ args->thread->jankTracker().dump(args->fd);
+ }
return nullptr;
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8d65a82..32d3283b 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -42,6 +42,7 @@
class DisplayList;
class Layer;
class Rect;
+class TreeObserver;
namespace renderthread {
@@ -49,6 +50,14 @@
class RenderThread;
class RenderProxyBridge;
+namespace DumpFlags {
+ enum {
+ FrameStats = 1 << 0,
+ Reset = 1 << 1,
+ JankStats = 1 << 2,
+ };
+};
+
/*
* RenderProxy is strictly single threaded. All methods must be invoked on the owning
* thread. It is important to note that RenderProxy may be deleted while it has
@@ -70,26 +79,27 @@
ANDROID_API void initialize(const sp<Surface>& surface);
ANDROID_API void updateSurface(const sp<Surface>& surface);
ANDROID_API bool pauseSurface(const sp<Surface>& surface);
+ ANDROID_API void setStopped(bool stopped);
ANDROID_API void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
ANDROID_API void setLightCenter(const Vector3& lightCenter);
ANDROID_API void setOpaque(bool opaque);
ANDROID_API int64_t* frameInfo();
- ANDROID_API int syncAndDrawFrame();
- ANDROID_API void destroy();
+ ANDROID_API int syncAndDrawFrame(TreeObserver* observer);
+ ANDROID_API void destroy(TreeObserver* observer);
ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
ANDROID_API void runWithGlContext(RenderTask* task);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
- ANDROID_API void buildLayer(RenderNode* node);
+ ANDROID_API void buildLayer(RenderNode* node, TreeObserver* observer);
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
- ANDROID_API void destroyHardwareResources();
+ ANDROID_API void destroyHardwareResources(TreeObserver* observer);
ANDROID_API static void trimMemory(int level);
ANDROID_API static void overrideProperty(const char* name, const char* value);
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5492035..5f4ebc0 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -146,7 +146,7 @@
if (setup) {
TestCanvas canvas(props.getWidth(), props.getHeight());
setup(props, canvas);
- node->setStagingDisplayList(canvas.finishRecording());
+ node->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
node->setPropertyFieldsDirty(0xFFFFFFFF);
return node;
@@ -157,7 +157,7 @@
TestCanvas canvas(node.stagingProperties().getWidth(),
node.stagingProperties().getHeight());
contentCallback(canvas);
- node.setStagingDisplayList(canvas.finishRecording());
+ node.setStagingDisplayList(canvas.finishRecording(), nullptr);
}
/**
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 63c067b..f184411 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -59,6 +59,6 @@
0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr);
}
- container->setStagingDisplayList(canvas.finishRecording());
+ container->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
};
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index ab368c05..8035dc4 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -76,7 +76,7 @@
// draw it to parent DisplayList
canvas.drawRenderNode(cards[ci].get());
}
- listView->setStagingDisplayList(canvas.finishRecording());
+ listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
private:
SkBitmap createRandomCharIcon() {
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 58c0876..c5af061 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -95,7 +95,7 @@
testContext.waitForVsync();
nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
proxy->resetProfileInfo();
@@ -110,7 +110,7 @@
ATRACE_NAME("UI-Draw Frame");
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
scene->doFrame(i);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
if (opts.reportFrametimeWeight) {
proxy->fence();
@@ -122,5 +122,5 @@
}
}
- proxy->dumpProfileInfo(STDOUT_FILENO, 0);
+ proxy->dumpProfileInfo(STDOUT_FILENO, DumpFlags::JankStats);
}
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index 822d04f..b864703 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -132,8 +132,7 @@
auto serializedClip = area.serializeClip(allocator);
ASSERT_NE(nullptr, serializedClip);
ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode);
- auto clipRect = reinterpret_cast<const ClipRect*>(serializedClip);
- EXPECT_EQ(Rect(200, 200), clipRect->rect);
+ EXPECT_EQ(Rect(200, 200), serializedClip->rect);
EXPECT_EQ(serializedClip, area.serializeClip(allocator))
<< "Requery of clip on unmodified ClipArea must return same pointer.";
}
@@ -192,8 +191,7 @@
auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);
ASSERT_NE(nullptr, resolvedClip);
ASSERT_EQ(ClipMode::Rectangle, resolvedClip->mode);
- EXPECT_EQ(Rect(100, 100, 200, 200),
- reinterpret_cast<const ClipRect*>(resolvedClip)->rect);
+ EXPECT_EQ(Rect(100, 100, 200, 200), resolvedClip->rect);
EXPECT_EQ(resolvedClip, area.serializeIntersectedClip(allocator, &recordedClip, translateScale))
<< "Must return previous serialization, since input is same";
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 0ea246f..9877439 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -1946,5 +1946,28 @@
EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
}
+RENDERTHREAD_TEST(FrameBuilder, clip_replace) {
+ class ClipReplaceTestRenderer : public TestRendererBase {
+ public:
+ void onColorOp(const ColorOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(0, mIndex++);
+ EXPECT_TRUE(op.localClip->intersectWithRoot);
+ EXPECT_EQ(Rect(20, 10, 30, 40), state.computedState.clipState->rect)
+ << "Expect resolved clip to be intersection of viewport clip and clip op";
+ }
+ };
+ auto node = TestUtils::createNode(20, 20, 30, 30,
+ [](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.clipRect(0, -20, 10, 30, SkRegion::kReplace_Op);
+ canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+ });
+
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeLTRB(10, 10, 40, 40), 50, 50,
+ TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+ ClipReplaceTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(1, renderer.getIndex());
+}
+
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 58376c6..c49ff71 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -569,6 +569,19 @@
EXPECT_CLIP_RECT(Rect(-100, -100, 300, 300), dl->getOps()[0]->localClip);
}
+TEST(RecordingCanvas, replaceClipIntersectWithRoot) {
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.clipRect(-10, -10, 110, 110, SkRegion::kReplace_Op);
+ canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+ canvas.restore();
+ });
+ ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op";
+ // first clip must be preserved, even if it extends beyond canvas bounds
+ EXPECT_CLIP_RECT(Rect(-10, -10, 110, 110), dl->getOps()[0]->localClip);
+ EXPECT_TRUE(dl->getOps()[0]->localClip->intersectWithRoot);
+}
+
TEST(RecordingCanvas, insertReorderBarrier) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
canvas.drawRect(0, 0, 400, 400, SkPaint());
diff --git a/libs/hwui/tests/unit/SnapshotTests.cpp b/libs/hwui/tests/unit/SnapshotTests.cpp
new file mode 100644
index 0000000..11797a8
--- /dev/null
+++ b/libs/hwui/tests/unit/SnapshotTests.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <Snapshot.h>
+
+#include <tests/common/TestUtils.h>
+
+using namespace android::uirenderer;
+
+TEST(Snapshot, serializeIntersectedClip) {
+ auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
+ auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
+ auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+ root->previous = actualRoot.get();
+ child->previous = root.get();
+
+ LinearAllocator allocator;
+ ClipRect rect(Rect(0, 0, 75, 75));
+ {
+ auto intersectWithChild = child->serializeIntersectedClip(allocator,
+ &rect, Matrix4::identity());
+ ASSERT_NE(nullptr, intersectWithChild);
+ EXPECT_EQ(Rect(50, 50, 75, 75), intersectWithChild->rect) << "Expect intersect with child";
+ }
+
+ rect.intersectWithRoot = true;
+ {
+ auto intersectWithRoot = child->serializeIntersectedClip(allocator,
+ &rect, Matrix4::identity());
+ ASSERT_NE(nullptr, intersectWithRoot);
+ EXPECT_EQ(Rect(10, 10, 75, 75), intersectWithRoot->rect) << "Expect intersect with root";
+ }
+}
+
+TEST(Snapshot, applyClip) {
+ auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
+ auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
+ root->previous = actualRoot.get();
+
+ ClipRect rect(Rect(0, 0, 75, 75));
+ {
+ auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+ child->previous = root.get();
+ child->applyClip(&rect, Matrix4::identity());
+
+ EXPECT_TRUE(child->getClipArea().isSimple());
+ EXPECT_EQ(Rect(50, 50, 75, 75), child->getRenderTargetClip());
+ }
+
+ {
+ rect.intersectWithRoot = true;
+ auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+ child->previous = root.get();
+ child->applyClip(&rect, Matrix4::identity());
+
+ EXPECT_TRUE(child->getClipArea().isSimple());
+ EXPECT_EQ(Rect(10, 10, 75, 75), child->getRenderTargetClip());
+ }
+}
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 7208547..796169e 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -231,11 +231,12 @@
};
const StringPath sStringPaths[] = {
- {"3e...3", false},
- {"L.M.F.A.O", false},
- {"m 1 1", true},
- {"z", true},
- {"1-2e34567", false}
+ {"3e...3", false}, // Not starting with a verb and ill-formatted float
+ {"L.M.F.A.O", false}, // No floats following verbs
+ {"m 1 1", true}, // Valid path data
+ {"z", true}, // Valid path data
+ {"1-2e34567", false}, // Not starting with a verb and ill-formatted float
+ {"f 4 5", false} // Invalid verb
};
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index b0431ce..b3195c4 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -104,8 +104,8 @@
}
void finishDrawing() {
- mRootNode->setStagingDisplayList(mCanvas->finishRecording());
- mProxy->syncAndDrawFrame();
+ mRootNode->setStagingDisplayList(mCanvas->finishRecording(), nullptr);
+ mProxy->syncAndDrawFrame(nullptr);
// Surprisingly, calling mProxy->fence() here appears to make no difference to
// the timings we record.
}
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index df42a73..25d247d 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -22,7 +22,8 @@
/**
* A class containing a GPS clock timestamp.
- * It represents a measurement of the GPS receiver's clock.
+ *
+ * <p>It represents a measurement of the GPS receiver's clock.
*/
public final class GnssClock implements Parcelable {
// The following enumerations must be in sync with the values declared in gps.h
@@ -85,7 +86,7 @@
}
/**
- * Returns true if {@link #getLeapSecond()} is available, false otherwise.
+ * Returns {@code true} if {@link #getLeapSecond()} is available, {@code false} otherwise.
*/
public boolean hasLeapSecond() {
return isFlagSet(HAS_LEAP_SECOND);
@@ -93,10 +94,12 @@
/**
* Gets the leap second associated with the clock's time.
- * The sign of the value is defined by the following equation:
- * utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000
*
- * The value is only available if {@link #hasLeapSecond()} is true.
+ * <p>The sign of the value is defined by the following equation:
+ * <pre>
+ * UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000</pre>
+ *
+ * <p>The value is only available if {@link #hasLeapSecond()} is {@code true}.
*/
public int getLeapSecond() {
return mLeapSecond;
@@ -123,18 +126,15 @@
}
/**
- * Gets the GNSS receiver internal clock value in nanoseconds.
+ * Gets the GNSS receiver internal hardware clock value in nanoseconds.
*
- * For 'local hardware clock' this value is expected to be monotonically increasing during the
- * reporting session. The real GPS time can be derived by compensating
- * {@link #getFullBiasNanos()} (when it is available) from this value.
+ * <p>This value is expected to be monotonically increasing while the hardware clock remains
+ * powered on. For the case of a hardware clock that is not continuously on, see the
+ * {@link #getHardwareClockDiscontinuityCount} field. The GPS time can be derived by subtracting
+ * the sum of {@link #getFullBiasNanos()} and {@link #getBiasNanos()} (when they are available)
+ * from this value. Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
*
- * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS
- * receiver can achieve. {@link #getTimeUncertaintyNanos()} should be available when GPS time is
- * specified.
- *
- * Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
- * The reported time includes {@link #getTimeUncertaintyNanos()}.
+ * <p>The error estimate for this value (if applicable) is {@link #getTimeUncertaintyNanos()}.
*/
public long getTimeNanos() {
return mTimeNanos;
@@ -150,7 +150,8 @@
}
/**
- * Returns true if {@link #getTimeUncertaintyNanos()} is available, false otherwise.
+ * Returns {@code true} if {@link #getTimeUncertaintyNanos()} is available, {@code false}
+ * otherwise.
*/
public boolean hasTimeUncertaintyNanos() {
return isFlagSet(HAS_TIME_UNCERTAINTY);
@@ -158,9 +159,13 @@
/**
* Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
- * The uncertainty is represented as an absolute (single sided) value.
*
- * The value is only available if {@link #hasTimeUncertaintyNanos()} is true.
+ * <p>The uncertainty is represented as an absolute (single sided) value.
+ *
+ * <p>The value is only available if {@link #hasTimeUncertaintyNanos()} is {@code true}.
+ *
+ * <p>This value is often effectively zero (it is the reference clock by which all other times
+ * and time uncertainties are measured), and thus this field may often be 0, or not provided.
*/
public double getTimeUncertaintyNanos() {
return mTimeUncertaintyNanos;
@@ -187,7 +192,7 @@
}
/**
- * Returns true if {@link #getFullBiasNanos()} is available, false otherwise.
+ * Returns {@code true} if {@link #getFullBiasNanos()} is available, {@code false} otherwise.
*/
public boolean hasFullBiasNanos() {
return isFlagSet(HAS_FULL_BIAS);
@@ -197,14 +202,18 @@
* Gets the difference between hardware clock ({@link #getTimeNanos()}) inside GPS receiver and
* the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
*
- * This value is available if the receiver has estimated GPS time. If the computed time is for a
- * non-GPS constellation, the time offset of that constellation to GPS has to be applied to fill
- * this value. The value contains the 'bias uncertainty' {@link #getBiasUncertaintyNanos()} in
- * it, and it should be used for quality check. The value is only available if
- * {@link #hasFullBiasNanos()} is true.
+ * <p>This value is available if the receiver has estimated GPS time. If the computed time is
+ * for a non-GPS constellation, the time offset of that constellation to GPS has to be applied
+ * to fill this value. The value is only available if {@link #hasFullBiasNanos()} is
+ * {@code true}.
*
- * The sign of the value is defined by the following equation:
- * local estimate of GPS time = time_ns + (full_bias_ns + bias_ns)
+ * <p>The error estimate for the sum of this field and {@link #getBiasNanos} is
+ * {@link #getBiasUncertaintyNanos()}.
+ *
+ * <p>The sign of the value is defined by the following equation:
+ *
+ * <pre>
+ * local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)</pre>
*/
public long getFullBiasNanos() {
return mFullBiasNanos;
@@ -231,7 +240,7 @@
}
/**
- * Returns true if {@link #getBiasNanos()} is available, false otherwise.
+ * Returns {@code true} if {@link #getBiasNanos()} is available, {@code false} otherwise.
*/
public boolean hasBiasNanos() {
return isFlagSet(HAS_BIAS);
@@ -239,9 +248,14 @@
/**
* Gets the clock's sub-nanosecond bias.
- * The reported bias includes {@link #getBiasUncertaintyNanos()}.
*
- * The value is only available if {@link #hasBiasNanos()} is true.
+ * <p>See the description of how this field is part of converting from hardware clock time, to
+ * GPS time, in {@link #getFullBiasNanos()}.
+ *
+ * <p>The error estimate for the sum of this field and {@link #getFullBiasNanos} is
+ * {@link #getBiasUncertaintyNanos()}.
+ *
+ * <p>The value is only available if {@link #hasBiasNanos()} is {@code true}.
*/
public double getBiasNanos() {
return mBiasNanos;
@@ -268,7 +282,8 @@
}
/**
- * Returns true if {@link #getBiasUncertaintyNanos()} is available, false otherwise.
+ * Returns {@code true} if {@link #getBiasUncertaintyNanos()} is available, {@code false}
+ * otherwise.
*/
public boolean hasBiasUncertaintyNanos() {
return isFlagSet(HAS_BIAS_UNCERTAINTY);
@@ -277,7 +292,10 @@
/**
* Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*
- * The value is only available if {@link #hasBiasUncertaintyNanos()} is true.
+ * <p>See the description of how this field provides the error estimate in the conversion from
+ * hardware clock time, to GPS time, in {@link #getFullBiasNanos()}.
+ *
+ * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}.
*/
public double getBiasUncertaintyNanos() {
return mBiasUncertaintyNanos;
@@ -304,7 +322,8 @@
}
/**
- * Returns true if {@link #getDriftNanosPerSecond()} is available, false otherwise.
+ * Returns {@code true} if {@link #getDriftNanosPerSecond()} is available, {@code false}
+ * otherwise.
*/
public boolean hasDriftNanosPerSecond() {
return isFlagSet(HAS_DRIFT);
@@ -312,10 +331,12 @@
/**
* Gets the clock's Drift in nanoseconds per second.
- * A positive value indicates that the frequency is higher than the nominal frequency.
- * The reported drift includes {@link #getDriftUncertaintyNanosPerSecond()}.
*
- * The value is only available if {@link #hasDriftNanosPerSecond()} is true.
+ * <p>A positive value indicates that the frequency is higher than the nominal (e.g. GPS master
+ * clock) frequency. The error estimate for this reported drift is
+ * {@link #getDriftUncertaintyNanosPerSecond()}.
+ *
+ * <p>The value is only available if {@link #hasDriftNanosPerSecond()} is {@code true}.
*/
public double getDriftNanosPerSecond() {
return mDriftNanosPerSecond;
@@ -342,7 +363,8 @@
}
/**
- * Returns true if {@link #getDriftUncertaintyNanosPerSecond()} is available, false otherwise.
+ * Returns {@code true} if {@link #getDriftUncertaintyNanosPerSecond()} is available,
+ * {@code false} otherwise.
*/
public boolean hasDriftUncertaintyNanosPerSecond() {
return isFlagSet(HAS_DRIFT_UNCERTAINTY);
@@ -351,7 +373,8 @@
/**
* Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*
- * The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is true.
+ * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is
+ * {@code true}.
*/
public double getDriftUncertaintyNanosPerSecond() {
return mDriftUncertaintyNanosPerSecond;
@@ -368,7 +391,29 @@
}
/**
- * Gets count of last hardware clock discontinuity.
+ * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+ * @hide
+ */
+ @TestApi
+ public void resetDriftUncertaintyNanosPerSecond() {
+ resetFlag(HAS_DRIFT_UNCERTAINTY);
+ mDriftUncertaintyNanosPerSecond = Double.NaN;
+ }
+
+ /**
+ * Gets count of hardware clock discontinuities.
+ *
+ * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it
+ * can be safely assumed that the {@code TimeNanos} value has been derived from a clock that has
+ * been running continuously - e.g. a single continuously powered crystal oscillator, and thus
+ * the {@code (FullBiasNanos + BiasNanos)} offset can be modelled with traditional clock bias
+ * & drift models.
+ *
+ * <p>Each time this value changes, vs. the value in a previously reported {@link GnssClock},
+ * that suggests the hardware clock may have experienced a discontinuity (e.g. a power cycle or
+ * other anomaly), so that any assumptions about modelling a smoothly changing
+ * {@code (FullBiasNanos + BiasNanos)} offset, and a smoothly growing {@code (TimeNanos)}
+ * between this and the previously reported {@code GnssClock}, should be reset.
*/
public int getHardwareClockDiscontinuityCount() {
return mHardwareClockDiscontinuityCount;
@@ -383,16 +428,6 @@
mHardwareClockDiscontinuityCount = value;
}
- /**
- * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
- * @hide
- */
- @TestApi
- public void resetDriftUncertaintyNanosPerSecond() {
- resetFlag(HAS_DRIFT_UNCERTAINTY);
- mDriftUncertaintyNanosPerSecond = Double.NaN;
- }
-
public static final Creator<GnssClock> CREATOR = new Creator<GnssClock>() {
@Override
public GnssClock createFromParcel(Parcel parcel) {
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index d78ccee..761ee22 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -67,18 +67,21 @@
public @interface MultipathIndicator {}
/**
- * The indicator is not available or it is unknown.
+ * The indicator is not available or the presence or absence of multipath is unknown.
*/
public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
/**
- * The measurement has been indicated to use multi-path.
+ * The measurement shows signs of multi-path.
*/
public static final int MULTIPATH_INDICATOR_DETECTED = 1;
/**
- * The measurement has been indicated not tu use multi-path.
+ * The measurement shows no signs of multi-path.
*/
+ public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
+
+ /** @removed */
public static final int MULTIPATH_INDICATOR_NOT_USED = 2;
/** This GNSS measurement's tracking state is invalid or unknown. */
@@ -192,15 +195,17 @@
}
/**
- * Gets the Pseudo-random number (PRN).
- * Range: [1, 32]
+ * Gets the satellite ID.
+ *
+ * <p>Interpretation depends on {@link #getConstellationType()}.
+ * See {@link GnssStatus#getSvid(int)}.
*/
public int getSvid() {
return mSvid;
}
/**
- * Sets the Pseud-random number (PRN).
+ * Sets the Satellite ID.
* @hide
*/
@TestApi
@@ -209,7 +214,10 @@
}
/**
- * Getst the constellation type.
+ * Gets the constellation type.
+ *
+ * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+ * {@link GnssStatus}.
*/
@GnssStatus.ConstellationType
public int getConstellationType() {
@@ -228,13 +236,14 @@
/**
* Gets the time offset at which the measurement was taken in nanoseconds.
*
- * The reference receiver's time from which this is offset is specified by
+ * <p>The reference receiver's time from which this is offset is specified by
* {@link GnssClock#getTimeNanos()}.
*
- * The sign of this value is given by the following equation:
- * measurement time = time_ns + time_offset_ns
+ * <p>The sign of this value is given by the following equation:
+ * <pre>
+ * measurement time = TimeNanos + TimeOffsetNanos</pre>
*
- * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
+ * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
* accuracy.
*/
public double getTimeOffsetNanos() {
@@ -252,9 +261,10 @@
/**
* Gets per-satellite sync state.
- * It represents the current sync state for the associated satellite.
*
- * This value helps interpret {@link #getReceivedSvTimeNanos()}.
+ * <p>It represents the current sync state for the associated satellite.
+ *
+ * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
*/
public int getState() {
return mState;
@@ -271,7 +281,8 @@
/**
* Gets a string representation of the 'sync state'.
- * For internal and logging use only.
+ *
+ * <p>For internal and logging use only.
*/
private String getStateString() {
if (mState == STATE_UNKNOWN) {
@@ -335,66 +346,79 @@
/**
* Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
*
- * For GPS & QZSS, this is:
- * Received GPS Time-of-Week at the measurement time, in nanoseconds.
- * The value is relative to the beginning of the current GPS week.
+ * <p>For GPS & QZSS, this is:
+ * <ul>
+ * <li>Received GPS Time-of-Week at the measurement time, in nanoseconds.</li>
+ * <li>The value is relative to the beginning of the current GPS week.</li>
+ * </ul>
*
- * Given the highest sync state that can be achieved, per each satellite, valid range
- * for this field can be:
+ * <p>Given the highest sync state that can be achieved, per each satellite, valid range
+ * for this field can be:
+ * <pre>
* Searching : [ 0 ] : STATE_UNKNOWN
* C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set
* Bit sync : [ 0 20ms ] : STATE_BIT_SYNC is set
* Subframe sync : [ 0 6s ] : STATE_SUBFRAME_SYNC is set
- * TOW decoded : [ 0 1week ] : STATE_TOW_DECODED is set
+ * TOW decoded : [ 0 1week ] : STATE_TOW_DECODED is set</pre>
*
- * Note well: if there is any ambiguity in integer millisecond,
- * STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field.
+ * <p>Note well: if there is any ambiguity in integer millisecond, {@code STATE_MSEC_AMBIGUOUS}
+ * should be set accordingly, in the 'state' field.
*
- * This value must be populated if 'state' != STATE_UNKNOWN.
+ * <p>This value must be populated if 'state' != {@code STATE_UNKNOWN}.
*
- * For Glonass, this is:
- * Received Glonass time of day, at the measurement time in nanoseconds.
+ * <p>For Glonass, this is:
+ * <ul>
+ * <li>Received Glonass time of day, at the measurement time in nanoseconds.</li>
+ * </ul>
*
- * Given the highest sync state that can be achieved, per each satellite, valid range for
- * this field can be:
+ * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+ * this field can be:
+ * <pre>
* Searching : [ 0 ] : STATE_UNKNOWN
* C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set
- * Symbol sync : [ 0 10ms ] : STATE_SYMBOL_SYNC is set
- * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC is set
- * String sync : [ 0 2s ] : STATE_GLO_STRING_SYNC is set
- * Time of day : [ 0 1day ] : STATE_GLO_TOD_DECODED is set
+ * Symbol sync : [ 0 10ms ] : STATE_SYMBOL_SYNC is set
+ * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC is set
+ * String sync : [ 0 2s ] : STATE_GLO_STRING_SYNC is set
+ * Time of day : [ 0 1day ] : STATE_GLO_TOD_DECODED is set</pre>
*
- * For Beidou, this is:
- * Received Beidou time of week, at the measurement time in nanoseconds.
+ * <p>For Beidou, this is:
+ * <ul>
+ * <li>Received Beidou time of week, at the measurement time in nanoseconds.</li>
+ * </ul>
*
- * Given the highest sync state that can be achieved, per each satellite, valid range for
- * this field can be:
+ * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+ * this field can be:
+ * <pre>
* Searching : [ 0 ] : STATE_UNKNOWN
* C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set
* Bit sync (D2) : [ 0 2ms ] : STATE_BDS_D2_BIT_SYNC is set
* Bit sync (D1) : [ 0 20ms ] : STATE_BIT_SYNC is set
* Subframe (D2) : [ 0 0.6s ] : STATE_BDS_D2_SUBFRAME_SYNC is set
* Subframe (D1) : [ 0 6s ] : STATE_SUBFRAME_SYNC is set
- * Time of week : [ 0 1week ] : STATE_TOW_DECODED is set
+ * Time of week : [ 0 1week ] : STATE_TOW_DECODED is set</pre>
*
- * For Galileo, this is:
- * Received Galileo time of week, at the measurement time in nanoseconds.
+ * <p>For Galileo, this is:
+ * <ul>
+ * <li>Received Galileo time of week, at the measurement time in nanoseconds.</li>
+ * </ul>
+ * <pre>
+ * E1BC code lock : [ 0 4ms ] : STATE_GAL_E1BC_CODE_LOCK is set
+ * E1C 2nd code lock: [ 0 100ms ] : STATE_GAL_E1C_2ND_CODE_LOCK is set
+ * E1B page : [ 0 2s ] : STATE_GAL_E1B_PAGE_SYNC is set
+ * Time of week : [ 0 1week ] : STATE_GAL_TOW_DECODED is set</pre>
*
- * E1BC code lock : [ 0 4ms ] : STATE_GAL_E1BC_CODE_LOCK is set
- * E1C 2nd code lock : [ 0 100ms ] : STATE_GAL_E1C_2ND_CODE_LOCK is set
+ * <p>For SBAS, this is:
+ * <ul>
+ * <li>Received SBAS time, at the measurement time in nanoseconds.</li>
+ * </ul>
*
- * E1B page : [ 0 2s ] : STATE_GAL_E1B_PAGE_SYNC is set
- * Time of week : [ 0 1week ] : STATE_GAL_TOW_DECODED is set
- *
- * For SBAS, this is:
- * Received SBAS time, at the measurement time in nanoseconds.
- *
- * Given the highest sync state that can be achieved, per each satellite, valid range for
- * this field can be:
+ * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+ * this field can be:
+ * <pre>
* Searching : [ 0 ] : STATE_UNKNOWN
* C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set
* Symbol sync : [ 0 2ms ] : STATE_SYMBOL_SYNC is set
- * Message : [ 0 1s ] : STATE_SBAS_SYNC is set
+ * Message : [ 0 1s ] : STATE_SBAS_SYNC is set</pre>
*/
public long getReceivedSvTimeNanos() {
return mReceivedSvTimeNanos;
@@ -410,7 +434,7 @@
}
/**
- * Gets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
+ * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
*/
public long getReceivedSvTimeUncertaintyNanos() {
return mReceivedSvTimeUncertaintyNanos;
@@ -427,9 +451,10 @@
/**
* Gets the Carrier-to-noise density in dB-Hz.
- * Range: [0, 63].
*
- * The value contains the measured C/N0 for the signal at the antenna input.
+ * <p>Typical range: 10-50 db-Hz.
+ *
+ * <p>The value contains the measured C/N0 for the signal at the antenna input.
*/
public double getCn0DbHz() {
return mCn0DbHz;
@@ -447,16 +472,18 @@
/**
* Gets the Pseudorange rate at the timestamp in m/s.
*
- * The reported value includes {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
+ * <p>The error estimate for this value is
+ * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
*
- * The value is uncorrected, hence corrections for receiver and satellite clock frequency errors
- * should not be included.
+ * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
+ * errors are not included.
*
- * A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
+ * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
* sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
* is given by the equation:
*
- * pseudorange rate = -k * doppler shift (where k is a constant)
+ * <pre>
+ * pseudorange rate = -k * doppler shift (where k is a constant)</pre>
*/
public double getPseudorangeRateMetersPerSecond() {
return mPseudorangeRateMetersPerSecond;
@@ -473,7 +500,8 @@
/**
* Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
- * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * <p>The uncertainty is represented as an absolute (single sided) value.
*/
public double getPseudorangeRateUncertaintyMetersPerSecond() {
return mPseudorangeRateUncertaintyMetersPerSecond;
@@ -490,7 +518,8 @@
/**
* Gets 'Accumulated Delta Range' state.
- * It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
+ *
+ * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
* cycle slip (indicating 'loss of lock').
*/
public int getAccumulatedDeltaRangeState() {
@@ -508,7 +537,8 @@
/**
* Gets a string representation of the 'Accumulated Delta Range state'.
- * For internal and logging use only.
+ *
+ * <p>For internal and logging use only.
*/
private String getAccumulatedDeltaRangeStateString() {
if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
@@ -536,14 +566,17 @@
/**
* Gets the accumulated delta range since the last channel reset, in meters.
- * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
*
- * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+ * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
*
- * A positive value indicates that the SV is moving away from the receiver.
+ * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+ *
+ * <p>A positive value indicates that the SV is moving away from the receiver.
* The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
* {@link #getCarrierPhase()} is given by the equation:
- * accumulated delta range = -k * carrier phase (where k is a constant)
+ *
+ * <pre>
+ * accumulated delta range = -k * carrier phase (where k is a constant)</pre>
*/
public double getAccumulatedDeltaRangeMeters() {
return mAccumulatedDeltaRangeMeters;
@@ -560,9 +593,10 @@
/**
* Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
- * The uncertainty is represented as an absolute (single sided) value.
*
- * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+ * <p>The uncertainty is represented as an absolute (single sided) value.
+ *
+ * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
public double getAccumulatedDeltaRangeUncertaintyMeters() {
return mAccumulatedDeltaRangeUncertaintyMeters;
@@ -571,7 +605,7 @@
/**
* Sets the accumulated delta range's uncertainty (1-sigma) in meters.
*
- * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+ * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*
* @hide
*/
@@ -581,17 +615,20 @@
}
/**
- * Returns true if {@link #getCarrierFrequencyHz()} is available, false otherwise.
+ * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
+ * otherwise.
*/
public boolean hasCarrierFrequencyHz() {
return isFlagSet(HAS_CARRIER_FREQUENCY);
}
/**
- * Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
- * If the field is not set, the carrier frequency corresponds to L1.
+ * Gets the carrier frequency at which codes and messages are modulated.
*
- * The value is only available if {@link #hasCarrierFrequencyHz()} is true.
+ * <p>For GPS, e.g., it can be L1 or L2. If the field is not set, it is the primary common use
+ * frequency, e.g. L1 for GPS.
+ *
+ * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
*/
public float getCarrierFrequencyHz() {
return mCarrierFrequencyHz;
@@ -618,7 +655,7 @@
}
/**
- * Returns true if {@link #getCarrierCycles()} is available, false otherwise.
+ * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
*/
public boolean hasCarrierCycles() {
return isFlagSet(HAS_CARRIER_CYCLES);
@@ -626,9 +663,10 @@
/**
* The number of full carrier cycles between the satellite and the receiver.
- * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
*
- * The value is only available if {@link #hasCarrierCycles()} is true.
+ * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+ *
+ * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
*/
public long getCarrierCycles() {
return mCarrierCycles;
@@ -655,7 +693,7 @@
}
/**
- * Returns true if {@link #getCarrierPhase()} is available, false otherwise.
+ * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
*/
public boolean hasCarrierPhase() {
return isFlagSet(HAS_CARRIER_PHASE);
@@ -663,13 +701,16 @@
/**
* Gets the RF phase detected by the receiver.
- * Range: [0.0, 1.0].
- * This is usually the fractional part of the complete carrier phase measurement.
*
- * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
- * The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
+ * <p>Range: [0.0, 1.0].
*
- * The value is only available if {@link #hasCarrierPhase()} is true.
+ * <p>This is the fractional part of the complete carrier phase measurement.
+ *
+ * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+ *
+ * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
+ *
+ * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
*/
public double getCarrierPhase() {
return mCarrierPhase;
@@ -696,7 +737,8 @@
}
/**
- * Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
+ * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
+ * otherwise.
*/
public boolean hasCarrierPhaseUncertainty() {
return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
@@ -704,9 +746,10 @@
/**
* Gets the carrier-phase's uncertainty (1-Sigma).
- * The uncertainty is represented as an absolute (single sided) value.
*
- * The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
+ * <p>The uncertainty is represented as an absolute (single sided) value.
+ *
+ * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
*/
public double getCarrierPhaseUncertainty() {
return mCarrierPhaseUncertainty;
@@ -751,7 +794,8 @@
/**
* Gets a string representation of the 'multi-path indicator'.
- * For internal and logging use only.
+ *
+ * <p>For internal and logging use only.
*/
private String getMultipathIndicatorString() {
switch(mMultipathIndicator) {
@@ -767,7 +811,7 @@
}
/**
- * Returns true if {@link #getSnrInDb()} is available, false otherwise.
+ * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
*/
public boolean hasSnrInDb() {
return isFlagSet(HAS_SNR);
@@ -776,7 +820,7 @@
/**
* Gets the Signal-to-Noise ratio (SNR) in dB.
*
- * The value is only available if {@link #hasSnrInDb()} is true.
+ * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
*/
public double getSnrInDb() {
return mSnrInDb;
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index ec252a8..3151694 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.TestApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
@@ -33,29 +34,11 @@
* Events are delivered to registered instances of {@link Callback}.
*/
public final class GnssMeasurementsEvent implements Parcelable {
- /**
- * The status of the GNSS measurements event.
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GNSS_LOCATION_DISABLED})
- public @interface GnssMeasurementsStatus {}
-
- /**
- * The system does not support tracking of GNSS Measurements. This status will not change in the
- * future.
- */
+ /** @removed */
public static final int STATUS_NOT_SUPPORTED = 0;
-
- /**
- * GNSS Measurements are successfully being tracked, it will receive updates once they are
- * available.
- */
+ /** @removed */
public static final int STATUS_READY = 1;
-
- /**
- * GNSS provider or Location is disabled, updates will not be received until they are enabled.
- */
+ /** @removed */
public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
private final GnssClock mClock;
@@ -68,6 +51,32 @@
* {@link LocationManager#registerGnssMeasurementsCallback}.
*/
public static abstract class Callback {
+ /**
+ * The status of the GNSS measurements event.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+ public @interface GnssMeasurementsStatus {}
+
+ /**
+ * The system does not support tracking of GNSS Measurements.
+ *
+ * <p>This status will not change in the future.
+ */
+ public static final int STATUS_NOT_SUPPORTED = 0;
+
+ /**
+ * GNSS Measurements are successfully being tracked, it will receive updates once they are
+ * available.
+ */
+ public static final int STATUS_READY = 1;
+
+ /**
+ * GPS provider or Location is disabled, updates will not be received until they are
+ * enabled.
+ */
+ public static final int STATUS_LOCATION_DISABLED = 2;
/**
* Reports the latest collected GNSS Measurements.
@@ -80,6 +89,10 @@
public void onStatusChanged(@GnssMeasurementsStatus int status) {}
}
+ /**
+ * @hide
+ */
+ @TestApi
public GnssMeasurementsEvent(GnssClock clock, GnssMeasurement[] measurements) {
if (clock == null) {
throw new InvalidParameterException("Parameter 'clock' must not be null.");
@@ -94,6 +107,10 @@
mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
}
+ /**
+ * Gets the GNSS receiver clock information associated with the measurements for the current
+ * event.
+ */
@NonNull
public GnssClock getClock() {
return mClock;
diff --git a/location/java/android/location/GnssNavigationMessage.aidl b/location/java/android/location/GnssNavigationMessage.aidl
new file mode 100644
index 0000000..1cdd510
--- /dev/null
+++ b/location/java/android/location/GnssNavigationMessage.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.location;
+
+parcelable GnssNavigationMessage;
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index a5eace8..aa26111 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -34,7 +34,7 @@
private static final byte[] EMPTY_ARRAY = new byte[0];
/**
- * The type of the GPS Clock.
+ * The type of the GNSS Navigation Message
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -81,6 +81,51 @@
*/
public static final int STATUS_PARITY_REBUILT = (1<<1);
+ /**
+ * Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
+ *
+ * <p>You can implement this interface and call
+ * {@link LocationManager#registerGnssNavigationMessageCallback}.
+ */
+ public static abstract class Callback {
+ /**
+ * The status of GNSS measurements event.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+ public @interface GnssNavigationMessageStatus {}
+
+ /**
+ * The system does not support tracking of GNSS Navigation Messages.
+ *
+ * This status will not change in the future.
+ */
+ public static final int STATUS_NOT_SUPPORTED = 0;
+
+ /**
+ * GNSS Navigation Messages are successfully being tracked, it will receive updates once
+ * they are available.
+ */
+ public static final int STATUS_READY = 1;
+
+ /**
+ * GNSS provider or Location is disabled, updated will not be received until they are
+ * enabled.
+ */
+ public static final int STATUS_LOCATION_DISABLED = 2;
+
+ /**
+ * Returns the latest collected GNSS Navigation Message.
+ */
+ public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {}
+
+ /**
+ * Returns the latest status of the GNSS Navigation Messages sub-system.
+ */
+ public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
+ }
+
// End enumerations in sync with gps.h
private int mType;
@@ -170,15 +215,16 @@
}
/**
- * Gets the Pseudo-random number.
- * Range: [1, 32].
+ * Gets the satellite ID.
+ *
+ * <p>Range varies by constellation. See definition at {@code GnssStatus#getSvid(int)}
*/
public int getSvid() {
return mSvid;
}
/**
- * Sets the Pseud-random number.
+ * Sets the satellite ID.
* @hide
*/
@TestApi
@@ -187,10 +233,25 @@
}
/**
- * Gets the Message Identifier.
- * It provides an index so the complete Navigation Message can be assembled. i.e. for L1 C/A
- * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message.
- * Subframe 1, 2, 3 does not contain a 'frame id' and this might be reported as -1.
+ * Gets the Message identifier.
+ *
+ * <p>This provides an index to help with complete Navigation Message assembly. Similar
+ * identifiers within the data bits themselves often supplement this information, in ways even
+ * more specific to each message type; see the relevant satellite constellation ICDs for
+ * details.
+ *
+ * <ul>
+ * <li> For GPS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+ * navigation message, in the range of 1-25 (Subframe 1, 2, 3 does not contain a 'frame id' and
+ * this value can be set to -1.)</li>
+ * <li> For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.</li>
+ * <li> For BeiDou D1, this refers to the frame number in the range of 1-24</li>
+ * <li> For Beidou D2, this refers to the frame number, in the range of 1-120</li>
+ * <li> For Galileo F/NAV nominal frame structure, this refers to the subframe number, in the
+ * range of 1-12</li>
+ * <li> For Galileo I/NAV nominal frame structure, this refers to the subframe number in the
+ * range of 1-24</li>
+ * </ul>
*/
public int getMessageId() {
return mMessageId;
@@ -206,10 +267,18 @@
}
/**
- * Gets the Sub-message Identifier.
- * If required by {@link #getType()}, this value contains a sub-index within the current message
- * (or frame) that is being transmitted. i.e. for L1 C/A the sub-message identifier corresponds
- * to the sub-frame Id of the navigation message.
+ * Gets the sub-message identifier, relevant to the {@link #getType()} of the message.
+ *
+ * <ul>
+ * <li> For GPS L1 C/A, BeiDou D1 & BeiDou D2, the submessage id corresponds to the subframe
+ * number of the navigation message, in the range of 1-5.</li>
+ * <li>For Glonass L1 C/A, this refers to the String number, in the range from 1-15</li>
+ * <li>For Galileo F/NAV, this refers to the page type in the range 1-6</li>
+ * <li>For Galileo I/NAV, this refers to the word type in the range 1-10+</li>
+ * <li>For Galileo in particular, the type information embedded within the data bits may be even
+ * more useful in interpretation, than the nominal page and word types provided in this
+ * field.</li>
+ * </ul>
*/
public int getSubmessageId() {
return mSubmessageId;
@@ -225,8 +294,25 @@
}
/**
- * Gets the data associated with the Navigation Message.
- * The bytes (or words) specified using big endian format (MSB first).
+ * Gets the data of the reported GPS message.
+ *
+ * <p>The bytes (or words) specified using big endian format (MSB first).
+ *
+ * <ul>
+ * <li>For GPS L1 C/A, Beidou D1 & Beidou D2, each subframe contains 10 30-bit words. Each
+ * word (30 bits) should be fit into the last 30 bits in a 4-byte word (skip B31 and B32), with
+ * MSB first, for a total of 40 bytes, covering a time period of 6, 6, and 0.6 seconds,
+ * respectively.</li>
+ * <li>For Glonass L1 C/A, each string contains 85 data bits, including the checksum. These
+ * bits should be fit into 11 bytes, with MSB first (skip B86-B88), covering a time period of 2
+ * seconds.</li>
+ * <li>For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols excluded). Each
+ * word should be fit into 30-bytes, with MSB first (skip B239, B240), covering a time period of
+ * 10 seconds.</li>
+ * <li>For Galileo I/NAV, each page contains 2 page parts, even and odd, with a total of 2x114 =
+ * 228 bits, (sync & tail excluded) that should be fit into 29 bytes, with MSB first (skip
+ * B229-B232).</li>
+ * </ul>
*/
@NonNull
public byte[] getData() {
diff --git a/location/java/android/location/GnssNavigationMessageCallbackTransport.java b/location/java/android/location/GnssNavigationMessageCallbackTransport.java
index 4204b99..1eafd02 100644
--- a/location/java/android/location/GnssNavigationMessageCallbackTransport.java
+++ b/location/java/android/location/GnssNavigationMessageCallbackTransport.java
@@ -20,12 +20,12 @@
import android.os.RemoteException;
/**
- * A handler class to manage transport callback for {@link GnssNavigationMessageEvent.Callback}.
+ * A handler class to manage transport callback for {@link GnssNavigationMessage.Callback}.
*
* @hide
*/
class GnssNavigationMessageCallbackTransport
- extends LocalListenerHelper<GnssNavigationMessageEvent.Callback> {
+ extends LocalListenerHelper<GnssNavigationMessage.Callback> {
private final ILocationManager mLocationManager;
private final IGnssNavigationMessageListener mListenerTransport = new ListenerTransport();
@@ -51,11 +51,11 @@
private class ListenerTransport extends IGnssNavigationMessageListener.Stub {
@Override
- public void onGnssNavigationMessageReceived(final GnssNavigationMessageEvent event) {
- ListenerOperation<GnssNavigationMessageEvent.Callback> operation =
- new ListenerOperation<GnssNavigationMessageEvent.Callback>() {
+ public void onGnssNavigationMessageReceived(final GnssNavigationMessage event) {
+ ListenerOperation<GnssNavigationMessage.Callback> operation =
+ new ListenerOperation<GnssNavigationMessage.Callback>() {
@Override
- public void execute(GnssNavigationMessageEvent.Callback callback)
+ public void execute(GnssNavigationMessage.Callback callback)
throws RemoteException {
callback.onGnssNavigationMessageReceived(event);
}
@@ -65,10 +65,10 @@
@Override
public void onStatusChanged(final int status) {
- ListenerOperation<GnssNavigationMessageEvent.Callback> operation =
- new ListenerOperation<GnssNavigationMessageEvent.Callback>() {
+ ListenerOperation<GnssNavigationMessage.Callback> operation =
+ new ListenerOperation<GnssNavigationMessage.Callback>() {
@Override
- public void execute(GnssNavigationMessageEvent.Callback callback)
+ public void execute(GnssNavigationMessage.Callback callback)
throws RemoteException {
callback.onStatusChanged(status);
}
diff --git a/location/java/android/location/GnssNavigationMessageEvent.java b/location/java/android/location/GnssNavigationMessageEvent.java
index 992dfc3..f7e5665 100644
--- a/location/java/android/location/GnssNavigationMessageEvent.java
+++ b/location/java/android/location/GnssNavigationMessageEvent.java
@@ -28,10 +28,11 @@
/**
* A class implementing a container for data associated with a navigation message event.
* Events are delivered to registered instances of {@link Callback}.
+ * @removed
*/
public final class GnssNavigationMessageEvent implements Parcelable {
/**
- * The status of GPS measurements event.
+ * The status of GNSS measurements event.
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -39,38 +40,40 @@
public @interface GnssNavigationMessageStatus {}
/**
- * The system does not support tracking of GPS Navigation Messages. This status will not change
- * in the future.
+ * The system does not support tracking of GNSS Navigation Messages.
+ *
+ * This status will not change in the future.
*/
public static final int STATUS_NOT_SUPPORTED = 0;
/**
- * GPS Navigation Messages are successfully being tracked, it will receive updates once they are
- * available.
+ * GNSS Navigation Messages are successfully being tracked, it will receive updates once they
+ * are available.
*/
public static final int STATUS_READY = 1;
/**
- * GPS provider or Location is disabled, updated will not be received until they are enabled.
+ * GNSS provider or Location is disabled, updated will not be received until they are enabled.
*/
public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
private final GnssNavigationMessage mNavigationMessage;
/**
- * Used for receiving GPS satellite Navigation Messages from the GPS engine.
- * You can implement this interface and call
+ * Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
+ *
+ * <p>You can implement this interface and call
* {@link LocationManager#registerGnssNavigationMessageCallback}.
*/
public static abstract class Callback {
/**
- * Returns the latest collected GPS Navigation Message.
+ * Returns the latest collected GNSS Navigation Message.
*/
public void onGnssNavigationMessageReceived(GnssNavigationMessageEvent event) {}
/**
- * Returns the latest status of the GPS Navigation Messages sub-system.
+ * Returns the latest status of the GNSS Navigation Messages sub-system.
*/
public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
}
diff --git a/location/java/android/location/GnssNmeaListener.java b/location/java/android/location/GnssNmeaListener.java
index 6c9b08a..756ae49 100644
--- a/location/java/android/location/GnssNmeaListener.java
+++ b/location/java/android/location/GnssNmeaListener.java
@@ -23,8 +23,9 @@
* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
* You can implement this interface and call {@link LocationManager#addNmeaListener}
* to receive NMEA data from the GNSS engine.
+* @removed
*/
public interface GnssNmeaListener {
/** Called when an NMEA message is received. */
void onNmeaReceived(long timestamp, String nmea);
-}
\ No newline at end of file
+}
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index d76feec..e834c30 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -23,9 +23,11 @@
/**
* This class represents the current state of the GNSS engine.
- * This class is used in conjunction with the {@link GnssStatusCallback}.
+ * This class is used in conjunction with the {@link GnssStatus.Callback}.
*/
public final class GnssStatus {
+ // these must match the definitions in gps.h
+
/** Unknown constellation type. */
public static final int CONSTELLATION_UNKNOWN = 0;
/** Constellation type constant for GPS. */
@@ -41,16 +43,6 @@
/** Constellation type constant for Galileo. */
public static final int CONSTELLATION_GALILEO = 6;
- /**
- * Constellation type.
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
- CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
- public @interface ConstellationType {}
-
- // these must match the definitions in gps.h
/** @hide */
public static final int GNSS_SV_FLAGS_NONE = 0;
/** @hide */
@@ -67,6 +59,42 @@
/** @hide */
public static final int CONSTELLATION_TYPE_MASK = 0xf;
+ /**
+ * Used for receiving notifications when GNSS events happen.
+ */
+ public static abstract class Callback {
+ /**
+ * Called when GNSS system has started.
+ */
+ public void onStarted() {}
+
+ /**
+ * Called when GNSS system has stopped.
+ */
+ public void onStopped() {}
+
+ /**
+ * Called when the GNSS system has received its first fix since starting.
+ * @param ttffMillis the time from start to first fix in milliseconds.
+ */
+ public void onFirstFix(int ttffMillis) {}
+
+ /**
+ * Called periodically to report GNSS satellite status.
+ * @param status the current status of all satellites.
+ */
+ public void onSatelliteStatusChanged(GnssStatus status) {}
+ }
+
+ /**
+ * Constellation type.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
+ CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
+ public @interface ConstellationType {}
+
/* These package private values are modified by the LocationManager class */
/* package */ int[] mSvidWithFlags;
/* package */ float[] mCn0DbHz;
@@ -83,15 +111,21 @@
mAzimuths = azimuths;
}
+ /** @removed */
+ public int getNumSatellites() {
+ return getSatelliteCount();
+ }
+
/**
* Gets the total number of satellites in satellite list.
*/
- public int getNumSatellites() {
+ public int getSatelliteCount() {
return mSvCount;
}
/**
- * Retrieves the constellation type of the satellite at the specified position.
+ * Retrieves the constellation type of the satellite at the specified index.
+ *
* @param satIndex the index of the satellite in the list.
*/
@ConstellationType
@@ -101,7 +135,30 @@
}
/**
- * Retrieves the pseudo-random number of the satellite at the specified position.
+ * Gets the identification number for the satellite at the specific index.
+ *
+ * <p>This svid is pseudo-random number for most constellations. It is FCN & OSN number for
+ * Glonass.
+ *
+ * <p>The distinction is made by looking at constellation field
+ * {@link #getConstellationType(int)} Expected values are in the range of:
+ *
+ * <ul>
+ * <li>GPS: 1-32</li>
+ * <li>SBAS: 120-151, 183-192</li>
+ * <li>GLONASS:
+ * <ul>
+ * <li>The least significant 8 bits, signed, are the orbital slot number (OSN) in the range
+ * from 1-24, if known, or -127 if unknown</li>
+ * <li>The next least signficant 8 bits, signed, are the frequency channel number (FCN) in the
+ * range from -7 to +6, if known, and -127, if unknown</li>
+ * <li>At least one of the two (FCN & OSN) shall be set to a known value</li>
+ * </ul></li>
+ * <li>QZSS: 193-200</li>
+ * <li>Galileo: 1-36</li>
+ * <li>Beidou: 1-37</li>
+ * </ul>
+ *
* @param satIndex the index of the satellite in the list.
*/
public int getSvid(int satIndex) {
@@ -109,7 +166,9 @@
}
/**
- * Retrieves the signal-noise ration of the satellite at the specified position.
+ * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
+ * in dB-Hz.
+ *
* @param satIndex the index of the satellite in the list.
*/
public float getCn0DbHz(int satIndex) {
@@ -117,7 +176,8 @@
}
/**
- * Retrieves the elevation of the satellite at the specified position.
+ * Retrieves the elevation of the satellite at the specified index.
+ *
* @param satIndex the index of the satellite in the list.
*/
public float getElevationDegrees(int satIndex) {
@@ -125,31 +185,46 @@
}
/**
- * Retrieves the azimuth the satellite at the specified position.
+ * Retrieves the azimuth the satellite at the specified index.
+ *
* @param satIndex the index of the satellite in the list.
*/
public float getAzimuthDegrees(int satIndex) {
return mAzimuths[satIndex];
}
- /**
- * Detects whether the satellite at the specified position has ephemeris data.
- * @param satIndex the index of the satellite in the list.
- */
+ /** @removed */
public boolean hasEphemeris(int satIndex) {
- return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+ return hasEphemerisData(satIndex);
}
/**
- * Detects whether the satellite at the specified position has almanac data.
+ * Reports whether the satellite at the specified index has ephemeris data.
+ *
* @param satIndex the index of the satellite in the list.
*/
+ public boolean hasEphemerisData(int satIndex) {
+ return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+ }
+
+ /** @removed */
public boolean hasAlmanac(int satIndex) {
+ return hasAlmanacData(satIndex);
+ }
+
+ /**
+ * Reports whether the satellite at the specified index has almanac data.
+ *
+ * @param satIndex the index of the satellite in the list.
+ */
+ public boolean hasAlmanacData(int satIndex) {
return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
}
/**
- * Detects whether the satellite at the specified position is used in fix.
+ * Reports whether the satellite at the specified index was used in the calculation of the most
+ * recent position fix.
+ *
* @param satIndex the index of the satellite in the list.
*/
public boolean usedInFix(int satIndex) {
diff --git a/location/java/android/location/GnssStatusCallback.java b/location/java/android/location/GnssStatusCallback.java
index 0d2955a..bf295ef 100644
--- a/location/java/android/location/GnssStatusCallback.java
+++ b/location/java/android/location/GnssStatusCallback.java
@@ -18,6 +18,7 @@
/**
* Used for receiving notifications when GNSS events happen.
+ * @removed
*/
public abstract class GnssStatusCallback {
/**
diff --git a/location/java/android/location/GpsSatellite.java b/location/java/android/location/GpsSatellite.java
index 820f5746..788d01e 100644
--- a/location/java/android/location/GpsSatellite.java
+++ b/location/java/android/location/GpsSatellite.java
@@ -18,8 +18,12 @@
/**
* This class represents the current state of a GPS satellite.
+ *
* This class is used in conjunction with the {@link GpsStatus} class.
+ *
+ * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
*/
+@Deprecated
public final class GpsSatellite {
/* These package private values are modified by the GpsStatus class */
boolean mValid;
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index bc518f9..038247b 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -24,8 +24,12 @@
/**
* This class represents the current state of the GPS engine.
- * This class is used in conjunction with the {@link Listener} interface.
+ *
+ * <p>This class is used in conjunction with the {@link Listener} interface.
+ *
+ * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
*/
+@Deprecated
public final class GpsStatus {
private static final int NUM_SATELLITES = 255;
@@ -102,7 +106,9 @@
/**
* Used for receiving notifications when GPS status has changed.
+ * @deprecated use {@link GnssStatus.Callback} instead.
*/
+ @Deprecated
public interface Listener {
/**
* Called to report changes in the GPS status.
@@ -130,7 +136,9 @@
* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
* You can implement this interface and call {@link LocationManager#addNmeaListener}
* to receive NMEA data from the GPS engine.
+ * @deprecated use {@link OnNmeaMessageListener} instead.
*/
+ @Deprecated
public interface NmeaListener {
void onNmeaReceived(long timestamp, String nmea);
}
diff --git a/location/java/android/location/IGnssNavigationMessageListener.aidl b/location/java/android/location/IGnssNavigationMessageListener.aidl
index de6129c..3e49b5b 100644
--- a/location/java/android/location/IGnssNavigationMessageListener.aidl
+++ b/location/java/android/location/IGnssNavigationMessageListener.aidl
@@ -16,12 +16,12 @@
package android.location;
-import android.location.GnssNavigationMessageEvent;
+import android.location.GnssNavigationMessage;
/**
* {@hide}
*/
oneway interface IGnssNavigationMessageListener {
- void onGnssNavigationMessageReceived(in GnssNavigationMessageEvent event);
+ void onGnssNavigationMessageReceived(in GnssNavigationMessage event);
void onStatusChanged(in int status);
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 28db099..b246360 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -70,10 +70,16 @@
new HashMap<>();
private final HashMap<GpsStatus.NmeaListener, GnssStatusListenerTransport> mGpsNmeaListeners =
new HashMap<>();
- private final HashMap<GnssStatusCallback, GnssStatusListenerTransport> mGnssStatusListeners =
+ private final HashMap<GnssStatusCallback, GnssStatusListenerTransport>
+ mOldGnssStatusListeners = new HashMap<>();
+ private final HashMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
new HashMap<>();
- private final HashMap<GnssNmeaListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+ private final HashMap<GnssNmeaListener, GnssStatusListenerTransport> mOldGnssNmeaListeners =
new HashMap<>();
+ private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+ new HashMap<>();
+ private final HashMap<GnssNavigationMessageEvent.Callback, GnssNavigationMessage.Callback>
+ mNavigationMessageBridge = new HashMap<>();
private GnssStatus mGnssStatus;
private int mTimeToFirstFix;
@@ -1392,8 +1398,10 @@
private final GpsStatus.Listener mGpsListener;
private final GpsStatus.NmeaListener mGpsNmeaListener;
- private final GnssStatusCallback mGnssCallback;
- private final GnssNmeaListener mGnssNmeaListener;
+ private final GnssStatusCallback mOldGnssCallback;
+ private final GnssStatus.Callback mGnssCallback;
+ private final GnssNmeaListener mOldGnssNmeaListener;
+ private final OnNmeaMessageListener mGnssNmeaListener;
private class GnssHandler extends Handler {
public GnssHandler(Handler handler) {
@@ -1408,7 +1416,7 @@
int length = mNmeaBuffer.size();
for (int i = 0; i < length; i++) {
Nmea nmea = mNmeaBuffer.get(i);
- mGnssNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea);
+ mGnssNmeaListener.onNmeaMessage(nmea.mNmea, nmea.mTimestamp);
}
mNmeaBuffer.clear();
}
@@ -1456,7 +1464,8 @@
mGnssHandler = new GnssHandler(handler);
mGpsNmeaListener = null;
mNmeaBuffer = null;
- mGnssCallback = new GnssStatusCallback() {
+ mOldGnssCallback = null;
+ mGnssCallback = new GnssStatus.Callback() {
@Override
public void onStarted() {
mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
@@ -1477,6 +1486,7 @@
mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
}
};
+ mOldGnssNmeaListener = null;
mGnssNmeaListener = null;
}
@@ -1489,10 +1499,12 @@
mGnssHandler = new GnssHandler(handler);
mGpsNmeaListener = listener;
mNmeaBuffer = new ArrayList<Nmea>();
+ mOldGnssCallback = null;
mGnssCallback = null;
- mGnssNmeaListener = new GnssNmeaListener() {
+ mOldGnssNmeaListener = null;
+ mGnssNmeaListener = new OnNmeaMessageListener() {
@Override
- public void onNmeaReceived(long timestamp, String nmea) {
+ public void onNmeaMessage(String nmea, long timestamp) {
mGpsNmeaListener.onNmeaReceived(timestamp, nmea);
}
};
@@ -1503,8 +1515,45 @@
}
GnssStatusListenerTransport(GnssStatusCallback callback, Handler handler) {
+ mOldGnssCallback = callback;
+ mGnssCallback = new GnssStatus.Callback() {
+ @Override
+ public void onStarted() {
+ mOldGnssCallback.onStarted();
+ }
+
+ @Override
+ public void onStopped() {
+ mOldGnssCallback.onStopped();
+ }
+
+ @Override
+ public void onFirstFix(int ttff) {
+ mOldGnssCallback.onFirstFix(ttff);
+ }
+
+ @Override
+ public void onSatelliteStatusChanged(GnssStatus status) {
+ mOldGnssCallback.onSatelliteStatusChanged(status);
+ }
+ };
+ mGnssHandler = new GnssHandler(handler);
+ mOldGnssNmeaListener = null;
+ mGnssNmeaListener = null;
+ mNmeaBuffer = null;
+ mGpsListener = null;
+ mGpsNmeaListener = null;
+ }
+
+ GnssStatusListenerTransport(GnssStatus.Callback callback) {
+ this(callback, null);
+ }
+
+ GnssStatusListenerTransport(GnssStatus.Callback callback, Handler handler) {
+ mOldGnssCallback = null;
mGnssCallback = callback;
mGnssHandler = new GnssHandler(handler);
+ mOldGnssNmeaListener = null;
mGnssNmeaListener = null;
mNmeaBuffer = null;
mGpsListener = null;
@@ -1517,7 +1566,29 @@
GnssStatusListenerTransport(GnssNmeaListener listener, Handler handler) {
mGnssCallback = null;
+ mOldGnssCallback = null;
mGnssHandler = new GnssHandler(handler);
+ mOldGnssNmeaListener = listener;
+ mGnssNmeaListener = new OnNmeaMessageListener() {
+ @Override
+ public void onNmeaMessage(String message, long timestamp) {
+ mOldGnssNmeaListener.onNmeaReceived(timestamp, message);
+ }
+ };
+ mGpsListener = null;
+ mGpsNmeaListener = null;
+ mNmeaBuffer = new ArrayList<Nmea>();
+ }
+
+ GnssStatusListenerTransport(OnNmeaMessageListener listener) {
+ this(listener, null);
+ }
+
+ GnssStatusListenerTransport(OnNmeaMessageListener listener, Handler handler) {
+ mOldGnssCallback = null;
+ mGnssCallback = null;
+ mGnssHandler = new GnssHandler(handler);
+ mOldGnssNmeaListener = null;
mGnssNmeaListener = listener;
mGpsListener = null;
mGpsNmeaListener = null;
@@ -1589,7 +1660,7 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
- * @deprecated use {@link #registerGnssStatusCallback(GnssStatusCallback)} instead.
+ * @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead.
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1617,6 +1688,7 @@
* Removes a GPS status listener.
*
* @param listener GPS status listener object to remove
+ * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead.
*/
@Deprecated
public void removeGpsStatusListener(GpsStatus.Listener listener) {
@@ -1630,7 +1702,6 @@
}
}
-
/**
* Registers a GNSS status listener.
*
@@ -1639,6 +1710,7 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ * @removed
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssStatusCallback(GnssStatusCallback callback) {
@@ -1654,10 +1726,73 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ * @removed
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssStatusCallback(GnssStatusCallback callback, Handler handler) {
boolean result;
+ if (mOldGnssStatusListeners.get(callback) != null) {
+ // listener is already registered
+ return true;
+ }
+ try {
+ GnssStatusListenerTransport transport =
+ new GnssStatusListenerTransport(callback, handler);
+ result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
+ if (result) {
+ mOldGnssStatusListeners.put(callback, transport);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ return result;
+ }
+
+ /**
+ * Removes a GNSS status listener.
+ *
+ * @param callback GNSS status listener object to remove
+ * @removed
+ */
+ public void unregisterGnssStatusCallback(GnssStatusCallback callback) {
+ try {
+ GnssStatusListenerTransport transport = mOldGnssStatusListeners.remove(callback);
+ if (transport != null) {
+ mService.unregisterGnssStatusCallback(transport);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers a GNSS status listener.
+ *
+ * @param callback GNSS status listener object to register
+ *
+ * @return true if the listener was successfully added
+ *
+ * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ */
+ @RequiresPermission(ACCESS_FINE_LOCATION)
+ public boolean registerGnssStatusCallback(GnssStatus.Callback callback) {
+ return registerGnssStatusCallback(callback, null);
+ }
+
+ /**
+ * Registers a GNSS status listener.
+ *
+ * @param callback GNSS status listener object to register
+ * @param handler the handler that the callback runs on.
+ *
+ * @return true if the listener was successfully added
+ *
+ * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ */
+ @RequiresPermission(ACCESS_FINE_LOCATION)
+ public boolean registerGnssStatusCallback(GnssStatus.Callback callback, Handler handler) {
+ boolean result;
if (mGnssStatusListeners.get(callback) != null) {
// listener is already registered
return true;
@@ -1681,7 +1816,7 @@
*
* @param callback GNSS status listener object to remove
*/
- public void unregisterGnssStatusCallback(GnssStatusCallback callback) {
+ public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
try {
GnssStatusListenerTransport transport = mGnssStatusListeners.remove(callback);
if (transport != null) {
@@ -1700,7 +1835,7 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
- * @deprecated use {@link #addNmeaListener(GnssNmeaListener)} instead.
+ * @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead.
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1728,6 +1863,7 @@
* Removes an NMEA listener.
*
* @param listener a {@link GpsStatus.NmeaListener} object to remove
+ * @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
*/
@Deprecated
public void removeNmeaListener(GpsStatus.NmeaListener listener) {
@@ -1749,6 +1885,7 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ * @removed
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addNmeaListener(GnssNmeaListener listener) {
@@ -1764,6 +1901,7 @@
* @return true if the listener was successfully added
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ * @removed
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addNmeaListener(GnssNmeaListener listener, Handler handler) {
@@ -1778,6 +1916,69 @@
new GnssStatusListenerTransport(listener, handler);
result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
if (result) {
+ mOldGnssNmeaListeners.put(listener, transport);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ return result;
+ }
+
+ /**
+ * Removes an NMEA listener.
+ *
+ * @param listener a {@link GnssNmeaListener} object to remove
+ * @removed
+ */
+ public void removeNmeaListener(GnssNmeaListener listener) {
+ try {
+ GnssStatusListenerTransport transport = mOldGnssNmeaListeners.remove(listener);
+ if (transport != null) {
+ mService.unregisterGnssStatusCallback(transport);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Adds an NMEA listener.
+ *
+ * @param listener a {@link OnNmeaMessageListener} object to register
+ *
+ * @return true if the listener was successfully added
+ *
+ * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ */
+ @RequiresPermission(ACCESS_FINE_LOCATION)
+ public boolean addNmeaListener(OnNmeaMessageListener listener) {
+ return addNmeaListener(listener, null);
+ }
+
+ /**
+ * Adds an NMEA listener.
+ *
+ * @param listener a {@link OnNmeaMessageListener} object to register
+ * @param handler the handler that the listener runs on.
+ *
+ * @return true if the listener was successfully added
+ *
+ * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ */
+ @RequiresPermission(ACCESS_FINE_LOCATION)
+ public boolean addNmeaListener(OnNmeaMessageListener listener, Handler handler) {
+ boolean result;
+
+ if (mGpsNmeaListeners.get(listener) != null) {
+ // listener is already registered
+ return true;
+ }
+ try {
+ GnssStatusListenerTransport transport =
+ new GnssStatusListenerTransport(listener, handler);
+ result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
+ if (result) {
mGnssNmeaListeners.put(listener, transport);
}
} catch (RemoteException e) {
@@ -1790,9 +1991,9 @@
/**
* Removes an NMEA listener.
*
- * @param listener a {@link GnssNmeaListener} object to remove
+ * @param listener a {@link OnNmeaMessageListener} object to remove
*/
- public void removeNmeaListener(GnssNmeaListener listener) {
+ public void removeNmeaListener(OnNmeaMessageListener listener) {
try {
GnssStatusListenerTransport transport = mGnssNmeaListeners.remove(listener);
if (transport != null) {
@@ -1843,7 +2044,8 @@
* No-op method to keep backward-compatibility.
* Don't use it. Use {@link #unregisterGnssMeasurementsCallback} instead.
* @hide
- * @deprecated
+ * @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)}
+ * instead.
*/
@Deprecated
@SystemApi
@@ -1872,10 +2074,23 @@
}
/**
- * Registers a GPS Navigation Message callback.
+ * No-op method to keep backward-compatibility.
+ * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead.
+ * @hide
+ * @deprecated use {@link #unregisterGnssNavigationMessageCallback(GnssMeasurements.Callback)}
+ * instead
+ */
+ @Deprecated
+ @SystemApi
+ public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
+ }
+
+ /**
+ * Registers a GNSS Navigation Message callback.
*
* @param callback a {@link GnssNavigationMessageEvent.Callback} object to register.
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
+ * @removed
*/
public boolean registerGnssNavigationMessageCallback(
GnssNavigationMessageEvent.Callback callback) {
@@ -1883,40 +2098,80 @@
}
/**
- * Registers a GPS Navigation Message callback.
+ * Registers a GNSS Navigation Message callback.
*
* @param callback a {@link GnssNavigationMessageEvent.Callback} object to register.
* @param handler the handler that the callback runs on.
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
+ * @removed
+ */
+ @RequiresPermission(ACCESS_FINE_LOCATION)
+ public boolean registerGnssNavigationMessageCallback(
+ final GnssNavigationMessageEvent.Callback callback, Handler handler) {
+ GnssNavigationMessage.Callback bridge = new GnssNavigationMessage.Callback() {
+ @Override
+ public void onGnssNavigationMessageReceived(GnssNavigationMessage message) {
+ GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(message);
+ callback.onGnssNavigationMessageReceived(event);
+ }
+
+ @Override
+ public void onStatusChanged(int status) {
+ callback.onStatusChanged(status);
+ }
+ };
+ mNavigationMessageBridge.put(callback, bridge);
+ return mGnssNavigationMessageCallbackTransport.add(bridge, handler);
+ }
+
+ /**
+ * Unregisters a GNSS Navigation Message callback.
+ *
+ * @param callback a {@link GnssNavigationMessageEvent.Callback} object to remove.
+ * @removed
+ */
+ public void unregisterGnssNavigationMessageCallback(
+ GnssNavigationMessageEvent.Callback callback) {
+ mGnssNavigationMessageCallbackTransport.remove(
+ mNavigationMessageBridge.remove(
+ callback));
+ }
+
+ /**
+ * Registers a GNSS Navigation Message callback.
+ *
+ * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+ * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+ */
+ public boolean registerGnssNavigationMessageCallback(
+ GnssNavigationMessage.Callback callback) {
+ return registerGnssNavigationMessageCallback(callback, null);
+ }
+
+ /**
+ * Registers a GNSS Navigation Message callback.
+ *
+ * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+ * @param handler the handler that the callback runs on.
+ * @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssNavigationMessageCallback(
- GnssNavigationMessageEvent.Callback callback, Handler handler) {
+ GnssNavigationMessage.Callback callback, Handler handler) {
return mGnssNavigationMessageCallbackTransport.add(callback, handler);
}
/**
- * Unregisters a GPS Navigation Message callback.
+ * Unregisters a GNSS Navigation Message callback.
*
- * @param callback a {@link GnssNavigationMessageEvent.Callback} object to remove.
+ * @param callback a {@link GnssNavigationMessage.Callback} object to remove.
*/
public void unregisterGnssNavigationMessageCallback(
- GnssNavigationMessageEvent.Callback callback) {
+ GnssNavigationMessage.Callback callback) {
mGnssNavigationMessageCallbackTransport.remove(callback);
}
/**
- * No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead.
- * @hide
- * @deprecated
- */
- @Deprecated
- @SystemApi
- public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
- }
-
- /**
* Retrieves information about the current status of the GPS engine.
* This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged}
* callback to ensure that the data is copied atomically.
diff --git a/location/java/android/location/OnNmeaMessageListener.java b/location/java/android/location/OnNmeaMessageListener.java
new file mode 100644
index 0000000..ccf6ce8
--- /dev/null
+++ b/location/java/android/location/OnNmeaMessageListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.location;
+
+/**
+* Used for receiving NMEA sentences from the GNSS.
+* NMEA 0183 is a standard for communicating with marine electronic devices
+* and is a common method for receiving data from a GNSS, typically over a serial port.
+* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
+* You can implement this interface and call {@link LocationManager#addNmeaListener}
+* to receive NMEA data from the GNSS engine.
+*/
+public interface OnNmeaMessageListener {
+ /**
+ * Called when an NMEA message is received.
+ * @param message NMEA message
+ * @param timestamp milliseconds since January 1, 1970.
+ */
+ void onNmeaMessage(String message, long timestamp);
+}
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 3d7e744..72f5742 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -697,7 +697,8 @@
/**
* Reads Exif tags from the specified image file descriptor. Attribute mutation is supported
- * for writable and seekable file descriptors only.
+ * for writable and seekable file descriptors only. This constructor will not rewind the offset
+ * of the given file descriptor. Developers should close the file descriptor after use.
*/
public ExifInterface(FileDescriptor fileDescriptor) throws IOException {
if (fileDescriptor == null) {
@@ -730,7 +731,8 @@
/**
* Reads Exif tags from the specified image input stream. Attribute mutation is not supported
- * for input streams.
+ * for input streams. The given input stream will proceed its current position. Developers
+ * should close the input stream after use.
*/
public ExifInterface(InputStream inputStream) throws IOException {
if (inputStream == null) {
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index a5ff29f..2613376 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -158,7 +158,7 @@
* <p>The application may supply the URI for a TV program for filling in program specific data
* fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
* A non-null {@code programHint} implies the started recording should be of that specific
- * program, whereas null {@code programHint} does not impose such a requirement and the
+ * program, whereas null {@code programUri} does not impose such a requirement and the
* recording can span across multiple TV programs. In either case, the application must call
* {@link TvRecordingClient#stopRecording()} to stop the recording.
*
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index 3814630..61fbfb9 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -23,12 +23,14 @@
public class MtpServer implements Runnable {
private long mNativeContext; // accessed by native methods
+ private final MtpDatabase mDatabase;
static {
System.loadLibrary("media_jni");
}
public MtpServer(MtpDatabase database, boolean usePtp) {
+ mDatabase = database;
native_setup(database, usePtp);
database.setServer(this);
}
@@ -42,6 +44,7 @@
public void run() {
native_run();
native_cleanup();
+ mDatabase.close();
}
public void sendObjectAdded(int handle) {
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 537b56d..d07942b 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -155,4 +155,8 @@
return 0;
}
+String8 JMediaDataSource::toString() {
+ return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid());
+}
+
} // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
index 34624eb..378baf4 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -46,6 +46,7 @@
virtual status_t getSize(off64_t* size);
virtual void close();
virtual uint32_t getFlags();
+ virtual String8 toString();
private:
// Protect all member variables with mLock because this object will be
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 1a7c620..27c4bbc 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Lêers"</string>
<string name="downloads_label" msgid="959113951084633612">"Aflaaie"</string>
<string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vee \"<xliff:g id="NAME">%1$s</xliff:g>\" uit?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vee vouer \"<xliff:g id="NAME">%1$s</xliff:g>\" en sy inhoud uit?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index ca43dab..0e1a34d 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ሰነዶች"</string>
- <string name="files_label" msgid="6051402950202690279">"ፋይሎች"</string>
<string name="downloads_label" msgid="959113951084633612">"የወረዱ"</string>
<string name="title_open" msgid="4353228937663917801">"ክፈት ከ"</string>
<string name="title_save" msgid="2433679664882857999">"አስቀምጥ ወደ"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"«<xliff:g id="NAME">%1$s</xliff:g>» ይሰረዝ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"አቃፊ «<xliff:g id="NAME">%1$s</xliff:g>» እና ይዘቶቹ ይሰረዙ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index e6fac50..264a275 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"مستندات"</string>
- <string name="files_label" msgid="6051402950202690279">"الملفات"</string>
<string name="downloads_label" msgid="959113951084633612">"التنزيلات"</string>
<string name="title_open" msgid="4353228937663917801">"فتح من"</string>
<string name="title_save" msgid="2433679664882857999">"حفظ في"</string>
@@ -152,6 +151,14 @@
<item quantity="other">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">تم تحديد <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
+ <item quantity="two">عنصران (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> عناصر</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصرًا</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
+ <item quantity="one">عنصر واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"هل تريد حذف \"<xliff:g id="NAME">%1$s</xliff:g>\"؟"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"هل تريد حذف المجلد \"<xliff:g id="NAME">%1$s</xliff:g>\" ومحتوياته؟"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 75a0686..e1d6050 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Sənədlər"</string>
- <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="downloads_label" msgid="959113951084633612">"Endirmələr"</string>
<string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
<string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçilib</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçilib</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" silinsin?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" qovluğu və onun məzmunu silinsin?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index 34c08bd..83f2763 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori sa"</string>
<string name="title_save" msgid="2433679664882857999">"Sačuvaj u"</string>
@@ -128,6 +127,11 @@
<item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
<item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li da izbrišete „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li da izbrišete direktorijum „<xliff:g id="NAME">%1$s</xliff:g>“ i njegov sadržaj?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-be-rBY/strings.xml b/packages/DocumentsUI/res/values-be-rBY/strings.xml
index 8493c477..1c06cd1 100644
--- a/packages/DocumentsUI/res/values-be-rBY/strings.xml
+++ b/packages/DocumentsUI/res/values-be-rBY/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Дакументы"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлы"</string>
<string name="downloads_label" msgid="959113951084633612">"Спампоўкі"</string>
<string name="title_open" msgid="4353228937663917801">"Адкрыць з"</string>
<string name="title_save" msgid="2433679664882857999">"Захаваць у"</string>
@@ -125,7 +124,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_request_primary_volume" msgid="6635562535713428688">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Даць праграме <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>
@@ -136,6 +135,12 @@
<item quantity="many">Выбрана <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Выбрана <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> элемент</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> элементы</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> элементаў</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> элемента</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Выдаліць \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Выдаліць папку \"<xliff:g id="NAME">%1$s</xliff:g>\" і яе змесціва?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index 1914bf5..16922c8 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлове"</string>
<string name="downloads_label" msgid="959113951084633612">"Изтегляния"</string>
<string name="title_open" msgid="4353228937663917801">"Отваряне от"</string>
<string name="title_save" msgid="2433679664882857999">"Запазване във:"</string>
@@ -120,6 +119,10 @@
<item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> елемента</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> елемент</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Искате ли да изтриете „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Искате ли да изтриете папката „<xliff:g id="NAME">%1$s</xliff:g>“ и съдържанието в нея?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index d931c2b..4be7dc80 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"দস্তাবেজগুলি"</string>
- <string name="files_label" msgid="6051402950202690279">"ফাইলগুলি"</string>
<string name="downloads_label" msgid="959113951084633612">"ডাউনলোডগুলি"</string>
<string name="title_open" msgid="4353228937663917801">"এখান থেকে খুলুন"</string>
<string name="title_save" msgid="2433679664882857999">"এতে সংরক্ষণ করুন"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" মুছবেন?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ফোল্ডার এবং এটির সামগ্রীগুলিকে মুছবেন?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
index 47ff436..aae7986 100644
--- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Fajlovi"</string>
<string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
<string name="title_save" msgid="2433679664882857999">"Sačuvaj u"</string>
@@ -128,6 +127,11 @@
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li izbrisati \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li izbrisati folder \"<xliff:g id="NAME">%1$s</xliff:g>\" i njegov sadržaj?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 09af97d..85b42076 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Fitxers"</string>
<string name="downloads_label" msgid="959113951084633612">"Baixades"</string>
<string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
<string name="title_save" msgid="2433679664882857999">"Desa a"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements seleccionats</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element seleccionat</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vols suprimir el fitxer <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vols suprimir la carpeta <xliff:g id="NAME">%1$s</xliff:g> i el seu contingut?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index cba2e0e..5ab5a41 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Soubory"</string>
<string name="downloads_label" msgid="959113951084633612">"Stahování"</string>
<string name="title_open" msgid="4353228937663917801">"Otevřít"</string>
<string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
@@ -136,6 +135,12 @@
<item quantity="other">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položek</item>
<item quantity="one">Vybrána <xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> položek</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Smazat soubor <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Smazat složku <xliff:g id="NAME">%1$s</xliff:g> a její obsah?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index f048e34..840dc00 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Åbn fra"</string>
<string name="title_save" msgid="2433679664882857999">"Gem i"</string>
@@ -120,6 +119,10 @@
<item quantity="one">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementer</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vil du slette \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vil du slette mappen \"<xliff:g id="NAME">%1$s</xliff:g>\" og dens indhold?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index a6eae70..eb81827 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Dateien"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Öffnen von"</string>
<string name="title_save" msgid="2433679664882857999">"Speichern unter"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Einträge</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Eintrag</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" löschen?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ordner \"<xliff:g id="NAME">%1$s</xliff:g>\" und dessen Inhalte löschen?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 7dc2067..ad681bd 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Έγγραφα"</string>
- <string name="files_label" msgid="6051402950202690279">"Αρχεία"</string>
<string name="downloads_label" msgid="959113951084633612">"Λήψεις"</string>
<string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
<string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> επιλεγμένα</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> επιλεγμένο</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> στοιχεία</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> στοιχείο</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Να διαγραφεί το αρχείο \"<xliff:g id="NAME">%1$s</xliff:g>\";"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Να διαγραφεί ο φάκελος \"<xliff:g id="NAME">%1$s</xliff:g>\" και τα περιεχόμενά του;"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index 8524de5..406d2ec 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index 8524de5..406d2ec 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index 8524de5..406d2ec 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 87641a7..bb471f7 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"¿Deseas borrar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"¿Deseas borrar la carpeta \"<xliff:g id="NAME">%1$s</xliff:g>\" y su contenido?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 9054561..2373e60 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"¿Eliminar <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"¿Eliminar la carpeta <xliff:g id="NAME">%1$s</xliff:g> y su contenido?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 4bb2a9b..6bc3942 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumendid"</string>
- <string name="files_label" msgid="6051402950202690279">"Failid"</string>
<string name="downloads_label" msgid="959113951084633612">"Allalaadimised"</string>
<string name="title_open" msgid="4353228937663917801">"Ava:"</string>
<string name="title_save" msgid="2433679664882857999">"Salvesta:"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> on valitud</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> on valitud</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> üksust</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> üksus</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Kas kustutada fail „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Kas kustutada kaust „<xliff:g id="NAME">%1$s</xliff:g>” ja selle sisu?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index d2bf89d..da11c5c 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentuak"</string>
- <string name="files_label" msgid="6051402950202690279">"Fitxategiak"</string>
<string name="downloads_label" msgid="959113951084633612">"Deskargak"</string>
<string name="title_open" msgid="4353228937663917801">"Ireki hemendik"</string>
<string name="title_save" msgid="2433679664882857999">"Gorde hemen"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elementu</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ezabatu nahi duzu?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" karpeta eta bertako edukia ezabatu nahi duzu?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 1a4c035..fb4b487 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"اسناد"</string>
- <string name="files_label" msgid="6051402950202690279">"فایلها"</string>
<string name="downloads_label" msgid="959113951084633612">"بارگیریها"</string>
<string name="title_open" msgid="4353228937663917801">"باز کردن از"</string>
<string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"«<xliff:g id="NAME">%1$s</xliff:g>» حذف شود؟"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"پوشه «<xliff:g id="NAME">%1$s</xliff:g>» و محتوای آن حذف شود؟"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index dfcfe89..21c0ce2 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Asiakirjat"</string>
- <string name="files_label" msgid="6051402950202690279">"Tiedostot"</string>
<string name="downloads_label" msgid="959113951084633612">"Lataukset"</string>
<string name="title_open" msgid="4353228937663917801">"Avaa sijainnista"</string>
<string name="title_save" msgid="2433679664882857999">"Tallenna kohteeseen"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kohdetta</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kohde</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Poistetaanko <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Poistetaanko kansio <xliff:g id="NAME">%1$s</xliff:g> ja sen sisältö?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index 543e226..a741e6b 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> article</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> articles</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Supprimer « <xliff:g id="NAME">%1$s</xliff:g> »?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Supprimer le dossier « <xliff:g id="NAME">%1$s</xliff:g> » et son contenu?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 05716d7..d41137e 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Docs"</string>
- <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Supprimer \"<xliff:g id="NAME">%1$s</xliff:g>\" ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Supprimer le dossier \"<xliff:g id="NAME">%1$s</xliff:g>\" et son contenu ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index 5797a96..77cc59d6 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Gardar en"</string>
@@ -120,6 +119,10 @@
<item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Queres eliminar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Queres eliminar o cartafol \"<xliff:g id="NAME">%1$s</xliff:g>\" e o seu contido?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 48e43c4..e3cd4cf 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"દસ્તાવેજો"</string>
- <string name="files_label" msgid="6051402950202690279">"ફાઇલો"</string>
<string name="downloads_label" msgid="959113951084633612">"ડાઉનલોડ્સ"</string>
<string name="title_open" msgid="4353228937663917801">"અહીંથી ખોલો"</string>
<string name="title_save" msgid="2433679664882857999">"આમાં સાચવો"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ને કાઢી નાખીએ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ફોલ્ડર અને તેની સામગ્રીઓને કાઢી નાખીએ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index fa82ee8..fa27dff 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तावेज़"</string>
- <string name="files_label" msgid="6051402950202690279">"फ़ाइलें"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोड"</string>
<string name="title_open" msgid="4353228937663917801">"यहां से खोलें"</string>
<string name="title_save" msgid="2433679664882857999">"यहां सहेजें"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" को हटाएं?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" फ़ोल्डर और उसकी सामग्रियां हटाएं?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 7988c71..66a8329 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
<string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
@@ -128,6 +127,11 @@
<item quantity="few">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li izbrisati datoteku \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li izbrisati mapu \"<xliff:g id="NAME">%1$s</xliff:g>\" i njezin sadržaj?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index fb666b5..962653c 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentumok"</string>
- <string name="files_label" msgid="6051402950202690279">"Fájlok"</string>
<string name="downloads_label" msgid="959113951084633612">"Letöltések"</string>
<string name="title_open" msgid="4353228937663917801">"Megnyitás innen"</string>
<string name="title_save" msgid="2433679664882857999">"Mentés ide"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elem</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elem</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Törli a következőt: „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Törli „<xliff:g id="NAME">%1$s</xliff:g>” mappát a tartalmával együtt?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index f6c3ad5..ab83358 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Փաստաթղթեր"</string>
- <string name="files_label" msgid="6051402950202690279">"Ֆայլեր"</string>
<string name="downloads_label" msgid="959113951084633612">"Ներբեռնումներ"</string>
<string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
<string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
@@ -120,6 +119,10 @@
<item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ջնջե՞լ «<xliff:g id="NAME">%1$s</xliff:g>» ֆայլը:"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ջնջե՞լ «<xliff:g id="NAME">%1$s</xliff:g>» պանակը՝ բովանդակության հետ մեկտեղ:"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index a8aee52..745bf45 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
- <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="downloads_label" msgid="959113951084633612">"Unduhan"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Hapus \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Hapus folder \"<xliff:g id="NAME">%1$s</xliff:g>\" dan kontennya?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 88aaced..47c3d35 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Skjöl"</string>
- <string name="files_label" msgid="6051402950202690279">"Skrár"</string>
<string name="downloads_label" msgid="959113951084633612">"Niðurhal"</string>
<string name="title_open" msgid="4353228937663917801">"Opna frá"</string>
<string name="title_save" msgid="2433679664882857999">"Vista í"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atriði</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atriði</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Eyða „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Eyða möppunni „<xliff:g id="NAME">%1$s</xliff:g>“ og öllu innihaldi hennar?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index b7497db..0321fb1 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenti"</string>
- <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="downloads_label" msgid="959113951084633612">"Download"</string>
<string name="title_open" msgid="4353228937663917801">"Apri da"</string>
<string name="title_save" msgid="2433679664882857999">"Salva in"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi selezionati</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento selezionato</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Eliminare \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Eliminare la cartella \"<xliff:g id="NAME">%1$s</xliff:g>\" e i relativi contenuti?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 4498f8c..4e69606 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"מסמכים"</string>
- <string name="files_label" msgid="6051402950202690279">"קבצים"</string>
<string name="downloads_label" msgid="959113951084633612">"הורדות"</string>
<string name="title_open" msgid="4353228937663917801">"פתח מ-"</string>
<string name="title_save" msgid="2433679664882857999">"שמור ב-"</string>
@@ -136,6 +135,12 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> נבחר</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="one">פריט <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"האם למחוק את \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"האם למחוק את התיקייה \"<xliff:g id="NAME">%1$s</xliff:g>\" ואת התוכן שלה?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index bfb1c3a..027bc03 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ドキュメント"</string>
- <string name="files_label" msgid="6051402950202690279">"ファイル"</string>
<string name="downloads_label" msgid="959113951084633612">"ダウンロード"</string>
<string name="title_open" msgid="4353228937663917801">"次から開く:"</string>
<string name="title_save" msgid="2433679664882857999">"次に保存:"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個を選択中</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個を選択中</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のアイテム</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のアイテム</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"「<xliff:g id="NAME">%1$s</xliff:g>」を削除しますか?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"フォルダ「<xliff:g id="NAME">%1$s</xliff:g>」とそのコンテンツを削除しますか?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index f0e9e86..4ac61f2 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"დოკუმენტები"</string>
- <string name="files_label" msgid="6051402950202690279">"ფაილები"</string>
<string name="downloads_label" msgid="959113951084633612">"ჩამოტვირთვები"</string>
<string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
<string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
@@ -120,6 +119,10 @@
<item quantity="other">არჩეულია <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">არჩეულია <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ერთეული</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ერთეული</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"გსურთ, წაშალოთ „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"გსურთ, წაშალოთ საქაღალდე „<xliff:g id="NAME">%1$s</xliff:g>“ და მისი შიგთავსი?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 2687900..1babc72 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Құжаттар"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="downloads_label" msgid="959113951084633612">"Жүктеулер"</string>
<string name="title_open" msgid="4353228937663917801">"Мынадан ашу:"</string>
<string name="title_save" msgid="2433679664882857999">"Сақталатын орны"</string>
@@ -111,7 +110,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_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына қатынас беру керек пе?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<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>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> элемент</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> элемент</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" жою керек пе?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" қалтасын және оның мазмұнын жою керек пе?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index ea24043..37eb3cb 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ឯកសារ"</string>
- <string name="files_label" msgid="6051402950202690279">"ឯកសារ"</string>
<string name="downloads_label" msgid="959113951084633612">"ដោនឡូត"</string>
<string name="title_open" msgid="4353228937663917801">"បើកពី"</string>
<string name="title_save" msgid="2433679664882857999">"រក្សាទុកទៅ"</string>
@@ -120,6 +119,10 @@
<item quantity="other">បានជ្រើស <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">បានជ្រើស <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ធាតុ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ធាតុ</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"លុប \"<xliff:g id="NAME">%1$s</xliff:g>\" ឬ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"លុបថតឯកសារ \"<xliff:g id="NAME">%1$s</xliff:g>\" និងមាតិការបស់វាឬ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index c756009..ad287d4 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
- <string name="files_label" msgid="6051402950202690279">"ಫೈಲ್ಗಳು"</string>
<string name="downloads_label" msgid="959113951084633612">"ಡೌನ್ಲೋಡ್ಗಳು"</string>
<string name="title_open" msgid="4353228937663917801">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
<string name="title_save" msgid="2433679664882857999">"ಇವುಗಳಲ್ಲಿ ಉಳಿಸಿ"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳು</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳು</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಅಳಿಸುವುದೇ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಫೋಲ್ಡರ್ ಮತ್ತು ಅದರ ವಿಷಯಗಳನ್ನು ಅಳಿಸುವುದೇ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 4d5dcf9..9441a10 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"문서"</string>
- <string name="files_label" msgid="6051402950202690279">"파일"</string>
<string name="downloads_label" msgid="959113951084633612">"다운로드"</string>
<string name="title_open" msgid="4353228937663917801">"열기:"</string>
<string name="title_save" msgid="2433679664882857999">"저장 위치:"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other">항목 <xliff:g id="COUNT_1">%1$d</xliff:g>개</item>
+ <item quantity="one">항목 <xliff:g id="COUNT_0">%1$d</xliff:g>개</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"<xliff:g id="NAME">%1$s</xliff:g>을(를) 삭제하시겠습니까?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\'<xliff:g id="NAME">%1$s</xliff:g>\' 폴더와 폴더에 포함된 콘텐츠를 삭제하시겠습니까?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 1b39039..1856eeb 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документтер"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="downloads_label" msgid="959113951084633612">"Жүктөлүп алынгандар"</string>
<string name="title_open" msgid="4353228937663917801">"Кийинкиден ачуу:"</string>
<string name="title_save" msgid="2433679664882857999">"Кийинкиге сактоо:"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> нерсе</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> нерсе</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" жок кылынсынбы?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" куржуну мазмуну менен жок кылынсынбы?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index a4f381d..1923940 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ເອກະສານ"</string>
- <string name="files_label" msgid="6051402950202690279">"ໄຟລ໌"</string>
<string name="downloads_label" msgid="959113951084633612">"ການດາວໂຫລດ"</string>
<string name="title_open" msgid="4353228937663917801">"ເປີດຈາກ"</string>
<string name="title_save" msgid="2433679664882857999">"ບັນທຶກໄປທີ່"</string>
@@ -120,6 +119,10 @@
<item quantity="other">ເລືອກ <xliff:g id="COUNT_1">%1$d</xliff:g> ແລ້ວ</item>
<item quantity="one">ເລືອກ <xliff:g id="COUNT_0">%1$d</xliff:g> ແລ້ວ</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ລາຍການ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ລາຍການ</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ລຶບ \"<xliff:g id="NAME">%1$s</xliff:g>\" ອອກບໍ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ລຶບໂຟນເດີ \"<xliff:g id="NAME">%1$s</xliff:g>\" ແລະ ເນື້ອຫາທັງໝົດຂອງມັນອອກບໍ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 2e0df93..d7d6c69 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentai"</string>
- <string name="files_label" msgid="6051402950202690279">"Failai"</string>
<string name="downloads_label" msgid="959113951084633612">"Atsisiuntimai"</string>
<string name="title_open" msgid="4353228937663917801">"Atidaryti iš"</string>
<string name="title_save" msgid="2433679664882857999">"Išsaugoti į"</string>
@@ -136,6 +135,12 @@
<item quantity="many">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
<item quantity="other">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> elementas</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementai</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ištrinti „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ištrinti aplanką „<xliff:g id="NAME">%1$s</xliff:g>“ ir jo turinį?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index fb81aa0..ef2e6e6 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="downloads_label" msgid="959113951084633612">"Lejupielādes"</string>
<string name="title_open" msgid="4353228937663917801">"Atvēršana no:"</string>
<string name="title_save" msgid="2433679664882857999">"Saglabāšana:"</string>
@@ -128,6 +127,11 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> vienumu</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> vienums</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> vienumi</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vai izdzēst failu “<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vai izdzēst mapi “<xliff:g id="NAME">%1$s</xliff:g>” un tās saturu?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index ad428a0..c6f58c0 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Датотеки"</string>
<string name="downloads_label" msgid="959113951084633612">"Преземања"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори од"</string>
<string name="title_save" msgid="2433679664882857999">"Зачувај во"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> е избрана</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> се избрани</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Да се избрише „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Да се избрише папката „<xliff:g id="NAME">%1$s</xliff:g>“ и нејзините содржини?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 5a16512..5bafacd 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"പ്രമാണങ്ങൾ"</string>
- <string name="files_label" msgid="6051402950202690279">"ഫയലുകൾ"</string>
<string name="downloads_label" msgid="959113951084633612">"ഡൗണ്ലോഡുകൾ"</string>
<string name="title_open" msgid="4353228937663917801">"ഇതിൽ നിന്നും തുറക്കുക"</string>
<string name="title_save" msgid="2433679664882857999">"ഇതില് സംരക്ഷിക്കുക"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഇനങ്ങൾ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഇനം</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ഇല്ലാതാക്കണോ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" എന്ന ഫോൾഡറും അതിലെ ഉള്ളടങ്ങളും ഇല്ലാതാക്കണോ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index cf2c2d4..2323d23 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документүүд"</string>
- <string name="files_label" msgid="6051402950202690279">"Файл"</string>
<string name="downloads_label" msgid="959113951084633612">"Таталт"</string>
<string name="title_open" msgid="4353228937663917801">"Нээх"</string>
<string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> сонгосон</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> сонгосон</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> зүйл</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> зүйл</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"-г устгах уу?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" фолдер болон үүний агуулгыг устгах уу?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 09dd133..eb7dab3 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तऐवज"</string>
- <string name="files_label" msgid="6051402950202690279">"फायली"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोड"</string>
<string name="title_open" msgid="4353228937663917801">"वरून उघडा"</string>
<string name="title_save" msgid="2433679664882857999">"येथे जतन करा"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडला</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" हटवायची?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" फोल्डर आणि त्यामधील सामग्री हटवायची?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 9eb3d49..71118d8 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
- <string name="files_label" msgid="6051402950202690279">"Fail"</string>
<string name="downloads_label" msgid="959113951084633612">"Muat turun"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Padamkan \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Padamkan folder \"<xliff:g id="NAME">%1$s</xliff:g>\" dan kandungannya?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 7c637c4..a0b1777 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"စာရွက်စာတန်းများ"</string>
- <string name="files_label" msgid="6051402950202690279">"ဖိုင်များ"</string>
<string name="downloads_label" msgid="959113951084633612">"ဒေါင်းလုဒ်များ"</string>
<string name="title_open" msgid="4353228937663917801">"မှ ဖွင့်ပါ"</string>
<string name="title_save" msgid="2433679664882857999">"သို့ သိမ်းပါ"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခု</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခု</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ကိုဖျက်မလား။"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ဖိုင်တွဲနှင့် ၎င်းတွင်ပါဝင်သည့် အကြောင်းအရာများကို ဖျက်မလား။"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 3c344eb..fd07c8d 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Nedlastinger"</string>
<string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
<string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> varer</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> vare</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vil du slette «<xliff:g id="NAME">%1$s</xliff:g>»?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vil du slette «<xliff:g id="NAME">%1$s</xliff:g>»-mappen og innholdet i den?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 9fef037..31085d5 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"कागजातहरू"</string>
- <string name="files_label" msgid="6051402950202690279">"फाइलहरू"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोडहरू"</string>
<string name="title_open" msgid="4353228937663917801">"यसबाट खोल्नुहोस्"</string>
<string name="title_save" msgid="2433679664882857999">"यसमा सुरक्षित गर्नुहोस्"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> लाई चयन गरियो</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> लाई चयन गरियो</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> वस्तुहरू</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> वस्तु</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" लाई मेट्ने हो?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"फोल्डर \"<xliff:g id="NAME">%1$s</xliff:g>\" र यसका सामग्रीहरूलाई मेट्ने हो?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index c5b9d76..7b0ce93 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenten"</string>
- <string name="files_label" msgid="6051402950202690279">"Bestanden"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"<xliff:g id="NAME">%1$s</xliff:g> verwijderen?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Map <xliff:g id="NAME">%1$s</xliff:g> en de bijbehorende inhoud verwijderen?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index 7d5e14a..25e4cd6 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ਦਸਤਾਵੇਜ਼"</string>
- <string name="files_label" msgid="6051402950202690279">"ਫਾਈਲਾਂ"</string>
<string name="downloads_label" msgid="959113951084633612">"ਡਾਊਨਲੋਡ"</string>
<string name="title_open" msgid="4353228937663917801">"ਤੋਂ ਖੋਲ੍ਹੋ"</string>
<string name="title_save" msgid="2433679664882857999">"ਇਸ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀ ਗਈ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀਆਂ ਗਈਆਂ</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ਕੀ \"<xliff:g id="NAME">%1$s</xliff:g>\" ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ਫੋਲਡਰ \"<xliff:g id="NAME">%1$s</xliff:g>\" ਅਤੇ ਉਸ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index ca007d7..09ca839 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Pliki"</string>
<string name="downloads_label" msgid="959113951084633612">"Pobrane"</string>
<string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
<string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
@@ -136,6 +135,12 @@
<item quantity="other">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Wybrano <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementy</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> elementów</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Usunąć „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Usunąć folder „<xliff:g id="NAME">%1$s</xliff:g>” i jego zawartość?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index 21359c7..921be33 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
@@ -111,7 +110,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_request_primary_volume" msgid="6635562535713428688">"Conceder acesso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></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>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Excluir \" <xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Excluir pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e o respectivo conteúdo?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index aea1249..c80bdd2 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="downloads_label" msgid="959113951084633612">"Transferências"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Pretende eliminar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Pretende eliminar a pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e os respetivos conteúdos?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 21359c7..921be33 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
@@ -111,7 +110,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_request_primary_volume" msgid="6635562535713428688">"Conceder acesso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></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>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Excluir \" <xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Excluir pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e o respectivo conteúdo?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 4b833b1..ced834c 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documente"</string>
- <string name="files_label" msgid="6051402950202690279">"Fișiere"</string>
<string name="downloads_label" msgid="959113951084633612">"Descărcări"</string>
<string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
<string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
@@ -128,6 +127,11 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selectat</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elemente</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> de elemente</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ștergeți „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ștergeți dosarul „<xliff:g id="NAME">%1$s</xliff:g>” și conținutul acestuia?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 6ba635d..02077cf 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документы"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлы"</string>
<string name="downloads_label" msgid="959113951084633612">"Загрузки"</string>
<string name="title_open" msgid="4353228937663917801">"Открыть"</string>
<string name="title_save" msgid="2433679664882857999">"Сохранить"</string>
@@ -136,6 +135,12 @@
<item quantity="many">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> объект</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> объекта</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> объектов</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> объекта</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Удалить файл \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Удалить папку \"<xliff:g id="NAME">%1$s</xliff:g>\" со всем содержимым?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 41c9d4a..d39e853 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ලේඛන"</string>
- <string name="files_label" msgid="6051402950202690279">"ගොනු"</string>
<string name="downloads_label" msgid="959113951084633612">"බාගැනීම්"</string>
<string name="title_open" msgid="4353228937663917801">"විවෘත වන්නේ"</string>
<string name="title_save" msgid="2433679664882857999">"සුරකින්නේ"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" මකන්නද?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ෆෝල්ඩරය හා එහි අන්තර්ගත මකන්නද?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 1ff01b0..eb59a51 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Súbory"</string>
<string name="downloads_label" msgid="959113951084633612">"Stiahnuté súbory"</string>
<string name="title_open" msgid="4353228937663917801">"Otvoriť z"</string>
<string name="title_save" msgid="2433679664882857999">"Uložiť do"</string>
@@ -136,6 +135,12 @@
<item quantity="other">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Vybraté: <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> položiek</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Odstrániť <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Odstrániť priečinok <xliff:g id="NAME">%1$s</xliff:g> a jeho obsah?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index d8b983c..d3daabb 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Prenosi"</string>
<string name="title_open" msgid="4353228937663917801">"Odpri iz mape"</string>
<string name="title_save" msgid="2433679664882857999">"Shrani v"</string>
@@ -136,6 +135,12 @@
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrani</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izbranih</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> elementa</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementov</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ali želite izbrisati »<xliff:g id="NAME">%1$s</xliff:g>«?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ali želite izbrisati mapo »<xliff:g id="NAME">%1$s</xliff:g>« in njeno vsebino?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index 933a537..fe93300 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Skedarët"</string>
<string name="downloads_label" msgid="959113951084633612">"Shkarkimet"</string>
<string name="title_open" msgid="4353228937663917801">"Hap nga"</string>
<string name="title_save" msgid="2433679664882857999">"Ruaje te"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhur</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> artikuj</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> artikull</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Të fshihet \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Të fshihet dosja \"<xliff:g id="NAME">%1$s</xliff:g>\" dhe përmbajtja e saj?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 0505f42..95af81f 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Датотеке"</string>
<string name="downloads_label" msgid="959113951084633612">"Преузимања"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
<string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
@@ -128,6 +127,11 @@
<item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
<item quantity="other">Изабрано је <xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Желите ли да избришете „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Желите ли да избришете директоријум „<xliff:g id="NAME">%1$s</xliff:g>“ и његов садржај?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 99f334b..17dfffd 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokument"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Nedladdningar"</string>
<string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
<string name="title_save" msgid="2433679664882857999">"Spara till"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> objekt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> objekt</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vill du radera <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vill du radera mappen <xliff:g id="NAME">%1$s</xliff:g> och dess innehåll?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 566e6a4..cf9c8c7 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hati"</string>
- <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="downloads_label" msgid="959113951084633612">"Vipakuliwa"</string>
<string name="title_open" msgid="4353228937663917801">"Fungua kutoka"</string>
<string name="title_save" msgid="2433679664882857999">"Hifadhi kwenye"</string>
@@ -120,6 +119,10 @@
<item quantity="other">Imechagua <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Imechagua <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other">Vipengee <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Kipengee <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ungependa kufuta \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ungependa kufuta folda ya \"<xliff:g id="NAME">%1$s</xliff:g>\" na maudhui yake?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index 9a8b4ec..d4c2f6a 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ஆவணங்கள்"</string>
- <string name="files_label" msgid="6051402950202690279">"கோப்புகள்"</string>
<string name="downloads_label" msgid="959113951084633612">"இறக்கங்கள்"</string>
<string name="title_open" msgid="4353228937663917801">"இதில் திற"</string>
<string name="title_save" msgid="2433679664882857999">"இதில் சேமி"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> உருப்படிகள்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> உருப்படி</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ஐ நீக்கவா?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" கோப்புறையையும் அதன் உள்ளடக்கத்தையும் நீக்கவா?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index 224d0db..3a91252 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"పత్రాలు"</string>
- <string name="files_label" msgid="6051402950202690279">"ఫైల్లు"</string>
<string name="downloads_label" msgid="959113951084633612">"డౌన్లోడ్లు"</string>
<string name="title_open" msgid="4353228937663917801">"ఇక్కడి నుండి తెరువు"</string>
<string name="title_save" msgid="2433679664882857999">"ఇందులో సేవ్ చేయి"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> అంశాలు</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> అంశం</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ని తొలగించాలా?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ఫోల్డర్ని మరియు అందులోని కంటెంట్లను తొలగించాలా?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index af07584..f739eda 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"เอกสาร"</string>
- <string name="files_label" msgid="6051402950202690279">"ไฟล์"</string>
<string name="downloads_label" msgid="959113951084633612">"การดาวน์โหลด"</string>
<string name="title_open" msgid="4353228937663917801">"เปิดจาก"</string>
<string name="title_save" msgid="2433679664882857999">"บันทึกไปยัง"</string>
@@ -120,6 +119,10 @@
<item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
<item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ลบ \"<xliff:g id="NAME">%1$s</xliff:g>\" ไหม"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ลบโฟลเดอร์ \"<xliff:g id="NAME">%1$s</xliff:g>\" และเนื้อหาข้างในไหม"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index b2acf05..3474be8 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Mga Dokumento"</string>
- <string name="files_label" msgid="6051402950202690279">"Mga File"</string>
<string name="downloads_label" msgid="959113951084633612">"Mga Download"</string>
<string name="title_open" msgid="4353228937663917801">"Buksan mula sa"</string>
<string name="title_save" msgid="2433679664882857999">"I-save sa"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> na item</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Gusto mo bang i-delete ang \"<xliff:g id="NAME">%1$s</xliff:g>?\""</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Gusto mo bang i-delete ang folder na \"<xliff:g id="NAME">%1$s</xliff:g>\" at ang mga content nito?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index c5653c9..b685568 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokümanlar"</string>
- <string name="files_label" msgid="6051402950202690279">"Dosyalar"</string>
<string name="downloads_label" msgid="959113951084633612">"İndirilenler"</string>
<string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
<string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" silinsin mi?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" adlı klasör ve içindekiler silinsin mi?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index 21532b6..b255459 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Файли"</string>
<string name="downloads_label" msgid="959113951084633612">"Завантаження"</string>
<string name="title_open" msgid="4353228937663917801">"Відкрити"</string>
<string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
@@ -136,6 +135,12 @@
<item quantity="many">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> елемент</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> елементи</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> елементів</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> елемента</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Видалити файл <xliff:g id="NAME">%1$s</xliff:g>?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Видалити папку \"<xliff:g id="NAME">%1$s</xliff:g>\" та її вміст?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index eb0cfc8..8d85a2b 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"دستاویزات"</string>
- <string name="files_label" msgid="6051402950202690279">"فائلیں"</string>
<string name="downloads_label" msgid="959113951084633612">"ڈاؤن لوڈز"</string>
<string name="title_open" msgid="4353228937663917801">"کھولیں از"</string>
<string name="title_save" msgid="2433679664882857999">"اس میں محفوظ کریں"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> آئٹمز</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> آئٹم</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" حذف کریں؟"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" فولڈر اور اس کی مشمولات حذف کریں؟"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index 2654308..76e82da 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hujjatlar"</string>
- <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="downloads_label" msgid="959113951084633612">"Yuklanishlar"</string>
<string name="title_open" msgid="4353228937663917801">"Ochish"</string>
<string name="title_save" msgid="2433679664882857999">"Saqlash"</string>
@@ -120,6 +119,10 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta belgilandi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta belgilandi</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta element</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta element</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"“<xliff:g id="NAME">%1$s</xliff:g>” fayli o‘chirib tashlansinmi?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"“<xliff:g id="NAME">%1$s</xliff:g>” jildi ichidagi kontentlari bilan o‘chirib tashlansinmi?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index 9af7db0..9e69e0f 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Tài liệu"</string>
- <string name="files_label" msgid="6051402950202690279">"Tệp"</string>
<string name="downloads_label" msgid="959113951084633612">"Tài nguyên đã tải xuống"</string>
<string name="title_open" msgid="4353228937663917801">"Mở từ"</string>
<string name="title_save" msgid="2433679664882857999">"Lưu vào"</string>
@@ -120,6 +119,10 @@
<item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> mục</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> mục</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Xóa \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Xóa thư mục \"<xliff:g id="NAME">%1$s</xliff:g>\" và nội dung của thư mục?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index e3db1a0..00e4c91 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文档"</string>
- <string name="files_label" msgid="6051402950202690279">"文件"</string>
<string name="downloads_label" msgid="959113951084633612">"下载"</string>
<string name="title_open" msgid="4353228937663917801">"打开文件"</string>
<string name="title_save" msgid="2433679664882857999">"保存文件"</string>
@@ -111,7 +110,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_request_primary_volume" msgid="6635562535713428688">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>目录吗?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要授权<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>
@@ -120,6 +119,7 @@
<item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
<item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
</plurals>
+ <!-- no translation found for elements_dragged (3727204615215602228) -->
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"要删除“<xliff:g id="NAME">%1$s</xliff:g>”吗?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要删除文件夹“<xliff:g id="NAME">%1$s</xliff:g>”及其中的内容吗?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index f13a4bd1..4b0f4e2 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
- <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="downloads_label" msgid="959113951084633612">"下載"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
@@ -120,6 +119,10 @@
<item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
<item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」資料夾及其內容嗎?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index f8f8282..07c5c2a 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
- <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="downloads_label" msgid="959113951084633612">"下載內容"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
@@ -120,6 +119,10 @@
<item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
<item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」資料夾和當中的內容嗎?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index a0b9f7f..095d275 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Amadokhumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Amafayela"</string>
<string name="downloads_label" msgid="959113951084633612">"Okulandiwe"</string>
<string name="title_open" msgid="4353228937663917801">"Vula kusuka ku-"</string>
<string name="title_save" msgid="2433679664882857999">"Londoloza ku-"</string>
@@ -120,6 +119,10 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
</plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izinto</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izinto</item>
+ </plurals>
<string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Susa i-\"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
<string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Susa ifolda engu-\"<xliff:g id="NAME">%1$s</xliff:g>\" nokuqukethwe kwalo?"</string>
<plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 4ee37a5..3b0be57 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -257,7 +257,6 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- Metrics.logMenuAction(this, item.getItemId());
switch (item.getItemId()) {
case android.R.id.home:
@@ -279,6 +278,7 @@
case R.id.menu_sort_date:
setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
return true;
+
case R.id.menu_sort_size:
setUserSortOrder(State.SORT_ORDER_SIZE);
return true;
@@ -307,6 +307,8 @@
return true;
case R.id.menu_settings:
+ Metrics.logUserAction(this, Metrics.USER_ACTION_SETTINGS);
+
final RootInfo root = getCurrentRoot();
final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
@@ -323,6 +325,8 @@
}
void showCreateDirectoryDialog() {
+ Metrics.logUserAction(this, Metrics.USER_ACTION_CREATE_DIR);
+
CreateDirectoryFragment.show(getFragmentManager());
}
@@ -469,13 +473,25 @@
"com.android.providers.downloads.documents", "downloads");
}
+ /**
+ * Set internal storage visible based on explicit user action.
+ */
void setDisplayAdvancedDevices(boolean display) {
+ Metrics.logUserAction(this,
+ display ? Metrics.USER_ACTION_SHOW_ADVANCED : Metrics.USER_ACTION_HIDE_ADVANCED);
+
mState.showAdvanced = display;
RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
invalidateOptionsMenu();
}
+ /**
+ * Set file size visible based on explicit user action.
+ */
void setDisplayFileSize(boolean display) {
+ Metrics.logUserAction(this,
+ display ? Metrics.USER_ACTION_SHOW_SIZE : Metrics.USER_ACTION_HIDE_SIZE);
+
LocalPreferences.setDisplayFileSize(this, display);
mState.showSize = display;
DirectoryFragment dir = getDirectoryFragment();
@@ -489,6 +505,18 @@
* Set state sort order based on explicit user action.
*/
void setUserSortOrder(int sortOrder) {
+ switch(sortOrder) {
+ case State.SORT_ORDER_DISPLAY_NAME:
+ Metrics.logUserAction(this, Metrics.USER_ACTION_SORT_NAME);
+ break;
+ case State.SORT_ORDER_LAST_MODIFIED:
+ Metrics.logUserAction(this, Metrics.USER_ACTION_SORT_DATE);
+ break;
+ case State.SORT_ORDER_SIZE:
+ Metrics.logUserAction(this, Metrics.USER_ACTION_SORT_SIZE);
+ break;
+ }
+
mState.userSortOrder = sortOrder;
DirectoryFragment dir = getDirectoryFragment();
if (dir != null) {
@@ -500,6 +528,12 @@
* Set mode based on explicit user action.
*/
void setViewMode(@ViewMode int mode) {
+ if (mode == State.MODE_GRID) {
+ Metrics.logUserAction(this, Metrics.USER_ACTION_GRID);
+ } else if (mode == State.MODE_LIST) {
+ Metrics.logUserAction(this, Metrics.USER_ACTION_LIST);
+ }
+
LocalPreferences.setViewMode(this, getCurrentRoot(), mode);
mState.derivedMode = mode;
@@ -621,12 +655,10 @@
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_TAB) {
- Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_SWITCH_FOCUS);
// Tab toggles focus on the navigation drawer.
toggleNavDrawerFocus();
return true;
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
- Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_BACK);
popDir();
return true;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 527eb78..84fc6fe 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -98,7 +98,7 @@
assert(uri == null || uri.getAuthority() == null ||
LauncherActivity.isLaunchUri(uri));
refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
- } else if (intent.getAction() == Intent.ACTION_VIEW) {
+ } else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
assert(uri != null);
new OpenUriForViewTask(this).executeOnExecutor(
ProviderExecutor.forAuthority(uri.getAuthority()), uri);
@@ -228,13 +228,12 @@
default:
return super.onOptionsItemSelected(item);
}
-
- Metrics.logMenuAction(this, item.getItemId());
return true;
}
private void createNewWindow() {
- Metrics.logMultiWindow(this);
+ Metrics.logUserAction(this, Metrics.USER_ACTION_NEW_WINDOW);
+
Intent intent = LauncherActivity.createLaunchIntent(this);
intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
@@ -277,18 +276,6 @@
@Override
public void onDocumentPicked(DocumentInfo doc, Model model) {
- if (doc.isContainer()) {
- openContainerDocument(doc);
- } else {
- openDocument(doc, model);
- }
- }
-
- /**
- * Launches an intent to view the specified document.
- */
- private void openDocument(DocumentInfo doc, Model model) {
-
// Anything on downloads goes through the back through downloads manager
// (that's the MANAGE_DOCUMENT bit).
// This is done for two reasons:
@@ -298,7 +285,13 @@
// like origin URL.
// All other files not on downloads, event APKs, would get no benefit from this
// treatment, thusly the "isDownloads" check.
- if (getCurrentRoot().isDownloads()) {
+
+ // Launch MANAGE_DOCUMENTS only for the root level files, so it's not called for
+ // files in archives. Also, if the activity is already browsing a ZIP from downloads,
+ // then skip MANAGE_DOCUMENTS.
+ final boolean isViewing = Intent.ACTION_VIEW.equals(getIntent().getAction());
+ final boolean isInArchive = mState.stack.size() > 1;
+ if (getCurrentRoot().isDownloads() && !isInArchive && !isViewing) {
// First try managing the document; we expect manager to filter
// based on authority, so we don't grant.
final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
@@ -312,6 +305,17 @@
}
}
+ if (doc.isContainer()) {
+ openContainerDocument(doc);
+ } else {
+ openDocument(doc, model);
+ }
+ }
+
+ /**
+ * Launches an intent to view the specified document.
+ */
+ private void openDocument(DocumentInfo doc, Model model) {
Intent intent = new QuickViewIntentBuilder(
getPackageManager(), getResources(), doc, model).build();
@@ -352,21 +356,18 @@
case KeyEvent.KEYCODE_A:
dir = getDirectoryFragment();
if (dir != null) {
- Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_SELECT_ALL);
dir.selectAllFiles();
}
return true;
case KeyEvent.KEYCODE_C:
dir = getDirectoryFragment();
if (dir != null) {
- Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_COPY);
dir.copySelectedToClipboard();
}
return true;
case KeyEvent.KEYCODE_V:
dir = getDirectoryFragment();
if (dir != null) {
- Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_PASTE);
dir.pasteFromClipboard();
}
return true;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 05cc7e6..69a6e1f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -62,16 +62,13 @@
private static final String COUNT_GET_CONTENT_MIME = "docsui_get_content_mime";
private static final String COUNT_BROWSE_ROOT = "docsui_browse_root";
@Deprecated private static final String COUNT_MANAGE_ROOT = "docsui_manage_root";
- private static final String COUNT_MULTI_WINDOW = "docsui_multi_window";
+ @Deprecated private static final String COUNT_MULTI_WINDOW = "docsui_multi_window";
private static final String COUNT_FILEOP_SYSTEM = "docsui_fileop_system";
private static final String COUNT_FILEOP_EXTERNAL = "docsui_fileop_external";
private static final String COUNT_FILEOP_CANCELED = "docsui_fileop_canceled";
private static final String COUNT_STARTUP_MS = "docsui_startup_ms";
private static final String COUNT_DRAWER_OPENED = "docsui_drawer_opened";
- private static final String COUNT_DRAG_N_DROP = "docsui_drag_n_drop";
- private static final String COUNT_SEARCH = "docsui_search";
- private static final String COUNT_MENU_ACTION = "docsui_menu_action";
- private static final String COUNT_KEYBOARD_ACTION = "docsui_keyboard_action";
+ private static final String COUNT_USER_ACTION = "docsui_menu_action";
// Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
// root that is not explicitly recognized by the Metrics code (see {@link
@@ -215,54 +212,67 @@
public @interface Provider {}
- // Codes representing different menu actions. These are used for bucketing stats in the
- // COUNT_MENU_ACTION histogram.
- // Both regular toolbar menu and action mode menu operations are included.
+ // Codes representing different user actions. These are used for bucketing stats in the
+ // COUNT_USER_ACTION histogram.
+ // The historgram includes action triggered from menu or invoked by keyboard shortcut.
// Do not change or rearrange these values, that will break historical data. Only add to the
// list.
// Do not use negative numbers or zero; clearcut only handles positive integers.
- private static final int ACTION_MENU_OTHER = 1;
- private static final int ACTION_MENU_GRID = 2;
- private static final int ACTION_MENU_LIST = 3;
- private static final int ACTION_MENU_SORT = 4;
- private static final int ACTION_MENU_SORT_NAME = 5;
- private static final int ACTION_MENU_SORT_DATE = 6;
- private static final int ACTION_MENU_SORT_SIZE = 7;
- private static final int ACTION_MENU_SEARCH = 8;
- private static final int ACTION_MENU_SHOW_SIZE = 9;
- private static final int ACTION_MENU_SETTINGS = 10;
- private static final int ACTION_MENU_COPY_TO = 11;
- private static final int ACTION_MENU_MOVE_TO = 12;
- private static final int ACTION_MENU_DELETE = 13;
- private static final int ACTION_MENU_RENAME = 14;
- private static final int ACTION_MENU_CREATE_DIR = 15;
- private static final int ACTION_MENU_SELECT_ALL = 16;
- private static final int ACTION_MENU_SHARE = 17;
- private static final int ACTION_MENU_OPEN = 18;
- private static final int ACTION_MENU_ADVANCED = 19;
+ public static final int USER_ACTION_OTHER = 1;
+ public static final int USER_ACTION_GRID = 2;
+ public static final int USER_ACTION_LIST = 3;
+ public static final int USER_ACTION_SORT_NAME = 4;
+ public static final int USER_ACTION_SORT_DATE = 5;
+ public static final int USER_ACTION_SORT_SIZE = 6;
+ public static final int USER_ACTION_SEARCH = 7;
+ public static final int USER_ACTION_SHOW_SIZE = 8;
+ public static final int USER_ACTION_HIDE_SIZE = 9;
+ public static final int USER_ACTION_SETTINGS = 10;
+ public static final int USER_ACTION_COPY_TO = 11;
+ public static final int USER_ACTION_MOVE_TO = 12;
+ public static final int USER_ACTION_DELETE = 13;
+ public static final int USER_ACTION_RENAME = 14;
+ public static final int USER_ACTION_CREATE_DIR = 15;
+ public static final int USER_ACTION_SELECT_ALL = 16;
+ public static final int USER_ACTION_SHARE = 17;
+ public static final int USER_ACTION_OPEN = 18;
+ public static final int USER_ACTION_SHOW_ADVANCED = 19;
+ public static final int USER_ACTION_HIDE_ADVANCED = 20;
+ public static final int USER_ACTION_NEW_WINDOW = 21;
+ public static final int USER_ACTION_PASTE_CLIPBOARD = 22;
+ public static final int USER_ACTION_COPY_CLIPBOARD = 23;
+ public static final int USER_ACTION_DRAG_N_DROP = 24;
+ public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 25;
@IntDef(flag = false, value = {
- ACTION_MENU_OTHER,
- ACTION_MENU_GRID,
- ACTION_MENU_LIST,
- ACTION_MENU_SORT,
- ACTION_MENU_SORT_NAME,
- ACTION_MENU_SORT_DATE,
- ACTION_MENU_SORT_SIZE,
- ACTION_MENU_SHOW_SIZE,
- ACTION_MENU_SETTINGS,
- ACTION_MENU_COPY_TO,
- ACTION_MENU_MOVE_TO,
- ACTION_MENU_DELETE,
- ACTION_MENU_RENAME,
- ACTION_MENU_CREATE_DIR,
- ACTION_MENU_SELECT_ALL,
- ACTION_MENU_SHARE,
- ACTION_MENU_OPEN,
- ACTION_MENU_ADVANCED
+ USER_ACTION_OTHER,
+ USER_ACTION_GRID,
+ USER_ACTION_LIST,
+ USER_ACTION_SORT_NAME,
+ USER_ACTION_SORT_DATE,
+ USER_ACTION_SORT_SIZE,
+ USER_ACTION_SEARCH,
+ USER_ACTION_SHOW_SIZE,
+ USER_ACTION_HIDE_SIZE,
+ USER_ACTION_SETTINGS,
+ USER_ACTION_COPY_TO,
+ USER_ACTION_MOVE_TO,
+ USER_ACTION_DELETE,
+ USER_ACTION_RENAME,
+ USER_ACTION_CREATE_DIR,
+ USER_ACTION_SELECT_ALL,
+ USER_ACTION_SHARE,
+ USER_ACTION_OPEN,
+ USER_ACTION_SHOW_ADVANCED,
+ USER_ACTION_HIDE_ADVANCED,
+ USER_ACTION_NEW_WINDOW,
+ USER_ACTION_PASTE_CLIPBOARD,
+ USER_ACTION_COPY_CLIPBOARD,
+ USER_ACTION_DRAG_N_DROP,
+ USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
})
@Retention(RetentionPolicy.SOURCE)
- public @interface MenuAction {}
+ public @interface UserAction {}
// Codes representing different menu actions. These are used for bucketing stats in the
// COUNT_MENU_ACTION histogram.
@@ -291,31 +301,6 @@
@Retention(RetentionPolicy.SOURCE)
public @interface MetricsAction {}
- // Codes representing different keyboard shortcut triggered actions. These are used for
- // bucketing stats in the COUNT_KEYBOARD_ACTION histogram.
- // Do not change or rearrange these values, that will break historical data. Only add to the
- // list.
- // Do not use negative numbers or zero; clearcut only handles positive integers.
- public static final int ACTION_KEYBOARD_OTHER = 1;
- public static final int ACTION_KEYBOARD_PASTE = 2;
- public static final int ACTION_KEYBOARD_COPY = 3;
- public static final int ACTION_KEYBOARD_DELETE = 4;
- public static final int ACTION_KEYBOARD_SELECT_ALL = 5;
- public static final int ACTION_KEYBOARD_BACK = 6;
- public static final int ACTION_KEYBOARD_SWITCH_FOCUS = 7;
-
- @IntDef(flag = false, value = {
- ACTION_KEYBOARD_OTHER,
- ACTION_KEYBOARD_PASTE,
- ACTION_KEYBOARD_COPY,
- ACTION_KEYBOARD_DELETE,
- ACTION_KEYBOARD_SELECT_ALL,
- ACTION_KEYBOARD_BACK,
- ACTION_KEYBOARD_SWITCH_FOCUS
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface KeyboardAction {}
-
// Codes representing different actions to open the drawer. They are used for bucketing stats in
// the COUNT_DRAWER_OPENED histogram.
// Do not change or rearrange these values, that will break historical data. Only add to the
@@ -382,15 +367,6 @@
}
/**
- * Logs a multi-window start. Call this when the user spawns a new DocumentsUI window.
- *
- * @param context
- */
- public static void logMultiWindow(Context context) {
- logCount(context, COUNT_MULTI_WINDOW);
- }
-
- /**
* Logs a drawer opened event. Call this when the user opens drawer by swipe or by clicking the
* hamburger icon.
* @param context
@@ -496,7 +472,7 @@
* @param context
*/
public static void logCreateDirError(Context context) {
- logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR);
+ logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR_ERROR);
}
/**
@@ -520,16 +496,6 @@
}
/**
- * Logs keyboard shortcut actions. Since keyboard shortcuts have their corresponding menu items,
- * they are identified by menu item resource id for convenience.
- * @param context
- * @param keyCode
- */
- public static void logKeyboardAction(Context context, @KeyboardAction int action) {
- logHistogram(context, COUNT_KEYBOARD_ACTION, action);
- }
-
- /**
* Logs startup time in milliseconds.
* @param context
* @param startupMs Startup time in milliseconds.
@@ -538,25 +504,6 @@
logHistogram(context, COUNT_STARTUP_MS, startupMs);
}
- /**
- * Logs a drag and drop action. Call this when the user drops the content triggering copy.
- * operation.
- *
- * @param context
- */
- public static void logDragNDrop(Context context) {
- logCount(context, COUNT_DRAG_N_DROP);
- }
-
- /**
- * Logs a search. Call this when the search operation is finished.
- *
- * @param context
- */
- public static void logSearch(Context context) {
- logCount(context, COUNT_SEARCH);
- }
-
private static void logInterProviderFileOps(
Context context,
String histogram,
@@ -677,71 +624,12 @@
}
/**
- * Logs menu action that was selected by user.
+ * Logs the action that was started by user.
* @param context
- * @param id Resource id of the menu item.
+ * @param userAction
*/
- public static void logMenuAction(Context context, int id) {
- @MenuAction int menuAction = ACTION_MENU_OTHER;
- switch (id) {
- case R.id.menu_grid:
- menuAction = ACTION_MENU_GRID;
- break;
- case R.id.menu_list:
- menuAction = ACTION_MENU_LIST;
- break;
- case R.id.menu_sort:
- menuAction = ACTION_MENU_SORT;
- break;
- case R.id.menu_sort_name:
- menuAction = ACTION_MENU_SORT_NAME;
- break;
- case R.id.menu_sort_date:
- menuAction = ACTION_MENU_SORT_DATE;
- break;
- case R.id.menu_sort_size:
- menuAction = ACTION_MENU_SORT_SIZE;
- break;
- case R.id.menu_search:
- menuAction = ACTION_MENU_SEARCH;
- break;
- case R.id.menu_file_size:
- menuAction = ACTION_MENU_SHOW_SIZE;
- break;
- case R.id.menu_settings:
- menuAction = ACTION_MENU_SETTINGS;
- break;
- case R.id.menu_copy_to:
- menuAction = ACTION_MENU_COPY_TO;
- break;
- case R.id.menu_move_to:
- menuAction = ACTION_MENU_MOVE_TO;
- break;
- case R.id.menu_delete:
- menuAction = ACTION_MENU_DELETE;
- break;
- case R.id.menu_rename:
- menuAction = ACTION_MENU_RENAME;
- break;
- case R.id.menu_create_dir:
- menuAction = ACTION_MENU_CREATE_DIR;
- break;
- case R.id.menu_select_all:
- menuAction = ACTION_MENU_SELECT_ALL;
- break;
- case R.id.menu_share:
- menuAction = ACTION_MENU_SHARE;
- break;
- case R.id.menu_open:
- menuAction = ACTION_MENU_OPEN;
- break;
- case R.id.menu_advanced:
- menuAction = ACTION_MENU_ADVANCED;
- break;
- default:
- break;
- }
- logHistogram(context, COUNT_MENU_ACTION, menuAction);
+ public static void logUserAction(Context context, @UserAction int userAction) {
+ logHistogram(context, COUNT_USER_ACTION, userAction);
}
/**
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
index 945ed34..11b8891 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
@@ -185,9 +185,6 @@
if(mFullBar) {
Menu menu = mActionBar.getMenu();
menu.setGroupVisible(R.id.group_hide_when_searching, false);
- } else {
- // If search in full-bar mode it will be logged in FilesActivity#onOptionsItemSelected
- Metrics.logMenuAction(mActionBar.getContext(), R.id.menu_search);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 1c85a8a..bc2133e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -605,8 +605,6 @@
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- Metrics.logMenuAction(getContext(), item.getItemId());
-
Selection selection = mSelectionManager.getSelection(new Selection());
switch (item.getItemId()) {
@@ -674,6 +672,8 @@
}
private void openDocuments(final Selection selected) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
+
new GetDocumentsTask() {
@Override
void onDocumentsReady(List<DocumentInfo> docs) {
@@ -684,6 +684,8 @@
}
private void shareDocuments(final Selection selected) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SHARE);
+
new GetDocumentsTask() {
@Override
void onDocumentsReady(List<DocumentInfo> docs) {
@@ -765,6 +767,8 @@
}
private void deleteDocuments(final Selection selected) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_DELETE);
+
assert(!selected.isEmpty());
final DocumentInfo srcParent = getDisplayState().stack.peek();
@@ -815,6 +819,12 @@
}
private void transferDocuments(final Selection selected, final @OpType int mode) {
+ if(mode == FileOperationService.OPERATION_COPY) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_TO);
+ } else if (mode == FileOperationService.OPERATION_MOVE) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_MOVE_TO);
+ }
+
// Pop up a dialog to pick a destination. This is inadequate but works for now.
// TODO: Implement a picker that is to spec.
final Intent intent = new Intent(
@@ -861,6 +871,8 @@
}
private void renameDocuments(Selection selected) {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_RENAME);
+
// Batch renaming not supported
// Rename option is only available in menu when 1 document selected
assert(selected.size() == 1);
@@ -1020,6 +1032,8 @@
}
public void copySelectedToClipboard() {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_CLIPBOARD);
+
Selection selection = mSelectionManager.getSelection(new Selection());
if (!selection.isEmpty()) {
copySelectionToClipboard(selection);
@@ -1043,6 +1057,8 @@
}
public void pasteFromClipboard() {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_PASTE_CLIPBOARD);
+
copyFromClipboard();
getActivity().invalidateOptionsMenu();
}
@@ -1073,6 +1089,8 @@
}
public void selectAllFiles() {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL);
+
// Exclude disabled files
List<String> enabled = new ArrayList<String>();
for (String id : mAdapter.getModelIds()) {
@@ -1147,7 +1165,14 @@
if (Objects.equals(src, dst)) {
return false;
}
- Metrics.logDragNDrop(getContext());
+ // Recognize multi-window drag and drop based on the fact that localState is not
+ // carried between processes. It will stop working when the localsState behavior
+ // is changed. The info about window should be passed in the localState then.
+ // The localState could also be null for copying from Recents in single window
+ // mode, but Recents doesn't offer this functionality (no directories).
+ Metrics.logUserAction(getContext(),
+ src == null ? Metrics.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
+ : Metrics.USER_ACTION_DRAG_N_DROP);
copyFromClipData(event.getClipData(), dst);
return true;
}
@@ -1387,7 +1412,6 @@
// This has to be handled here instead of in a keyboard shortcut, because
// keyboard shortcuts all have to be modified with the 'Ctrl' key.
if (mSelectionManager.hasSelection()) {
- Metrics.logKeyboardAction(getContext(), Metrics.ACTION_KEYBOARD_DELETE);
deleteDocuments(mSelectionManager.getSelection());
}
// Always handle the key, even if there was nothing to delete. This is a
@@ -1674,8 +1698,9 @@
@Override
public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
if (!isAdded()) return;
+
if (mSearchMode) {
- Metrics.logSearch(getContext());
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SEARCH);
}
State state = getDisplayState();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index b80486d..1285b34 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -672,9 +672,9 @@
/**
* Used by CREATOR.
*/
- private Selection(String directoryKey, List<String> selection) {
+ private Selection(String directoryKey, Set<String> selection) {
mDirectoryKey = directoryKey;
- mSelection = new HashSet<String>(selection);
+ mSelection = selection;
mProvisionalSelection = new HashSet<String>();
}
@@ -887,7 +887,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mDirectoryKey);
- dest.writeList(new ArrayList<>(mSelection));
+ dest.writeStringList(new ArrayList<>(mSelection));
// We don't include provisional selection since it is
// typically coupled to some other runtime state (like a band).
}
@@ -901,9 +901,12 @@
@Override
public Selection createFromParcel(Parcel in, ClassLoader loader) {
- return new Selection(
- in.readString(),
- in.readArrayList(loader));
+ String directoryKey = in.readString();
+
+ ArrayList<String> selected = new ArrayList<>();
+ in.readStringList(selected);
+
+ return new Selection(directoryKey, new HashSet<String>(selected));
}
@Override
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
index 0763403..b77ff10 100644
--- a/packages/ExtServices/res/values/strings.xml
+++ b/packages/ExtServices/res/values/strings.xml
@@ -17,4 +17,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Android Services Library</string>
<string name="notification_ranker">Android Notification Ranking Service</string>
+ <string name="notification_ranker_autobundle_explanation">Auto-grouping updated by Ranking Service</string>
</resources>
diff --git a/packages/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
index 0b2b1a4..3ef2aea 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Ranker.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
@@ -16,16 +16,36 @@
package android.ext.services.notification;
+import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+
+import android.os.Bundle;
+import android.service.notification.Adjustment;
import android.service.notification.NotificationRankerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import android.ext.services.R;
/**
* Class that provides an updatable ranker module for the notification manager..
*/
public final class Ranker extends NotificationRankerService {
private static final String TAG = "RocketRanker";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static final int AUTOBUNDLE_AT_COUNT = 4;
+ private static final String AUTOBUNDLE_KEY = "ranker_bundle";
+
+ // Map of package : notification keys. Only contains notifications that are not bundled
+ // by the app (aka no group or sort key).
+ Map<String, LinkedHashSet<String>> mUnbundledNotifications;
@Override
public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance,
@@ -37,10 +57,146 @@
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
+ try {
+ List<String> notificationsToBundle = new ArrayList<>();
+ if (!sbn.isGroup()) {
+ // Not grouped by the app, add to the list of notifications for the app;
+ // send bundling update if app exceeds the autobundling limit.
+ synchronized (mUnbundledNotifications) {
+ LinkedHashSet<String> notificationsForPackage
+ = mUnbundledNotifications.get(sbn.getPackageName());
+ if (notificationsForPackage == null) {
+ notificationsForPackage = new LinkedHashSet<>();
+ }
+ if (notificationsForPackage.contains(sbn.getKey())) {
+ return;
+ }
+ notificationsForPackage.add(sbn.getKey());
+ mUnbundledNotifications.put(sbn.getPackageName(), notificationsForPackage);
+
+ if (notificationsForPackage.size() >= AUTOBUNDLE_AT_COUNT) {
+ // Autobundle all but the most recently posted (not updated) notification.
+ int count = 0;
+ for (String key : notificationsForPackage) {
+ if (count < notificationsForPackage.size() - 1) {
+ notificationsToBundle.add(key);
+ }
+ count++;
+ }
+ }
+ }
+ if (notificationsToBundle.size() > 0) {
+ adjustAutobundlingSummary(sbn.getPackageName(), notificationsToBundle.get(0),
+ true);
+ adjustNotificationBundling(sbn.getPackageName(), notificationsToBundle, true);
+ }
+ } else {
+ // Grouped, but not by us. Send updates to unautobundle, if we bundled it.
+ maybeUnbundle(sbn, false);
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Failure processing new notification", e);
+ }
+ }
+
+ @Override
+ public void onNotificationRemoved(StatusBarNotification sbn) {
+ try {
+ maybeUnbundle(sbn, true);
+ } catch (Exception e) {
+ Slog.e(TAG, "Error processing canceled notification", e);
+ }
+ }
+
+ /**
+ * Un-autobundles notifications that are now grouped by the app. Additionally cancels
+ * autobundling if the status change of this notification resulted in the loose notification
+ * count being under the limit.
+ */
+ private void maybeUnbundle(StatusBarNotification sbn, boolean notificationGone) {
+ List<String> notificationsToUnAutobundle = new ArrayList<>();
+ boolean removeSummary = false;
+ synchronized (mUnbundledNotifications) {
+ LinkedHashSet<String> notificationsForPackage
+ = mUnbundledNotifications.get(sbn.getPackageName());
+ if (notificationsForPackage == null || notificationsForPackage.size() == 0) {
+ return;
+ }
+ if (notificationsForPackage.remove(sbn.getKey())) {
+ if (!notificationGone) {
+ // Add the current notification to the unbundling list if it still exists.
+ notificationsToUnAutobundle.add(sbn.getKey());
+ }
+ // If the status change of this notification has brought the number of loose
+ // notifications back below the limit, remove the summary and un-autobundle.
+ if (notificationsForPackage.size() == AUTOBUNDLE_AT_COUNT - 1) {
+ removeSummary = true;
+ for (String key : notificationsForPackage) {
+ notificationsToUnAutobundle.add(key);
+ }
+ }
+ }
+ }
+ if (notificationsToUnAutobundle.size() > 0) {
+ if (removeSummary) {
+ adjustAutobundlingSummary(sbn.getPackageName(), null, false);
+ }
+ adjustNotificationBundling(sbn.getPackageName(), notificationsToUnAutobundle, false);
+ }
}
@Override
public void onListenerConnected() {
if (DEBUG) Log.i(TAG, "CONNECTED");
+ mUnbundledNotifications = new HashMap<>();
+ for (StatusBarNotification sbn : getActiveNotifications()) {
+ onNotificationPosted(sbn);
+ }
}
+
+ private void adjustAutobundlingSummary(String packageName, String key, boolean summaryNeeded) {
+ Bundle signals = new Bundle();
+ if (summaryNeeded) {
+ signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, true);
+ signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, AUTOBUNDLE_KEY);
+ } else {
+ signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false);
+ }
+ Adjustment adjustment = new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals,
+ getContext().getString(R.string.notification_ranker_autobundle_explanation), null);
+ if (DEBUG) {
+ Log.i(TAG, "Summary update for: " + packageName + " "
+ + (summaryNeeded ? "adding" : "removing"));
+ }
+ try {
+ adjustNotification(adjustment);
+ } catch (Exception e) {
+ Slog.e(TAG, "Adjustment failed", e);
+ }
+
+ }
+ private void adjustNotificationBundling(String packageName, List<String> keys, boolean bundle) {
+ List<Adjustment> adjustments = new ArrayList<>();
+ for (String key : keys) {
+ adjustments.add(createBundlingAdjustment(packageName, key, bundle));
+ if (DEBUG) Log.i(TAG, "Sending bundling adjustment for: " + key);
+ }
+ try {
+ adjustNotifications(adjustments);
+ } catch (Exception e) {
+ Slog.e(TAG, "Adjustments failed", e);
+ }
+ }
+
+ private Adjustment createBundlingAdjustment(String packageName, String key, boolean bundle) {
+ Bundle signals = new Bundle();
+ if (bundle) {
+ signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, AUTOBUNDLE_KEY);
+ } else {
+ signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, null);
+ }
+ return new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals,
+ getContext().getString(R.string.notification_ranker_autobundle_explanation), null);
+ }
+
}
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
index 442f29e..426d60f 100644
--- a/packages/Keyguard/res/values-ar/strings.xml
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -72,8 +72,8 @@
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"إدخال رمز رمز PIN المراد"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"تأكيد رمز رمز PIN المراد"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"جارٍ إلغاء تأمين شريحة SIM…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رمز PIN المكون من 4 إلى 8 أرقام."</string>
- <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"يجب أن يتضمن رمز PUK 8 أرقام أو أكثر."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رقم التعريف الشخصي المكون من ٤ إلى ٨ أرقام."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"يجب أن يتضمن رمز PUK ۸ أرقام أو أكثر."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى تعطيل شريحة SIM نهائيًا."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"لا يتطابق رمزا رمز PIN"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"محاولات النقش كثيرة جدًا"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
index 6eea81b..7dba545 100644
--- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -148,8 +148,9 @@
protected void onDraw(Canvas canvas) {
float totalDrawingWidth = getDrawingWidth();
float currentDrawPosition;
- if ((mGravity & Gravity.START) != 0) {
- if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
+ if ((mGravity & Gravity.RELATIVE_LAYOUT_DIRECTION) != 0
+ && getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
currentDrawPosition = getWidth() - getPaddingRight() - totalDrawingWidth;
} else {
currentDrawPosition = getPaddingLeft();
@@ -163,7 +164,7 @@
float yPosition =
(getHeight() - getPaddingBottom() - getPaddingTop()) / 2 + getPaddingTop();
canvas.clipRect(getPaddingLeft(), getPaddingTop(),
- getWidth()-getPaddingRight(), getHeight()-getPaddingBottom());
+ getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
float charLength = bounds.right - bounds.left;
for (int i = 0; i < length; i++) {
CharState charState = mTextChars.get(i);
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index eb96015..7c8806e 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 0
#define LOG_TAG "AppFuseJNI"
#include "utils/Log.h"
@@ -451,7 +450,7 @@
ScopedFd fd(static_cast<int>(jfd));
AppFuse appfuse(env, self);
- ALOGD("Start fuse loop.");
+ ALOGV("Start fuse loop.");
while (true) {
FuseRequest request;
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 246b95de..329afdd 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -33,7 +33,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
@@ -118,9 +117,10 @@
synchronized @Nullable LoaderTask getNextTaskOrReleaseBackgroundThread() {
Preconditions.checkState(mBackgroundThread != null);
- final LoaderTask task = mTaskList.findRunningTask();
- if (task != null) {
- return task;
+ for (final LoaderTask task : mTaskList) {
+ if (task.getState() == LoaderTask.STATE_LOADING) {
+ return task;
+ }
}
final Identifier identifier = mDatabase.getUnmappedDocumentsParent(mDevice.deviceId);
@@ -161,8 +161,21 @@
mTaskList.clearCompletedTasks();
}
- synchronized void clearTask(Identifier parentIdentifier) {
- mTaskList.clearTask(parentIdentifier);
+ /**
+ * Cancels the task for |parentIdentifier|.
+ *
+ * Task is removed from the cached list and it will create new task when |parentIdentifier|'s
+ * children are queried next.
+ */
+ void cancelTask(Identifier parentIdentifier) {
+ final LoaderTask task;
+ synchronized (this) {
+ task = mTaskList.findTask(parentIdentifier);
+ }
+ if (task != null) {
+ task.cancel();
+ mTaskList.remove(task);
+ }
}
/**
@@ -205,14 +218,6 @@
return null;
}
- LoaderTask findRunningTask() {
- for (int i = 0; i < size(); i++) {
- if (get(i).getState() == LoaderTask.STATE_LOADING)
- return get(i);
- }
- return null;
- }
-
void clearCompletedTasks() {
int i = 0;
while (i < size()) {
@@ -223,17 +228,6 @@
}
}
}
-
- void clearTask(Identifier parentIdentifier) {
- for (int i = 0; i < size(); i++) {
- final LoaderTask task = get(i);
- if (task.mIdentifier.mDeviceId == parentIdentifier.mDeviceId &&
- task.mIdentifier.mObjectHandle == parentIdentifier.mObjectHandle) {
- remove(i);
- return;
- }
- }
- }
}
/**
@@ -245,6 +239,7 @@
static final int STATE_LOADING = 1;
static final int STATE_COMPLETED = 2;
static final int STATE_ERROR = 3;
+ static final int STATE_CANCELLED = 4;
final MtpManager mManager;
final MtpDatabase mDatabase;
@@ -272,6 +267,7 @@
synchronized void loadObjectHandles() {
assert mState == STATE_START;
+ mPosition = 0;
int parentHandle = mIdentifier.mObjectHandle;
// Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
// getObjectHandles if we would like to obtain children under the root.
@@ -303,12 +299,10 @@
case STATE_ERROR:
throw mError;
}
-
final Cursor cursor =
mDatabase.queryChildDocuments(columnNames, mIdentifier.mDocumentId);
+ cursor.setExtras(extras);
cursor.setNotificationUri(resolver, createUri());
- cursor.respond(extras);
-
return cursor;
}
@@ -374,6 +368,10 @@
}
}
synchronized (this) {
+ // Check if the task is cancelled or not.
+ if (mState != STATE_LOADING) {
+ return;
+ }
try {
mDatabase.getMapper().putChildDocuments(
mIdentifier.mDeviceId,
@@ -403,6 +401,14 @@
}
/**
+ * Cancels the task.
+ */
+ synchronized void cancel() {
+ mDatabase.getMapper().cancelAddingDocuments(mIdentifier.mDocumentId);
+ mState = STATE_CANCELLED;
+ }
+
+ /**
* Returns a state of the task.
*/
int getState() {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
index adc71ae..63f18f3 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
@@ -363,6 +363,41 @@
}
/**
+ * Cancels adding documents.
+ * @param parentId
+ */
+ void cancelAddingDocuments(@Nullable String parentId) {
+ final String selection;
+ final String[] args;
+ if (parentId != null) {
+ selection = COLUMN_PARENT_DOCUMENT_ID + " = ?";
+ args = strings(parentId);
+ } else {
+ selection = COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
+ args = EMPTY_ARGS;
+ }
+
+ final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+ database.beginTransaction();
+ try {
+ if (!mInMappingIds.contains(parentId)) {
+ return;
+ }
+ mInMappingIds.remove(parentId);
+ final ContentValues values = new ContentValues();
+ values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+ mDatabase.getSQLiteDatabase().update(
+ TABLE_DOCUMENTS,
+ values,
+ selection + " AND " + COLUMN_ROW_STATE + " = ?",
+ DatabaseUtils.appendSelectionArgs(args, strings(ROW_STATE_INVALIDATED)));
+ database.setTransactionSuccessful();
+ } finally {
+ database.endTransaction();
+ }
+ }
+
+ /**
* Queries candidate for each mappingKey, and returns the first cursor that includes a
* candidate.
*
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 50781bf..1823711 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -308,7 +308,7 @@
final Identifier parentIdentifier = mDatabase.getParentIdentifier(documentId);
mMtpManager.deleteDocument(identifier.mDeviceId, identifier.mObjectHandle);
mDatabase.deleteDocument(documentId);
- getDocumentLoader(parentIdentifier).clearTask(parentIdentifier);
+ getDocumentLoader(parentIdentifier).cancelTask(parentIdentifier);
notifyChildDocumentsChange(parentIdentifier.mDocumentId);
if (parentIdentifier.mDocumentType == MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE) {
// If the parent is storage, the object might be appeared as child of device because
@@ -402,7 +402,7 @@
final String documentId = mDatabase.putNewDocument(
parentId.mDeviceId, parentDocumentId, record.operationsSupported,
infoWithHandle, 0l);
- getDocumentLoader(parentId).clearTask(parentId);
+ getDocumentLoader(parentId).cancelTask(parentId);
notifyChildDocumentsChange(parentDocumentId);
return documentId;
} catch (FileNotFoundException | RuntimeException error) {
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index 45f89e4..60dd7e1 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -21,6 +21,7 @@
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
@@ -28,6 +29,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
@MediumTest
public class DocumentLoaderTest extends AndroidTestCase {
@@ -141,6 +143,33 @@
}
}
+ public void testCancelTask() throws IOException, InterruptedException {
+ setUpDocument(mManager,
+ DocumentLoader.NUM_INITIAL_ENTRIES + DocumentLoader.NUM_LOADING_ENTRIES + 1);
+
+ // Block the first iteration in the background thread.
+ mManager.blockDocument(
+ 0, DocumentLoader.NUM_INITIAL_ENTRIES + 1);
+ setUpLoader();
+ try (final Cursor cursor = mLoader.queryChildDocuments(
+ MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION, mParentIdentifier)) {
+ assertTrue(cursor.getExtras().getBoolean(DocumentsContract.EXTRA_LOADING));
+ }
+ Thread.sleep(DocumentLoader.NOTIFY_PERIOD_MS);
+
+ // Clear task while the first iteration is being blocked.
+ mManager.unblockDocument(
+ 0, DocumentLoader.NUM_INITIAL_ENTRIES + 1);
+ mLoader.cancelTask(mParentIdentifier);
+
+ Thread.sleep(DocumentLoader.NOTIFY_PERIOD_MS * 2);
+
+ // Check if it's OK to query invalidated task.
+ try (final Cursor cursor = mLoader.queryChildDocuments(
+ MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION, mParentIdentifier)) {
+ }
+ }
+
private void setUpLoader() {
mLoader = new DocumentLoader(
new MtpDeviceRecord(
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index 1208298..b9d1902 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -30,7 +30,7 @@
<string name="destination_default_text" msgid="5422708056807065710">"اختر طابعة"</string>
<string name="template_all_pages" msgid="3322235982020148762">"جميع الصفحات وعددها <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="template_page_range" msgid="428638530038286328">"النطاق <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
- <string name="pages_range_example" msgid="8558694453556945172">"على سبيل المثال، 1—5،8،11—13"</string>
+ <string name="pages_range_example" msgid="8558694453556945172">"مثلاً، ۱—۵،۹،۷—۱۰"</string>
<string name="print_preview" msgid="8010217796057763343">"معاينة قبل الطباعة"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"تثبيت برنامج عرض PDF للمعاينة"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"تعطّل تطبيق الطباعة"</string>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index c44f0d0..f32cd13 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> oor"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – sowat <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol op WS"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol oor USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol vanaf draadloos"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laai tans op WS"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Laai tans"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laai tans oor USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Laai tans"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laai tans draadloos"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Laai tans"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Laai nie"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index cd05135..1bb27e2 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ገደማ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> እስከሚሞላ ድረስ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በኤሲ ላይ እስከሚሞላ ድረስ"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በዩኤስቢ ላይ እስከሚሞላ ድረስ"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በገመድ አልባ ላይ እስከሚሞላ ድረስ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"በኤሲ ሃይል በመሙላት ላይ"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"በዩኤስቢ ሃይል በመሙላት ላይ"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"በገመድ አልባ ሃይል በመሙላት ላይ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ባትሪ እየሞላ አይደለም"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል እየሞላ አይደለም"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index b3f55eb..0f6b315 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال باستخدام التيار المتردد"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال عبر USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال بالشحن اللاسلكي"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"شحن"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"جارٍ الشحن بتيار متردد"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"جارٍ الشحن عبر USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"جارٍ الشحن لاسلكيًا"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"جارٍ الشحن"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"لا يتم الشحن"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index 9a099af..5b2214a 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> dolana qədər"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC üzərindən dolana qədər"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB üzərindən dolana qədər"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> naqilsiz üzərindən dolana qədər"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Dəyişən cərəyanda qidalanır"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Qidalanır"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB üzərindən qidalanır"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Qidalanır"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Naqilsiz qidalanır"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Qidalanır"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Doldurulmur"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 85b6ac2..e361efd 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Preostalo vreme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"Preostalo je <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni punjačem"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni preko USB-a"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni bežično"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje preko punjača"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Puni se"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Puni se"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Puni se"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml
index c8098ec..05c6d9af 100644
--- a/packages/SettingsLib/res/values-be-rBY/strings.xml
+++ b/packages/SettingsLib/res/values-be-rBY/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэтая функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося прыблізна <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі ад сеткі пер. току"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі па USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўн. зарадкі бесправадным шляхам"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зар. ад сеткі пер. току"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарадка"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарадка па USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарадка"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бесправадная зарадка"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарадка"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не зараджаецца"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 35b24bf..f596b04 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Прибл. оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – приблизително оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане при променлив ток"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане през USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно безжично зареждане"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зареждане при AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарежда се"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зареждане през USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарежда се"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично зареждане"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарежда се"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не се зарежда"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 14c2c95..f691278 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index f9c7fcad..e4bd011 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo vreme je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do kraja punjenja na el. napajanju"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije preko USB-a"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije bežičnim punjenjem"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Puni se na punjaču"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Punjenje"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Punjenje"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Punjenje"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index a070740..ba19e30 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 040c9f0..03208bf 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g> (přibližně)"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití ze zásuvky"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití přes USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití bezdrátově"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjení z adaptéru"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Nabíjení"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjení přes USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Nabíjení"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrátové nabíjení"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Nabíjení"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíjí se"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index ddad673..d58fe62d 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 514228f..dc38dae 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion. Dies kann sich auf die Leistung auswirken."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g> verbleibend"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei Stromanschluss voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – über USB voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei kabellosem Laden voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laden über Netzteil"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Ladevorgang"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laden über USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Ladevorgang"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kabelloses Laden"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Ladevorgang"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Wird nicht geladen"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 8df693a..87d5a98 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένει/ουν <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση με φορτιστή AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση μέσω USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη ασύρματη φόρτιση"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Φόρτιση με AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Φόρτιση"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Φόρτιση μέσω USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Φόρτιση"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ασύρματη φόρτιση"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Φόρτιση"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Δεν φορτίζει"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 466291a..fe490a2 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Charging"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Charging"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 466291a..fe490a2 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Charging"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Charging"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 466291a..fe490a2 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Charging"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Charging"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 9bc2cf4..03d9a95 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Falta <xliff:g id="TIME">%1$s</xliff:g> aproximadamente"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: alrededor de <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga inalámbrica"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carga en CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Cargando"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carga con USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Cargando"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carga inalámbrica"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Cargando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando."</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ec0cafe..4aaad05 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 29a1aea..85261129 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – jäänud on umbes <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (vahelduvvool)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (USB)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (juhtmeta laad.)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laad. vahelduvv.-v."</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Laadimine"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laadimine USB kaudu"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Laadimine"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Juhtmevaba laadimine"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Laadimine"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ei lae"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 4f55e35..2cc73bb 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> inguru guztiz kargatu arte"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> inguru. <xliff:g id="TIME">%2$s</xliff:g> geratzen d(ir)a"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> korrontearen bidez guztiz kargatu arte"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB bidez guztiz kargatu arte"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> haririk gabe guztiz kargatu arte"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzea"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"KA bidez kargatzen"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Kargatzen"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB bidez kargatzen"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Kargatzen"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hari gabe kargatzen"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Kargatzen"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ez da kargatzen ari"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index e9d63fd..3fdb474 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی مانده"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی مانده"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل با جریان متناوب"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل از طریق USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل بهطور بیسیم"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"شارژ با جریان متناوب"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"درحال شارژ شدن"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"شارژ از طریق USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"درحال شارژ شدن"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"شارژ به صورت بیسیم"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"درحال شارژ شدن"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"شارژ نمیشود"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمیشود"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 5531d27..b70d6a0 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (laturilataus)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (USB-lataus)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (WiFi-lataus)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laturilataus"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Ladataan"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-lataus"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Ladataan"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Langaton lataus"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Ladataan"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ei laturissa"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index df6bdc6..cc8e7f6 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut toucher les performances."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> %% – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (charge complète sur c.a. dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% par USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% avec chargeur sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge (c.a.)"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Charge en cours..."</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge par USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Charge en cours..."</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Charge en cours..."</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"N\'est pas en charge"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ee40b2a..a1b85a0 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>."</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g> environ"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sur secteur dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% via USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge sur secteur"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"En charge"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"En charge"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"En charge"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Pas en charge"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index 4a0451e..1bdddd9 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Duración aproximada de <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - faltan aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga co modo sen fíos"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Cargando con CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Cargando"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Cargando por USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Cargando"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Cargando sen fíos"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Cargando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Non se está cargando"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index becda28..eafb8b1 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"અંદાજે. <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - આશરે <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"સંપૂર્ણ થવામાં <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>, AC પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>, USB પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> વાયરલેસ દ્વારા પૂર્ણ થાય ત્યાં સુધી"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC પર ચાર્જિંગ"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB થી ચાર્જિંગ"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"વાયરલેસથી ચાર્જિંગ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ચાર્જ થઈ રહ્યું નથી"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 6dffdd9..b008e1f 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी होने तक"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC पर पूरी होने तक"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB पर पूरी होने तक"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेस से पूरी होने तक"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC से चार्ज हो रही"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"चार्ज हो रहा है"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB पर चार्ज हो रही"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"चार्ज हो रहा है"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस रूप से चार्ज हो रही"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"चार्ज हो रहा है"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज नहीं हो रही है"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 1edb015..6ba366c 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 060599c..b10f5be 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -331,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 63c4336..2021520 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել աշխատանքի վրա:"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնաց մոտավորապես <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը հոսանքից"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը USB-ով"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը անլար ցանցից"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Լիցքավորում AC-ով"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Լիցքավորում"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Լիցքավորում USB-ով"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Լիցքավորում"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Անլար լիցքավորում"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Լիցքավորում"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Չի լիցքավորվում"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index c86c768..c02e3fa 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira tersisa <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tersisa"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira tersisa. <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tersisa"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh pada AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh melalui USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh dari nirkabel"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengisi daya pada AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Mengisi daya"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Isi daya lewat USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Mengisi daya"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Isi daya nirkabel"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Mengisi daya"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengisi daya"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 1fc0dc0..bdf5a35 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu með hleðslutæki"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu í gegnum USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu þráðlaust"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Hleðslutæki tengt"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Í hleðslu"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Hleður um USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Í hleðslu"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hleður þráðlaust"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Í hleðslu"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ekki í hleðslu"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 78cd29b..43c41d7 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Circa <xliff:g id="TIME">%1$s</xliff:g> rimanenti"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g> circa"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lla carica completa con wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"In carica tramite CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"In carica"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"In carica tramite USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"In carica"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"In carica, wireless"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"In carica"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Non in carica"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 16e0f44d..e25d218 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"נשארו <xliff:g id="TIME">%1$s</xliff:g> בערך"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> בקירוב עד לסיום"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - נותרו <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בזרם חילופין"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי ב-USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בטעינה אלחוטית"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"טוען בזרם חילופין"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"בטעינה"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"טוען ב-USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"בטעינה"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"טוען באופן אלחוטי"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"בטעינה"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index ce405df..ac239fe 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g>(残り時間)"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約<xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>(残り時間)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(AC)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(USB)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(ワイヤレス)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACで充電しています"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"充電しています"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBで充電しています"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"充電しています"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"無線で充電しています"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"充電しています"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"充電していません"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"充電していません"</string>
<!-- String.format failed for translation -->
@@ -342,4 +333,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 20a1d2a..883d637 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს შესრულებაზე."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"დარჩენილია დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"დაახლ. <xliff:g id="LEVEL">%1$s</xliff:g> დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> სრულ დატენვამდე"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ელკვებით სრულ დატენვამდე"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB-თი სრულ დატენვამდე"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> უსადენოდან სრულ დატენვამდე"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"დატენვა ელკვებაზე"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"იტენება"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"დატენვა USB-ზე"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"იტენება"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"დატენვა უსადენოდ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"იტენება"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"არ იტენება"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index e71c8d0..3270170 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - айнымалы токпен толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB арқылы толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - сымсыз толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Айнымалы токпен зар."</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарядталуда"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB арқылы зарядтау"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарядталуда"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Сымсыз зарядтау"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарядталуда"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Зарядталу орындалып жатқан жоқ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 687b71b..9d6d3475 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"លក្ខណៈនេះគឺជាការពិសោធន៍ ហើយអាចប៉ះពាល់ការអនុវត្ត។"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"នៅសល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញរចន្តឆ្លាស់"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញតាមយូអេសប៊ី"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញពីឥតខ្សែ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"មិនស្គាល់"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូលថ្ម"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"បញ្ចូលថ្មតាម AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"កំពុងសាកថ្ម"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"បញ្ចូលថ្មតាមយូអេសប៊ី"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"កំពុងសាកថ្ម"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"បញ្ចូលថ្មដោយឥតខ្សែ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"កំពុងសាកថ្ម"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"មិនកំពុងបញ្ចូលថ្ម"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិនបញ្ចូលថ្ម"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index 713d9b3..dc35604 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"ಸುಮಾರು <xliff:g id="LEVEL">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ನಲ್ಲಿ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ಮೂಲಕ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ವೈರ್ಲೆಸ್ನಿಂದ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಜ್ಞಾತ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ನಲ್ಲಿ ಚಾರ್ಜ್"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ಮೂಲಕ ಚಾರ್ಜ್"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ನಿಸ್ತಂತುವಾಗಿ ಚಾರ್ಜ್"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 348141e..fc8f478 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 대략 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(AC 전원)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(USB)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(무선)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"충전 중(AC 전원)"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"충전 중"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"충전 중(USB)"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"충전 중"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"충전 중(무선)"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"충전 중"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"충전 안함"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 2016f04..8b0119e 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> калды"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> калды"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - болжол менен <xliff:g id="TIME">%2$s</xliff:g> саат калды"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> толгончо"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC аркылуу толгончо"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB аркылуу толгончо"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> зымсыз кубаттоо аркылуу толгончо"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ӨА кубатталууда"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Кубатталууда"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB\'ден кубатталууда"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Кубатталууда"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Зымсыз кубатталууда"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Кубатталууда"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Кубат алган жок"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 7e6db5e..3532137 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ຄຸນສົມບັດນີ້ກຳລັງຢູ່ໃນການທົດລອງແລະອາດມີຜົນຕໍ່ປະສິດທິພາບ."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກດ້ວຍໄຟ AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກດ້ວຍ USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກແບບໄຮ້ສາຍ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ກຳລັງສາກຜ່ານໝໍ້ໄຟ"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"ກຳລັງສາກຜ່ານ USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ກຳລັງສາກໄຮ້ສາຍ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ບໍ່ໄດ້ສາກໄຟ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
@@ -340,4 +331,5 @@
<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>
+ <string name="help_feedback_label" msgid="6815040660801785649">"ຊ່ວຍເຫຼືອ & ຄຳຕິຊົມ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index d49876e..02739f3 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naud. kint. sr."</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naudojant USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo belaid. ryš."</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Įkr. naud. kint. sr."</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Įkraunama"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Įkraunama naud. USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Įkraunama"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Įkraunama be laidų"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Įkraunama"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nekraunama"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 6cd9cfd5..54c75ff 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> — aptuvenais atlikušais laiks: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlicis: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai maiņstrāvas uzlādei"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai USB uzlādei"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai bezvadu uzlādei"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Maiņstrāvas uzlāde"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Notiek uzlāde"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB uzlāde"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Notiek uzlāde"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezvadu uzlāde"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Notiek uzlāde"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenotiek uzlāde"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index f8f65ec..8f11118 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостанува приближно <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна на AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна преку USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна, безжично"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Полнење на струја"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Се полни"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Полнење преку УСБ"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Се полни"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично полнење"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Се полни"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не се полни"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Целосна"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 7350b7f..f39b109 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - വയർലെസ് വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-യിൽ ചാർജ്ജുചെയ്യുന്നു"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-യിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"വയർലെസ്സ് കണക്ഷനിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index 7eeae06..8b005d1 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"АС-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"USB-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"утасгүй цэнэглэгчээр дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-р цэнэглэж байна"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-р цэнэглэж байна"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Кабльгүйгээр цэнэглэж байна"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Цэнэглэж байна"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Цэнэглэхгүй байна"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 0521ba1..9296a32 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण होण्यात"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC वरून पूर्ण होण्यात"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB वरून पूर्ण होण्यात"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसवरून पूर्ण होण्यात"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC वर चार्ज करीत आहे"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB वरून चार्ज करीत आहे"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस वरून चार्ज करीत आहे"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"चार्ज होत आहे"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज होत नाही"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index a8be0e5..60a5298 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira. <xliff:g id="TIME">%2$s</xliff:g> yang tinggal"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh di AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh melalui USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh dari wayarles"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengecas pada AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Mengecas"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Mengecas melalui USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Mengecas"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Mengecas tanpa wayar"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Mengecas"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengecas"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 220deff..e512aac 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဒီအင်္ဂါရပ်မှာ စမ်းသပ်မှု ဖြစ်၍ လုပ်ကိုင်မှုကို အကျိုးသက်ရောက်နိုင်သည်။"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ခန့်မှန်းခြေ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ခန့်မှန်းခြေ။ <xliff:g id="TIME">%2$s</xliff:g> ကျန်ရှိနေ"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> အပြည့်အထိ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လျှပ်စစ်ဖြင့် အပြည့်အထိ"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ဖြင့် အပြည့်အထိ"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကြိုးမဲ့ဖြင့် အပြည့်အထိ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"အကြောင်းအရာ မသိရှိ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"လျှပ်စစ်ဖြင့် အားသွင်းနေ"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"အားသွင်းနေသည်"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBဖြင့် အားသွင်းနေ"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"အားသွင်းနေသည်"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ကြိုးမဲ့ အားသွင်းနေ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"အားသွင်းနေသည်"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"အားသွင်းမနေပါ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index a1407ac..3d01254 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funksjonen er eksperimentell og kan påvirke ytelsen."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> igjen"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> med vekselstrøm"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via trådløs lading"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Lader via strømuttak"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Lader"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Lader via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Lader"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Lader trådløst"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Lader"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Lader ikke"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 83e2e74..f2e6ea4 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग। <xliff:g id="TIME">%2$s</xliff:g> बायाँ"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण नभए सम्म"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC मा पूर्ण नभए सम्म"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB मा पूर्ण नभए सम्म"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसबाट पूर्ण नभए सम्म"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC मा चार्ज गर्दै"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB मा चार्ज गर्दै"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"बिना तार चार्ज गर्दै"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"चार्ज हुँदै"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज भइरहेको छैन"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 55017d8..4ae1fb0b 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ca. <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via wisselstroom"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via draadloos"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Opladen via netvoeding"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Opladen"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Opladen via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Opladen"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Draadloos opladen"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Opladen"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Wordt niet opgeladen"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index eb1eaac..5596cbc 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਵਾਇਰਲੈਸ ਤੋਂ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ਤੇ ਚਾਰਜਿੰਗ"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ਤੇ ਚਾਰਜਿੰਗ"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ਵਾਇਰਲੈਸ ਤੌਰ ਤੇ ਚਾਰਜਿੰਗ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 1e56cfd..81ebed8 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Pozostało około <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało ok. <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania z gniazdka"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania przez USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania bezprzewodowo"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Ładowanie zasilaczem"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Ładowanie"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Ładowanie przez USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Ładowanie"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ład. bezprzewodowe"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Ładowanie"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nie podłączony"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 93f333a..5bfbc2d 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -115,7 +115,7 @@
<string name="tts_engine_network_required" msgid="1190837151485314743">"Este idioma requer uma conexão de rede ativa para a conversão de texto em voz."</string>
<string name="tts_default_sample_string" msgid="4040835213373086322">"Este é um exemplo de sintetização de voz."</string>
<string name="tts_status_title" msgid="7268566550242584413">"Status de idioma padrão"</string>
- <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportada"</string>
+ <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportado"</string>
<string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requer conexão de rede"</string>
<string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> não é suportado"</string>
<string name="tts_status_checking" msgid="5339150797940483592">"Verificando..."</string>
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Carregando"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Carregando"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Carregando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index dda00fe..244e27d 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) aprox. <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até ficar compl. por rede s/ fios"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"A carregar por CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"A carregar"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"A carregar por USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"A carregar"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"A carregar sem fios"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"A carregar"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está a carregar"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 93f333a..5bfbc2d 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -115,7 +115,7 @@
<string name="tts_engine_network_required" msgid="1190837151485314743">"Este idioma requer uma conexão de rede ativa para a conversão de texto em voz."</string>
<string name="tts_default_sample_string" msgid="4040835213373086322">"Este é um exemplo de sintetização de voz."</string>
<string name="tts_status_title" msgid="7268566550242584413">"Status de idioma padrão"</string>
- <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportada"</string>
+ <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportado"</string>
<string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requer conexão de rede"</string>
<string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> não é suportado"</string>
<string name="tts_status_checking" msgid="5339150797940483592">"Verificando..."</string>
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Carregando"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Carregando"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Carregando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 3c46d41..668d19c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă la c.a."</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă prin USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Se încarcă la C.A."</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Se încarcă"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Se încarcă prin USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Se încarcă"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Se încarcă fără fir"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Se încarcă"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nu se încarcă"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index f4929de..a9d4abc 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось около <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>, осталось: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (от сети)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (через USB)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (беспроводная)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зарядка от сети"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарядка"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарядка через USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарядка"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Беспроводная зарядка"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарядка"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряжается"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 99f018b..90b82f1 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්රියාකාරිත්වයට බලපෑ හැක."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"දළ වශයෙන් <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරිය"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආසන්න <xliff:g id="TIME">%2$s</xliff:g> වම"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඉතිරි <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"AC හි <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"USB හරහ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"රේඩියෝව වෙතින් <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණ වන තෙක්"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC හි ආරෝපණය වෙමින්"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB හරහා ආරෝපණය වෙමින්"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"රැහැන් රහිතව ආරෝපණය වෙමින්"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ආරෝපණය නොවේ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 4dffdef..dbb4dde 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zostáva cca. <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia zo zásuvky"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia cez USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia bezdrôtovo"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjanie zo zásuvky"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Nabíjanie"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjanie cez USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Nabíjanie"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrôtové nabíjanie"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Nabíjanie"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíja sa"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 676a3ab..54e8636 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek napajalnika"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek USB-ja"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek brezž. pol."</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Polnj. prek iz. toka"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Polnjenje"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Polnj. prek USB-ja"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Polnjenje"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Brezžično polnjenje"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Polnjenje"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Se ne polni"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index c18e639..ecc10f4 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të jetë e plotë"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet në AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet me USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet nga lidhja pa tel"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Po ngarkohet në AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Po ngarkohet"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Po ngarkohet me USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Po ngarkohet"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Po ngarkohet me valë"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Po ngarkohet"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nuk po ngarkohet"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index c0791fc..5330893 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на перформансе."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостало око <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни пуњачем"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни преко USB-а"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни бежично"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Пуњење преко пуњача"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Пуни се"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Пуњење преко USB-а"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Пуни се"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бежично пуњење"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Пуни се"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не пуни се"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 60c42a5..0a054578 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca <xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via laddare"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via trådlös laddning"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laddas via adapter"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Laddar"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laddas via USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Laddar"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laddas trådlöst"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Laddar"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Laddar inte"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 5de7686..20d3cc8 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takriban <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">%1$s</xliff:g> - Zimesalia <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>%% - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa isiyotumia waya"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Inachaji kupitia AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Inachaji"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Inachaji kupitia USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Inachaji"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Inachaji bila kutumia waya"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Inachaji"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Haichaji"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index a5f04d0..304680b 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"தோராயமாக <xliff:g id="TIME">%1$s</xliff:g> உள்ளது"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"தோராயம்: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> உள்ளது"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"முழு சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"முழு AC சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"முழு USB சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"முழு வயர்லெஸ் சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஏற்றப்படுகிறது"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC மூலம் சார்ஜாகிறது"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"சார்ஜ் ஏறுகிறது"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB மூலம் சார்ஜாகிறது"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"சார்ஜ் ஏறுகிறது"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"வயர்லெஸில் சார்ஜாகிறது"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"சார்ஜ் ஏறுகிறது"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"சார்ஜ் செய்யப்படவில்லை"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index fe40766..b6457c7 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ACలో పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ద్వారా పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - వైర్లెస్ నుండి పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACలో ఛార్జ్ అవుతోంది"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ద్వారా ఛార్జ్ అవుతోంది"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"వైర్లెస్ ద్వారా ఛార్జ్ అవుతోంది"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ఛార్జ్ కావడం లేదు"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index c58692f..345da0f 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"เหลืออีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลือเวลา <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีก <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็ม"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่านระบบไร้สาย"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"กำลังชาร์จไฟ AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"กำลังชาร์จผ่าน USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"กำลังชาร์จแบบไร้สาย"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"กำลังชาร์จ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ไม่ได้ชาร์จ"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 093256c..f820ab8 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa pagganap."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> na lang ang natitira"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> pa"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> pa"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno mula sa wireless"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nagcha-charge sa AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Nagcha-charge"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nagcha-charge sa USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Nagcha-charge"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Wireless nag-charge"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Nagcha-charge"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Hindi nagcha-charge"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 1947d39..9766dea 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - prize takılı, tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB üzerinden şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - kablosuzdan tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ile şarj oluyor"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Şarj oluyor"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ile şarj oluyor"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Şarj oluyor"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kablosuz şarj oluyor"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Şarj oluyor"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Şarj olmuyor"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 0ed6cc0..831484f 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Залишилося приблизно <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилось близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилося <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження з розетки"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження через USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного з бездротового зарядження"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядж-ся"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Заряджання з розетки"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Заряджається"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Заряджання через USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Заряджається"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Заряджання без дроту"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Заряджається"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряджається"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index 99a0f2be..15277ae 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریبا <xliff:g id="TIME">%1$s</xliff:g> باقی ہیں"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریبا <xliff:g id="TIME">%2$s</xliff:g> باقی"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پورا ہونے تک"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC پر پورا ہونے تک"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB پر پورا ہونے تک"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> وائرلیس سے پورا ہونے تک"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC پر چارج ہو رہی ہے"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"چارجنگ ہو رہی ہے"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB پر چارج ہورہی ہے"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"چارجنگ ہو رہی ہے"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"وائرلیس چارجنگ"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"چارجنگ ہو رہی ہے"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"چارج نہیں ہو رہا ہے"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index b9c0243..374e7fc 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, to‘lguncha"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, o‘zgaruvchan tok orqali to‘lguncha"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, USB orqali to‘lguncha"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, simsiz quvvatlash orqali to‘lguncha"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Quvvat olmoqda (AC)"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Quvvat olmoqda (USB)"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Simsiz quvvat olmoqda"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Quvvat olmoqda"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvat olmayapti"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 0c3dc89..1c86175 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn lại <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy khi cắm vào nguồn AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy qua USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy từ không dây"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Sạc trên AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Đang sạc"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Sạc qua USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Đang sạc"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Sạc không dây"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Đang sạc"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Hiện không sạc"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 2b8ce65..d0dc925 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"此功能为实验性功能,可能会影响性能。"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用大约<xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(交流电充电)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(USB充电)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(无线充电)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在通过交流电源充电"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"正在充电"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在通过USB充电"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"正在充电"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在无线充电"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"正在充电"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"未在充电"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 8dd0417..9bb0a4c 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"尚餘大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過插頭充電)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過 USB 充電)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (無線充電)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 充電"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"正在充電"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"正在充電"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"正在充電"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index dd59954..bf3880b 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"還剩大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大約還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (AC)"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (USB)"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (無線充電)"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 變壓器充電"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"充電中"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"充電中"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"充電中"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 610cac4..7953372 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -296,35 +296,26 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Cishe ngu-<xliff:g id="TIME">%1$s</xliff:g> osele"</string>
- <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) -->
- <skip />
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> esisele"</string>
<string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - isilinganiso esingu-<xliff:g id="TIME">%2$s</xliff:g> esisele"</string>
- <!-- no translation found for power_discharging_duration_short (4192244429001842403) -->
- <skip />
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale"</string>
- <!-- no translation found for power_charging_duration_short (1098603958472207920) -->
- <skip />
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ku-AC"</string>
- <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) -->
- <skip />
+ <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ngaphezulu kwe-USB"</string>
- <!-- no translation found for power_charging_duration_usb_short (941854728040426399) -->
- <skip />
+ <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale kusukela kokungenantambo"</string>
- <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) -->
- <skip />
+ <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
<string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Iyashaja ku-AC"</string>
- <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) -->
- <skip />
+ <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Iyashaja"</string>
<string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Iyashaja ngaphezulu kwe-USB"</string>
- <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) -->
- <skip />
+ <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Iyashaja"</string>
<string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Iyashaja ngaphandle kwentambo"</string>
- <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) -->
- <skip />
+ <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Iyashaja"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ayishaji"</string>
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
@@ -340,4 +331,6 @@
<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>
+ <!-- no translation found for help_feedback_label (6815040660801785649) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a560e3c..084acac 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -850,5 +850,7 @@
<!-- Description for a custom screen zoom level. This shows the requested display
density in raw pixels per inch rather than using a relative description. [CHAR LIMIT=24] -->
<string name="screen_zoom_summary_custom">Custom (<xliff:g id="densityDpi" example="160">%d</xliff:g>)</string>
+ <!-- Label for Help and feedback menu item -->
+ <string name="help_feedback_label">Help & feedback</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java
new file mode 100644
index 0000000..320cd58
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources.Theme;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
+
+import java.net.URISyntaxException;
+import java.util.Locale;
+
+/**
+ * Functions to easily prepare contextual help menu option items with an intent that opens up the
+ * browser to a particular URL, while taking into account the preferred language and app version.
+ */
+public class HelpUtils {
+ private final static String TAG = HelpUtils.class.getSimpleName();
+
+ private static final int MENU_HELP = Menu.FIRST + 100;
+
+ /**
+ * Help URL query parameter key for the preferred language.
+ */
+ private final static String PARAM_LANGUAGE_CODE = "hl";
+
+ /**
+ * Help URL query parameter key for the app version.
+ */
+ private final static String PARAM_VERSION = "version";
+
+ // Constants for help intents.
+ private static final String EXTRA_CONTEXT = "EXTRA_CONTEXT";
+ private static final String EXTRA_THEME = "EXTRA_THEME";
+ private static final String EXTRA_PRIMARY_COLOR = "EXTRA_PRIMARY_COLOR";
+ private static final String EXTRA_BACKUP_URI = "EXTRA_BACKUP_URI";
+
+ /**
+ * Cached version code to prevent repeated calls to the package manager.
+ */
+ private static String sCachedVersionCode = null;
+
+ /** Static helper that is not instantiable*/
+ private HelpUtils() { }
+
+ public static boolean prepareHelpMenuItem(Activity activity, Menu menu, String helpUri,
+ String backupContext) {
+ MenuItem helpItem = menu.add(0, MENU_HELP, 0, R.string.help_feedback_label);
+ return prepareHelpMenuItem(activity, helpItem, helpUri, backupContext);
+ }
+
+ public static boolean prepareHelpMenuItem(Activity activity, Menu menu, int helpUriResource,
+ String backupContext) {
+ MenuItem helpItem = menu.add(0, MENU_HELP, 0, R.string.help_feedback_label);
+ return prepareHelpMenuItem(activity, helpItem, activity.getString(helpUriResource),
+ backupContext);
+ }
+
+ /**
+ * Prepares the help menu item by doing the following.
+ * - If the helpUrlString is empty or null, the help menu item is made invisible.
+ * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
+ * item to view the URL.
+ *
+ * @return returns whether the help menu item has been made visible.
+ */
+ public static boolean prepareHelpMenuItem(final Activity activity, MenuItem helpMenuItem,
+ String helpUriString, String backupContext) {
+ if (TextUtils.isEmpty(helpUriString)) {
+ // The help url string is empty or null, so set the help menu item to be invisible.
+ helpMenuItem.setVisible(false);
+
+ // return that the help menu item is not visible (i.e. false)
+ return false;
+ } else {
+ final Intent intent = getHelpIntent(activity, helpUriString, backupContext);
+
+ // Set the intent to the help menu item, show the help menu item in the overflow
+ // menu, and make it visible.
+ if (intent != null) {
+ helpMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ try {
+ activity.startActivityForResult(intent, 0);
+ } catch (ActivityNotFoundException exc) {
+ Log.e(TAG, "No activity found for intent: " + intent);
+ }
+ return true;
+ }
+ });
+ helpMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ helpMenuItem.setVisible(true);
+ } else {
+ helpMenuItem.setVisible(false);
+ return false;
+ }
+
+ // return that the help menu item is visible (i.e., true)
+ return true;
+ }
+ }
+
+ public static Intent getHelpIntent(Context context, String helpUriString,
+ String backupContext) {
+ // Try to handle as Intent Uri, otherwise just treat as Uri.
+ try {
+ Intent intent = Intent.parseUri(helpUriString,
+ Intent.URI_ANDROID_APP_SCHEME | Intent.URI_INTENT_SCHEME);
+ addIntentParameters(context, intent, backupContext);
+ ComponentName component = intent.resolveActivity(context.getPackageManager());
+ if (component != null) {
+ return intent;
+ } else if (intent.hasExtra(EXTRA_BACKUP_URI)) {
+ // This extra contains a backup URI for when the intent isn't available.
+ return getHelpIntent(context, intent.getStringExtra(EXTRA_BACKUP_URI),
+ backupContext);
+ } else {
+ return null;
+ }
+ } catch (URISyntaxException e) {
+ }
+ // The help url string exists, so first add in some extra query parameters.
+ final Uri fullUri = uriWithAddedParameters(context, Uri.parse(helpUriString));
+
+ // Then, create an intent that will be fired when the user
+ // selects this help menu item.
+ Intent intent = new Intent(Intent.ACTION_VIEW, fullUri);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ return intent;
+ }
+
+ private static void addIntentParameters(Context context, Intent intent, String backupContext) {
+ if (!intent.hasExtra(EXTRA_CONTEXT)) {
+ // Insert some context if none exists.
+ intent.putExtra(EXTRA_CONTEXT, backupContext);
+ }
+ intent.putExtra(EXTRA_THEME, 1 /* Light, dark action bar */);
+ Theme theme = context.getTheme();
+ TypedValue typedValue = new TypedValue();
+ theme.resolveAttribute(android.R.attr.colorPrimary, typedValue, true);
+ intent.putExtra(EXTRA_PRIMARY_COLOR, context.getColor(typedValue.resourceId));
+ }
+
+ /**
+ * Adds two query parameters into the Uri, namely the language code and the version code
+ * of the app's package as gotten via the context.
+ * @return the uri with added query parameters
+ */
+ public static Uri uriWithAddedParameters(Context context, Uri baseUri) {
+ Uri.Builder builder = baseUri.buildUpon();
+
+ // Add in the preferred language
+ builder.appendQueryParameter(PARAM_LANGUAGE_CODE, Locale.getDefault().toString());
+
+ // Add in the package version code
+ if (sCachedVersionCode == null) {
+ // There is no cached version code, so try to get it from the package manager.
+ try {
+ // cache the version code
+ PackageInfo info = context.getPackageManager().getPackageInfo(
+ context.getPackageName(), 0);
+ sCachedVersionCode = Integer.toString(info.versionCode);
+
+ // append the version code to the uri
+ builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode);
+ } catch (NameNotFoundException e) {
+ // Cannot find the package name, so don't add in the version parameter
+ // This shouldn't happen.
+ Log.wtf(TAG, "Invalid package name for context", e);
+ }
+ } else {
+ builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode);
+ }
+
+ // Build the full uri and return it
+ return builder.build();
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index e86ca82..59637be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -459,58 +459,40 @@
LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
EnforcedAdmin enforcedAdmin = null;
final int userId = UserHandle.myUserId();
- if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
- // userId is managed profile and has a separate challenge, only consider
- // the admins in that user.
- final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId);
+ final UserManager um = UserManager.get(context);
+ final List<UserInfo> profiles = um.getProfiles(userId);
+ final int profilesSize = profiles.size();
+ // As we do not have a separate screen lock timeout settings for work challenge,
+ // we need to combine all profiles maximum time to lock even work challenge is
+ // enabled.
+ for (int i = 0; i < profilesSize; i++) {
+ final UserInfo userInfo = profiles.get(i);
+ final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
if (admins == null) {
- return null;
+ continue;
}
for (ComponentName admin : admins) {
- if (dpm.getMaximumTimeToLock(admin, userId) > 0) {
+ if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
if (enforcedAdmin == null) {
- enforcedAdmin = new EnforcedAdmin(admin, userId);
+ enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
} else {
return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
}
- }
- }
- } else {
- // Return all admins for this user and the profiles that are visible from this
- // user that do not use a separate work challenge.
- final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- for (UserInfo userInfo : um.getProfiles(userId)) {
- final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
- if (admins == null) {
+ // This same admins could have set policies both on the managed profile
+ // and on the parent. So, if the admin has set the policy on the
+ // managed profile here, we don't need to further check if that admin
+ // has set policy on the parent admin.
continue;
}
- final boolean isSeparateProfileChallengeEnabled =
- lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id);
- for (ComponentName admin : admins) {
- if (!isSeparateProfileChallengeEnabled) {
- if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
- if (enforcedAdmin == null) {
- enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
- } else {
- return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
- }
- // This same admins could have set policies both on the managed profile
- // and on the parent. So, if the admin has set the policy on the
- // managed profile here, we don't need to further check if that admin
- // has set policy on the parent admin.
- continue;
- }
- }
- if (userInfo.isManagedProfile()) {
- // If userInfo.id is a managed profile, we also need to look at
- // the policies set on the parent.
- DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo);
- if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
- if (enforcedAdmin == null) {
- enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
- } else {
- return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
- }
+ if (userInfo.isManagedProfile()) {
+ // If userInfo.id is a managed profile, we also need to look at
+ // the policies set on the parent.
+ final DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo);
+ if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
+ if (enforcedAdmin == null) {
+ enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+ } else {
+ return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 586f269..ca0b86a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -15,7 +15,7 @@
import android.os.BatteryManager;
import android.os.UserManager;
import com.android.internal.util.UserIcons;
-import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.settingslib.drawable.UserIconDrawable;
import java.text.NumberFormat;
@@ -73,21 +73,22 @@
/**
* Returns a circular icon for a user.
*/
- public static Drawable getUserIcon(Context context, UserManager um, UserInfo user) {
+ public static UserIconDrawable getUserIcon(Context context, UserManager um, UserInfo user) {
+ final int iconSize = UserIconDrawable.getSizeForList(context);
if (user.isManagedProfile()) {
// We use predefined values for managed profiles
Bitmap b = BitmapFactory.decodeResource(context.getResources(),
com.android.internal.R.drawable.ic_corp_icon);
- return CircleFramedDrawable.getInstance(context, b);
+ return new UserIconDrawable(iconSize).setIcon(b).bake();
}
if (user.iconPath != null) {
Bitmap icon = um.getUserIcon(user.id);
if (icon != null) {
- return CircleFramedDrawable.getInstance(context, icon);
+ return new UserIconDrawable(iconSize).setIcon(icon).bake();
}
}
- return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap(
- UserIcons.getDefaultUserIcon(user.id, /* light= */ false)));
+ return new UserIconDrawable(iconSize).setIconDrawable(
+ UserIcons.getDefaultUserIcon(user.id, /* light= */ false)).bake();
}
/** Formats the ratio of amount/total as a percentage. */
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 6052ccd..7f0e27a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -399,6 +399,9 @@
// Copy previous profile list into removedProfiles
removedProfiles.clear();
removedProfiles.addAll(profiles);
+ if (DEBUG) {
+ Log.d(TAG,"Current Profiles" + profiles.toString());
+ }
profiles.clear();
if (uuids == null) {
@@ -415,6 +418,13 @@
}
}
+ if ((mHfpClientProfile != null) &&
+ BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) &&
+ BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree)) {
+ profiles.add(mHfpClientProfile);
+ removedProfiles.remove(mHfpClientProfile);
+ }
+
if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) &&
mA2dpProfile != null) {
profiles.add(mA2dpProfile);
@@ -425,7 +435,7 @@
mA2dpSinkProfile != null) {
profiles.add(mA2dpSinkProfile);
removedProfiles.remove(mA2dpSinkProfile);
- }
+ }
if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
mOppProfile != null) {
@@ -461,5 +471,9 @@
profiles.remove(mPbapProfile);
removedProfiles.add(mPbapProfile);
}
+
+ if (DEBUG) {
+ Log.d(TAG,"New Profiles" + profiles.toString());
+ }
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
new file mode 100644
index 0000000..32478a7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -0,0 +1,428 @@
+/*
+ * 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.settingslib.drawable;
+
+import android.annotation.NonNull;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+
+import com.android.settingslib.R;
+
+/**
+ * Converts the user avatar icon to a circularly clipped one with an optional badge and frame
+ */
+public class UserIconDrawable extends Drawable implements Drawable.Callback {
+
+ private Drawable mUserDrawable;
+ private Bitmap mUserIcon;
+ private Bitmap mBitmap; // baked representation. Required for transparent border around badge
+ private final Paint mIconPaint = new Paint();
+ private final Paint mPaint = new Paint();
+ private final Matrix mIconMatrix = new Matrix();
+ private float mIntrinsicRadius;
+ private float mDisplayRadius;
+ private float mPadding = 0;
+ private int mSize = 0; // custom "intrinsic" size for this drawable if non-zero
+ private boolean mInvalidated = true;
+ private ColorStateList mTintColor = null;
+ private PorterDuff.Mode mTintMode = PorterDuff.Mode.SRC_ATOP;
+
+ private float mFrameWidth;
+ private float mFramePadding;
+ private ColorStateList mFrameColor = null;
+ private Paint mFramePaint;
+
+ private Drawable mBadge;
+ private Paint mClearPaint;
+ private float mBadgeRadius;
+ private float mBadgeMargin;
+
+ /**
+ * Gets the system default managed-user badge as a drawable
+ * @param context
+ * @return drawable containing just the badge
+ */
+ public static Drawable getManagedUserBadgeDrawable(Context context) {
+ int displayDensity = context.getResources().getDisplayMetrics().densityDpi;
+ return context.getResources().getDrawableForDensity(
+ com.android.internal.R.drawable.ic_corp_user_badge,
+ displayDensity, context.getTheme());
+ }
+
+ /**
+ * Gets the preferred list-item size of this drawable.
+ * @param context
+ * @return size in pixels
+ */
+ public static int getSizeForList(Context context) {
+ return (int) context.getResources().getDimension(R.dimen.circle_avatar_size);
+ }
+
+ public UserIconDrawable() {
+ this(0);
+ }
+
+ /**
+ * Use this constructor if the drawable is intended to be placed in listviews
+ * @param intrinsicSize if 0, the intrinsic size will come from the icon itself
+ */
+ public UserIconDrawable(int intrinsicSize) {
+ super();
+ mIconPaint.setAntiAlias(true);
+ mIconPaint.setFilterBitmap(true);
+ mPaint.setFilterBitmap(true);
+ mPaint.setAntiAlias(true);
+ if (intrinsicSize > 0) {
+ setBounds(0, 0, intrinsicSize, intrinsicSize);
+ setIntrinsicSize(intrinsicSize);
+ }
+ setIcon(null);
+ }
+
+ public UserIconDrawable setIcon(Bitmap icon) {
+ if (mUserDrawable != null) {
+ mUserDrawable.setCallback(null);
+ mUserDrawable = null;
+ }
+ mUserIcon = icon;
+ if (mUserIcon == null) {
+ mIconPaint.setShader(null);
+ mBitmap = null;
+ } else {
+ mIconPaint.setShader(new BitmapShader(icon, Shader.TileMode.CLAMP,
+ Shader.TileMode.CLAMP));
+ }
+ onBoundsChange(getBounds());
+ return this;
+ }
+
+ public UserIconDrawable setIconDrawable(Drawable icon) {
+ if (mUserDrawable != null) {
+ mUserDrawable.setCallback(null);
+ }
+ mUserIcon = null;
+ mUserDrawable = icon;
+ if (mUserDrawable == null) {
+ mBitmap = null;
+ } else {
+ mUserDrawable.setCallback(this);
+ }
+ onBoundsChange(getBounds());
+ return this;
+ }
+
+ public UserIconDrawable setBadge(Drawable badge) {
+ mBadge = badge;
+ if (mBadge != null) {
+ if (mClearPaint == null) {
+ mClearPaint = new Paint();
+ mClearPaint.setAntiAlias(true);
+ mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+ mClearPaint.setStyle(Paint.Style.FILL);
+ }
+ // update metrics
+ onBoundsChange(getBounds());
+ } else {
+ invalidateSelf();
+ }
+ return this;
+ }
+
+ public UserIconDrawable setBadgeIfManagedUser(Context context, int userId) {
+ Drawable badge = null;
+ boolean isManaged = context.getSystemService(DevicePolicyManager.class)
+ .getProfileOwnerAsUser(userId) != null;
+ if (isManaged) {
+ badge = getManagedUserBadgeDrawable(context);
+ }
+ return setBadge(badge);
+ }
+
+ public void setBadgeRadius(float radius) {
+ mBadgeRadius = radius;
+ onBoundsChange(getBounds());
+ }
+
+ public void setBadgeMargin(float margin) {
+ mBadgeMargin = margin;
+ onBoundsChange(getBounds());
+ }
+
+ /**
+ * Sets global padding of icon/frame. Doesn't effect the badge.
+ * @param padding
+ */
+ public void setPadding(float padding) {
+ mPadding = padding;
+ onBoundsChange(getBounds());
+ }
+
+ private void initFramePaint() {
+ if (mFramePaint == null) {
+ mFramePaint = new Paint();
+ mFramePaint.setStyle(Paint.Style.STROKE);
+ mFramePaint.setAntiAlias(true);
+ }
+ }
+
+ public void setFrameWidth(float width) {
+ initFramePaint();
+ mFrameWidth = width;
+ mFramePaint.setStrokeWidth(width);
+ onBoundsChange(getBounds());
+ }
+
+ public void setFramePadding(float padding) {
+ initFramePaint();
+ mFramePadding = padding;
+ onBoundsChange(getBounds());
+ }
+
+ public void setFrameColor(int color) {
+ initFramePaint();
+ mFramePaint.setColor(color);
+ invalidateSelf();
+ }
+
+ public void setFrameColor(ColorStateList colorList) {
+ initFramePaint();
+ mFrameColor = colorList;
+ invalidateSelf();
+ }
+
+ /**
+ * This sets the "intrinsic" size of this drawable. Useful for views which use the drawable's
+ * intrinsic size for layout. It is independent of the bounds.
+ * @param size if 0, the intrinsic size will be set to the displayed icon's size
+ */
+ public void setIntrinsicSize(int size) {
+ mSize = size;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (mInvalidated) {
+ rebake();
+ }
+ if (mBitmap != null) {
+ if (mTintColor == null) {
+ mPaint.setColorFilter(null);
+ } else {
+ int color = mTintColor.getColorForState(getState(), mTintColor.getDefaultColor());
+ if (mPaint.getColorFilter() == null) {
+ mPaint.setColorFilter(new PorterDuffColorFilter(color, mTintMode));
+ } else {
+ ((PorterDuffColorFilter) mPaint.getColorFilter()).setMode(mTintMode);
+ ((PorterDuffColorFilter) mPaint.getColorFilter()).setColor(color);
+ }
+ }
+
+ canvas.drawBitmap(mBitmap, 0, 0, mPaint);
+ }
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mPaint.setAlpha(alpha);
+ super.invalidateSelf();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+
+ @Override
+ public void setTintList(ColorStateList tintList) {
+ mTintColor = tintList;
+ super.invalidateSelf();
+ }
+
+ @Override
+ public void setTintMode(@NonNull PorterDuff.Mode mode) {
+ mTintMode = mode;
+ super.invalidateSelf();
+ }
+
+ /**
+ * This 'bakes' the current state of this icon into a bitmap and removes/recycles the source
+ * bitmap/drawable. Use this when no more changes will be made and an intrinsic size is set.
+ * This effectively turns this into a static drawable.
+ */
+ public UserIconDrawable bake() {
+ if (mSize <= 0) {
+ throw new IllegalStateException("Baking requires an explicit intrinsic size");
+ }
+ onBoundsChange(new Rect(0, 0, mSize, mSize));
+ rebake();
+ mFrameColor = null;
+ mFramePaint = null;
+ mClearPaint = null;
+ if (mUserDrawable != null) {
+ mUserDrawable.setCallback(null);
+ mUserDrawable = null;
+ } else if (mUserIcon != null) {
+ mUserIcon.recycle();
+ mUserIcon = null;
+ }
+ return this;
+ }
+
+ private void rebake() {
+ mInvalidated = false;
+
+ if (mBitmap == null || (mUserDrawable == null && mUserIcon == null)) {
+ return;
+ }
+
+ final Canvas canvas = new Canvas(mBitmap);
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ if(mUserDrawable != null) {
+ mUserDrawable.draw(canvas);
+ } else if (mUserIcon != null) {
+ int saveId = canvas.save();
+ canvas.concat(mIconMatrix);
+ canvas.drawCircle(mUserIcon.getWidth() * 0.5f, mUserIcon.getHeight() * 0.5f,
+ mIntrinsicRadius, mIconPaint);
+ canvas.restoreToCount(saveId);
+ }
+
+ if (mFrameColor != null) {
+ mFramePaint.setColor(mFrameColor.getColorForState(getState(), Color.TRANSPARENT));
+ }
+ if ((mFrameWidth + mFramePadding) > 0.001f) {
+ float radius = mDisplayRadius - mPadding - mFrameWidth * 0.5f;
+ canvas.drawCircle(getBounds().exactCenterX(), getBounds().exactCenterY(),
+ radius, mFramePaint);
+ }
+
+ if ((mBadge != null) && (mBadgeRadius > 0.001f)) {
+ final float badgeDiameter = mBadgeRadius * 2f;
+ final float badgeTop = mBitmap.getHeight() - badgeDiameter;
+ float badgeLeft = mBitmap.getWidth() - badgeDiameter;
+
+ mBadge.setBounds((int) badgeLeft, (int) badgeTop,
+ (int) (badgeLeft + badgeDiameter), (int) (badgeTop + badgeDiameter));
+
+ final float borderRadius = mBadge.getBounds().width() * 0.5f + mBadgeMargin;
+ canvas.drawCircle(badgeLeft + mBadgeRadius, badgeTop + mBadgeRadius,
+ borderRadius, mClearPaint);
+
+ mBadge.draw(canvas);
+ }
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ if (bounds.isEmpty() || (mUserIcon == null && mUserDrawable == null)) {
+ return;
+ }
+
+ // re-create bitmap if applicable
+ float newDisplayRadius = Math.min(bounds.width(), bounds.height()) * 0.5f;
+ int size = (int) (newDisplayRadius * 2);
+ if (mBitmap == null || size != ((int) (mDisplayRadius * 2))) {
+ mDisplayRadius = newDisplayRadius;
+ if (mBitmap != null) {
+ mBitmap.recycle();
+ }
+ mBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+ }
+
+ // update metrics
+ mDisplayRadius = Math.min(bounds.width(), bounds.height()) * 0.5f;
+ final float iconRadius = mDisplayRadius - mFrameWidth - mFramePadding - mPadding;
+ RectF dstRect = new RectF(bounds.exactCenterX() - iconRadius,
+ bounds.exactCenterY() - iconRadius,
+ bounds.exactCenterX() + iconRadius,
+ bounds.exactCenterY() + iconRadius);
+ if (mUserDrawable != null) {
+ Rect rounded = new Rect();
+ dstRect.round(rounded);
+ mIntrinsicRadius = Math.min(mUserDrawable.getIntrinsicWidth(),
+ mUserDrawable.getIntrinsicHeight()) * 0.5f;
+ mUserDrawable.setBounds(rounded);
+ } else if (mUserIcon != null) {
+ // Build square-to-square transformation matrix
+ final float iconCX = mUserIcon.getWidth() * 0.5f;
+ final float iconCY = mUserIcon.getHeight() * 0.5f;
+ mIntrinsicRadius = Math.min(iconCX, iconCY);
+ RectF srcRect = new RectF(iconCX - mIntrinsicRadius, iconCY - mIntrinsicRadius,
+ iconCX + mIntrinsicRadius, iconCY + mIntrinsicRadius);
+ mIconMatrix.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.FILL);
+ }
+
+ invalidateSelf();
+ }
+
+ @Override
+ public void invalidateSelf() {
+ super.invalidateSelf();
+ mInvalidated = true;
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mFrameColor != null && mFrameColor.isStateful();
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return (mSize <= 0 ? (int) mIntrinsicRadius * 2 : mSize);
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return getIntrinsicWidth();
+ }
+
+ @Override
+ public void invalidateDrawable(@NonNull Drawable who) {
+ invalidateSelf();
+ }
+
+ @Override
+ public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
+ scheduleSelf(what, when);
+ }
+
+ @Override
+ public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
+ unscheduleSelf(what);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/UserAdapter.java b/packages/SettingsLib/src/com/android/settingslib/drawer/UserAdapter.java
index f9fa805f..750601d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/UserAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/UserAdapter.java
@@ -33,7 +33,7 @@
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.android.internal.util.UserIcons;
-import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.settingslib.drawable.UserIconDrawable;
import com.android.settingslib.R;
@@ -71,7 +71,8 @@
}
private static Drawable encircle(Context context, Drawable icon) {
- return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap(icon));
+ return new UserIconDrawable(UserIconDrawable.getSizeForList(context))
+ .setIconDrawable(icon).bake();
}
}
private ArrayList<UserDetails> data;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 61c9f2b..5621642 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1942,7 +1942,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 126;
+ private static final int SETTINGS_VERSION = 127;
private final int mUserId;
@@ -2167,6 +2167,36 @@
currentVersion = 126;
}
+ if (currentVersion == 126) {
+ // Version 126: copy the primary values of LOCK_SCREEN_SHOW_NOTIFICATIONS and
+ // LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS into managed profile.
+ if (mUserManager.isManagedProfile(userId)) {
+ final SettingsState systemSecureSettings =
+ getSecureSettingsLocked(UserHandle.USER_SYSTEM);
+
+ final Setting showNotifications = systemSecureSettings.getSettingLocked(
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
+ if (showNotifications != null) {
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ secureSettings.insertSettingLocked(
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ showNotifications.getValue(),
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ final Setting allowPrivate = systemSecureSettings.getSettingLocked(
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+ if (allowPrivate != null) {
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ secureSettings.insertSettingLocked(
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+ allowPrivate.getValue(),
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ }
+ currentVersion = 127;
+ }
+
// vXXX: Add new settings above this point.
// Return the current version.
diff --git a/packages/SystemUI/res/values-h560dp/config.xml b/packages/SystemUI/res/color/qs_user_detail_avatar_frame.xml
similarity index 68%
rename from packages/SystemUI/res/values-h560dp/config.xml
rename to packages/SystemUI/res/color/qs_user_detail_avatar_frame.xml
index 8b576b9..20251c2 100644
--- a/packages/SystemUI/res/values-h560dp/config.xml
+++ b/packages/SystemUI/res/color/qs_user_detail_avatar_frame.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2014 The Android Open Source Project
+ ~ 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.
@@ -16,8 +16,7 @@
~ limitations under the License
-->
-<resources>
- <!-- The maximum number of items to be displayed in quick settings -->
- <integer name="quick_settings_detail_max_item_count">6</integer>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_activated="true" android:color="@color/current_user_border_color" />
+ <item android:color="@android:color/transparent" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-h560dp/config.xml b/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
similarity index 68%
copy from packages/SystemUI/res/values-h560dp/config.xml
copy to packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
index 8b576b9..2b75c36 100644
--- a/packages/SystemUI/res/values-h560dp/config.xml
+++ b/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2014 The Android Open Source Project
+ ~ 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.
@@ -16,8 +16,7 @@
~ limitations under the License
-->
-<resources>
- <!-- The maximum number of items to be displayed in quick settings -->
- <integer name="quick_settings_detail_max_item_count">6</integer>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" />
+ <item android:color="@android:color/transparent" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
index af3e379..1f24ab0 100644
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ b/packages/SystemUI/res/layout/battery_detail.xml
@@ -26,10 +26,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="72dp"
- android:paddingBottom="@dimen/battery_detail_graph_space_top"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/colorAccent" />
+ <com.android.systemui.ResizingSpace
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/battery_detail_graph_space_top" />
+
<com.android.settingslib.graph.UsageView
android:id="@+id/battery_usage"
android:layout_width="match_parent"
@@ -40,11 +43,14 @@
android:colorAccent="?android:attr/colorAccent"
systemui:textColor="#66FFFFFF" />
+ <com.android.systemui.ResizingSpace
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/battery_detail_graph_space_bottom" />
+
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
- android:layout_marginTop="@dimen/battery_detail_graph_space_bottom"
android:layout_marginBottom="8dp" />
<RelativeLayout
diff --git a/packages/SystemUI/res/layout/forced_resizable_activity.xml b/packages/SystemUI/res/layout/forced_resizable_activity.xml
index df245bc..3c778c4 100644
--- a/packages/SystemUI/res/layout/forced_resizable_activity.xml
+++ b/packages/SystemUI/res/layout/forced_resizable_activity.xml
@@ -18,10 +18,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <TextView
+ <include
+ layout="@*android:layout/transient_notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="@string/forced_resizable_info_text"
- android:textColor="#ffffff"/>
+ android:layout_gravity="center"/>
</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
index 9c2c0ab..3865020 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
@@ -22,8 +22,17 @@
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingBottom="8dp">
+ <ImageView
+ android:id="@+id/keyboard_shortcuts_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginEnd="32dp"
+ android:layout_gravity="center_vertical"
+ android:visibility="gone"
+ android:layout_alignParentStart="true"/>
<TextView
android:id="@+id/keyboard_shortcuts_keyword"
+ android:layout_toEndOf="@+id/keyboard_shortcuts_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="12dp"
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
index c6e453a..d685528 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
@@ -33,14 +33,18 @@
<TextView android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="16dp"
+ android:layout_marginEnd="13dp"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.UserSwitcher.UserName"
/>
<com.android.systemui.statusbar.phone.UserAvatarView android:id="@+id/user_picture"
- android:layout_width="@dimen/max_avatar_size"
- android:layout_height="@dimen/max_avatar_size"
+ android:layout_width="@dimen/framed_avatar_size"
+ android:layout_height="@dimen/framed_avatar_size"
android:contentDescription="@null"
+ android:backgroundTint="@color/qs_user_detail_avatar_tint"
+ android:backgroundTintMode="src_atop"
sysui:frameWidth="@dimen/keyguard_user_switcher_border_thickness"
- sysui:framePadding="6dp"
- sysui:activeFrameColor="@color/current_user_border_color" />
+ sysui:framePadding="2.5dp"
+ sysui:badgeDiameter="18dp"
+ sysui:badgeMargin="1dp"
+ sysui:frameColor="@color/qs_user_detail_avatar_frame" />
</com.android.systemui.qs.tiles.UserDetailItemView>
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 3358a18..af2a285 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -25,13 +25,15 @@
android:visibility="invisible"
android:orientation="vertical">
+ <com.android.systemui.ResizingSpace
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_detail_margin_top" />
+
<include
android:id="@+id/qs_detail_header"
layout="@layout/qs_detail_header"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="28dp"
- />
+ android:layout_height="wrap_content" />
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/qs_detail_header_progress"
diff --git a/packages/SystemUI/res/layout/qs_detail_items.xml b/packages/SystemUI/res/layout/qs_detail_items.xml
index c22e42c..f1a8d63 100644
--- a/packages/SystemUI/res/layout/qs_detail_items.xml
+++ b/packages/SystemUI/res/layout/qs_detail_items.xml
@@ -16,17 +16,19 @@
-->
<!-- extends FrameLayout -->
<com.android.systemui.qs.QSDetailItems xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingTop="16dp"
+ android:paddingTop="@dimen/qs_detail_items_padding_top"
android:paddingStart="16dp"
android:paddingEnd="16dp">
- <LinearLayout
+ <com.android.systemui.qs.AutoSizingList
android:id="@android:id/list"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ sysui:itemHeight="@dimen/qs_detail_item_height" />
<LinearLayout
android:id="@android:id/empty"
@@ -48,9 +50,4 @@
android:layout_marginTop="20dp"
android:textAppearance="@style/TextAppearance.QS.DetailEmpty" />
</LinearLayout>
-
- <View
- android:id="@+id/min_height_spacer"
- android:layout_width="match_parent"
- android:layout_height="0dp"/>
-</com.android.systemui.qs.QSDetailItems>
\ No newline at end of file
+</com.android.systemui.qs.QSDetailItems>
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index b0dca9a..cce9c0f 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -26,9 +26,7 @@
android:gravity="center_horizontal"
android:minLines="2"
android:padding="0dp"
- android:fontFamily="sans-serif-condensed"
- android:textStyle="normal"
- android:textSize="@dimen/qs_tile_text_size"
+ android:textAppearance="@style/TextAppearance.QS.TileLabel"
android:clickable="false" />
<ImageView android:id="@+id/restricted_padlock"
android:layout_width="@dimen/qs_tile_text_size"
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index 661d74a..58fc069 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -33,12 +33,16 @@
<com.android.systemui.statusbar.phone.UserAvatarView
android:id="@+id/user_picture"
- android:layout_width="@dimen/max_avatar_size"
- android:layout_height="@dimen/max_avatar_size"
- android:layout_marginBottom="10dp"
+ android:layout_width="@dimen/framed_avatar_size"
+ android:layout_height="@dimen/framed_avatar_size"
+ android:layout_marginBottom="7dp"
+ android:backgroundTint="@color/qs_user_detail_avatar_tint"
+ android:backgroundTintMode="src_atop"
systemui:frameWidth="2dp"
- systemui:framePadding="6dp"
- systemui:activeFrameColor="@color/current_user_border_color"/>
+ systemui:framePadding="2.5dp"
+ systemui:badgeDiameter="18dp"
+ systemui:badgeMargin="1dp"
+ systemui:frameColor="@color/qs_user_detail_avatar_frame"/>
<LinearLayout
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 3dca77d..7c4ce15 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -55,6 +55,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/heads_up_scrim_height"
android:background="@drawable/heads_up_scrim"
+ sysui:ignoreRightInset="true"
android:importantForAccessibility="no"/>
<include layout="@layout/status_bar"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 3fa6245..8dff1c7 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Maak <xliff:g id="APP">%s</xliff:g> toe."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwerp."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle onlangse programme is toegemaak."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Maak <xliff:g id="APP">%s</xliff:g>-programinligting oop."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Begin tans <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Kennisgewing is toegemaak."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is die volumedialoog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Raak om die oorspronklike terug te stel."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jy gebruik tans jou werkprofiel"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Stelsel-UI-ontvanger"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Wys persentasie van ingebedde battery"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Wys batteryvlakpersentasie binne die statusbalkikoon wanneer dit nie laai nie"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Program sal dalk nie met multivenster werk nie"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te wysig."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om by te voeg."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>. Dubbeltik om te kies."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is verwyder"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is na posisie <xliff:g id="POSITION">%2$d</xliff:g> geskuif"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Kitsinstellingswysiger."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Program sal dalk nie met verdeelde skerm werk nie."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Program steun nie verdeelde skerm nie."</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index eb5d256..7f6c6b2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> አስወግድ።"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ተሰናብቷል::"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ሁሉም የቅርብ ጊዜ ማመልከቻዎች ተሰናብተዋል።"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"የ<xliff:g id="APP">%s</xliff:g> መተግበሪያ መረጃውን ይክፈቱ።"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> በመጀመር ላይ።"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ማሳወቂያ ተወግዷል።"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> የድምጽ መጠን መገናኛው ነው"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"የመጀመሪያውን ወደነበረበት ለመመለስ ይንኩ።"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"የስራ መገለጫዎን እየተጠቀሙ ነው"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"የስርዓት በይነገጽ መቃኛ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"የተቀላቀለ የባትሪ አጠቃቀም መቶኛ አሳይ"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ኃይል በማይሞላበት ጊዜ በሁነታ አሞሌ አዶ ውስጥ የባትሪ ደረጃ መቶኛን አሳይ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"መተግበሪያ ከብዝሃ-መስኮት ጋር ላይሠራ ይችላል"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ቦታ <xliff:g id="POSITION">%1$d</xliff:g>፣ <xliff:g id="TILE_NAME">%2$s</xliff:g>። ለማርትዕ ሁለቴ መታ ያድርጉ።"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>። ለማከል ሁለቴ መታ ያድርጉ።"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ቦታ <xliff:g id="POSITION">%1$d</xliff:g>። ለመምረጥ ሁለቴ መታ ያድርጉ።"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ተወግዷል"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ወደ ቦታ <xliff:g id="POSITION">%2$d</xliff:g> ተወስዷል"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"የፈጣን ቅንብሮች አርታዒ።"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 82a772c..1b1d280 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -172,8 +172,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"إزالة <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"تمت إزالة <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"تم تجاهل كل التطبيقات المستخدمة مؤخرًا."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"فتح معلومات تطبيق <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"جارٍ بدء <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"تم تجاهل الإشعار."</string>
@@ -425,6 +424,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> هو مربع حوار مستوى الصوت"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"المس لاستعادة الإعداد الأصلي."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"أنت تستخدم ملفك الشخصي للعمل"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"أداة ضبط واجهة مستخدم النظام"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"عرض نسبة البطارية المدمجة"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"عرض نسبة مستوى البطارية داخل رمز شريط الحالة أثناء عدم الشحن"</string>
@@ -499,7 +504,7 @@
<string name="night_mode_disclaimer" msgid="598914896926759578">"يتم تطبيق المظهر المعتم على المناطق الأساسية في نظام التشغيل Android والتي يتم عرضها عادة في مظهر مضيء، مثل الإعدادات."</string>
<string name="color_apply" msgid="9212602012641034283">"تطبيق"</string>
<string name="color_revert_title" msgid="4746666545480534663">"تأكيد الإعدادات"</string>
- <string name="color_revert_message" msgid="9116001069397996691">"يمكن أن تتسبب بعض إعدادات الألوان في تعطيل إمكانية استخدام الجهاز. يمكنك النقر على \"موافق\" لتأكيد إعدادات الألوان هذه، وإلا فستتم إعادة تعيين هذه الإعدادات بعد 10 ثوانٍ."</string>
+ <string name="color_revert_message" msgid="9116001069397996691">"يمكن أن تتسبب بعض إعدادات الألوان في تعطيل إمكانية استخدام الجهاز. يمكنك النقر على \"موافق\" لتأكيد إعدادات الألوان هذه، وإلا فستتم إعادة تعيين هذه الإعدادات بعد ۱۰ ثوانٍ."</string>
<string name="battery_panel_title" msgid="7944156115535366613">"استخدام البطارية"</string>
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
@@ -600,7 +605,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"يمكن ألا يعمل التطبيق مع وضع النوافذ المتعددة."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"الموضع <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. انقر نقرًا مزدوجًا للتعديل."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. انقر نقرًا مزدوجًا للإضافة."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"الموضع <xliff:g id="POSITION">%1$d</xliff:g>. انقر نقرًا مزدوجًا للتحديد."</string>
@@ -610,4 +614,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"تمت إزالة <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"تم نقل <xliff:g id="TILE_NAME">%1$s</xliff:g> إلى الموضع <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"برنامج تعديل الإعدادات السريعة."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"يمكن ألا يعمل التطبيق مع وضع تقسيم الشاشة."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"التطبيق لا يتيح تقسيم الشاشة."</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 59b3141..4fee4ec 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> kənarlaşdırın."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> çıxarıldı."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Bütün son tətbiqlər kənarlaşdırıldı."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> tətbiqi haqqında məlumatı açın."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> başlanır."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildiriş uzaqlaşdırıldı."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> proqramı səs səviyyəsi dialoqudur"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinalı bərpa etmək üçün toxun."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi istifadə edirsiniz"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Daxil batareya faizini göstərin"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Elektrik şəbəsinə qoşulu olmayan zaman batareya səviyyəsini status paneli ikonası daxilində göstərin"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Redaktə etmək üçün iki dəfə tıklayın."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Əlavə etmək üçün iki dəfə tıklayın."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi. Seçmək üçün iki dəfə tıklayın."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> silindi"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> mövqeyinə köçürüldü"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Sürətli ayarlar redaktoru."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Tətbiq ekran bölünməsini dəstəkləmir."</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 0945885..4d22d2e 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbacite <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> je odbačena."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Sve nedavno korišćene aplikacije su odbačene."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otvorite informacije o aplikaciji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokrećemo <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obaveštenje je odbačeno."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dijalog za jačinu zvuka"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Koristite profil za Work"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Tjuner za korisnički interfejs sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Prikazuj ugrađeni procenat baterije"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikazivanje nivoa napunjenosti baterije u procentima unutar ikone na statusnoj traci kada se baterija ne puni"</string>
@@ -597,7 +602,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija možda neće funkcionisati sa više prozora"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvaput dodirnite da biste izmenili."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dvaput dodirnite da biste dodali."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija. Dvaput dodirnite da biste izabrali."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Pločica <xliff:g id="TILE_NAME">%1$s</xliff:g> je uklonjena"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Pločica <xliff:g id="TILE_NAME">%1$s</xliff:g> je premeštena na <xliff:g id="POSITION">%2$d</xliff:g>. poziciju"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Uređivač za Brza podešavanja."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podeljeni ekran."</string>
</resources>
diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml
index 726a0e7..5f3aa55 100644
--- a/packages/SystemUI/res/values-be-rBY/strings.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings.xml
@@ -172,8 +172,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Выдаліць <xliff:g id="APP">%s</xliff:g> са спіса апошніх."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> выдалены."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Усе апошнія праграмы адхілены."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Адкрыць інфармацыю пра праграму <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запускаецца <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Апавяшчэнне прапушчана."</string>
@@ -425,6 +424,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> з\'яўляецца дыялогам гучнасці"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Націсніце, каб аднавіць арыгінал."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Вы выкарыстоўваеце свой працоўны профіль"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Наладка сістэмнага інтэрфейсу карыстальніка"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Паказваць працэнт зараду акумулятара"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Паказваць працэнт узроўню акумулятара ўнутры значка панэлі стану, калі ён не зараджаецца"</string>
@@ -535,7 +540,7 @@
<string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Апошнія"</string>
<string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Апавяшчэнні"</string>
- <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Спалучэнні клавіш для хуткага доступу"</string>
+ <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Спалучэнні клавіш"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Пераключэнне рэжыму ўводу"</string>
<string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Праграмы"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Памочнік"</string>
@@ -600,7 +605,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Праграма можа не працаваць у рэжыме некалькіх вокнаў"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Краніце двойчы, каб рэдагаваць."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Краніце двойчы, каб дадаць."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>. Краніце двойчы, каб выбраць."</string>
@@ -610,4 +614,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Плітка <xliff:g id="TILE_NAME">%1$s</xliff:g> выдалена"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> перамешчана ў наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Рэдактар хуткіх налад."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 479087a..7aa52fe 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отхвърляне на <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложението <xliff:g id="APP">%s</xliff:g> е отхвърлено."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Всички скорошни приложения са отхвърлени."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Отворете информацията за приложението <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> се стартира."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известието е отхвърлено."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> изпълнява ролята на диалоговия прозорец за силата на звука"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Докоснете, за да възстановите оригинала."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Използвате служебния си потребителски профил"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Тунер на системния потребителски интерфейс"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Показване на процента на вградената батерия"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Показване на процента на нивото на батерията в иконата на лентата на състоянието, когато не се зарежда"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложението може да не работи в режим за няколко прозореца"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Докоснете двукратно, за да редактирате."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"„<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Докоснете двукратно, за да добавите."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>. Докоснете двукратно, за да изберете."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Премахнахте „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Преместихте „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ на позиция <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Редактор за бързи настройки."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Приложението може да не работи в режим на разделен екран."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Приложението не поддържа разделен екран."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index ccbcb6e..6bf0cae 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> খারিজ করুন।"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> খারিজ করা হয়েছে৷"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"সমস্ত সাম্প্রতিক অ্যাপ্লিকেশন খারিজ করা হয়েছে।"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> অ্যাপ্লিকেশানের তথ্য খুলবে৷"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> তারাঙ্কিত করা হচ্ছে।"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"বিজ্ঞপ্তি খারিজ করা হয়েছে৷"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"আসলটি পুনঃস্থাপন করতে স্পর্শ করুন৷"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"আপনি আপনার কাজের প্রোফাইল ব্যবহার করছেন"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"সিস্টেম UI টিউনার"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"এম্বেড করা ব্যাটারির শতকরা হার দেখায়"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"যখন চার্জ করা হবে না তখন স্থিতি দন্ডের আইকনের ভিতরে ব্যাটারি স্তরের শতকার হার দেখায়"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"একাধিক-উইন্ডো দিয়ে অ্যাপ কাজ নাও করতে পারে"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g> অবস্থান, <xliff:g id="TILE_NAME">%2$s</xliff:g>৷ সম্পাদনা করতে দুবার আলতো চাপুন৷"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>৷ যোগ করতে দুবার আলতো চাপুন৷"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> অবস্থান৷ নির্বাচন করতে দুবার আলতো চাপুন৷"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> মোছা হয়েছে"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> এ সরানো হয়েছে"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"দ্রুত সেটিংস সম্পাদক৷"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"অ্যাপ্লিকেশানটি বিভক্ত স্ক্রীনে কাজ নাও করতে পারে৷"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রীন সমর্থন করে না৷"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index c5398a2..3b438d6 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbaci aplikaciju <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> uklonjena."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Sve nedavno korištene aplikacije su odbačene."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otvaranje informacija o aplikaciji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokrećem aplikaciju <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavještenje je uklonjeno."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dijaloški okvir za jačinu zvuka"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da vratite original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Koristite svoj profil za posao"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Podešavač za korisničko sučelje sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikazuje postotak nivoa baterije unutar ikone na statusnoj traci kada se baterija ne puni"</string>
@@ -597,7 +602,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvaput dodirnite za uređivanje."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> Dvaput dodirnite za dodavanje."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>. Dvaput dodirnite za odabir."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> je uklonjen"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> je premješten na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Uređivanje brzih postavki"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće raditi na podijeljenom ekranu"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava dijeljenje ekrana."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index b7fffb7..99cc5a9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignora <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"S\'ha omès <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"S\'han descartat totes les aplicacions recents."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Obre la informació sobre l\'aplicació <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"S\'està iniciant <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estàs utilitzant el perfil professional"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Personalitzador d\'interfície d\'usuari"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostra el percentatge de la bateria inserit"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra el percentatge del nivell de bateria dins de la icona de la barra d\'estat quan no s\'estigui carregant"</string>
@@ -539,7 +544,7 @@
<string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactes"</string>
<string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correu electrònic"</string>
<string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string>
- <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendari"</string>
<string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostra amb els controls de volum"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posició <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Fes doble toc per editar-la."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Fes doble toc per afegir-ho."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posició <xliff:g id="POSITION">%1$d</xliff:g>. Fes doble toc per seleccionar-la."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha suprimit"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha mogut a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de la configuració ràpida."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'aplicació no admet la pantalla dividida."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index b707ece..3bc73f6 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zavřít aplikaci <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikace <xliff:g id="APP">%s</xliff:g> byla odebrána."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všechny naposledy použité aplikace byly odstraněny."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otevře informace o aplikaci <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Spouštění aplikace <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení je zavřeno."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialog hlasitosti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používáte pracovní profil"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Nástroj na ladění uživatelského rozhraní systému"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Zobrazovat vložené procento nabití baterie"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Když neprobíhá nabíjení, zobrazit v ikoně na stavovém řádku procento nabití baterie"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikace nemusí v režimu několika oken fungovat."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvojitým klepnutím ji upravíte."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dlaždici přidáte dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>. Dvojitým klepnutím ji vyberete."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Dlaždice <xliff:g id="TILE_NAME">%1$s</xliff:g> byla odstraněna"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Dlaždice <xliff:g id="TILE_NAME">%1$s</xliff:g> byla přesunuta na pozici <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor rychlého nastavení"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikace nepodporuje režim rozdělené obrazovky."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7a25141..3b47e24 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Afvis <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> er annulleret."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle de seneste applikationer er lukket."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Åbn appoplysningerne for <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> startes."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Underretningen er annulleret."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er dialogboksen for lydstyrke"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tryk for at gendanne originalen."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruger din arbejdsprofil"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Vis procent for det indbyggede batteri"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Vis procenttallet for batteriniveauet i ikonet for statusbjælken, når der ikke oplades"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Appen fungerer muligvis ikke i Multivindue"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryk to gange for at redigere."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tryk to gange for at tilføje."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Tryk to gange for at vælge."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> fjernes"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> blev flyttet til position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigeringsværktøj for Hurtige indstillinger."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i delt skærm."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke delt skærm."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e10eb64..436e7c4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> beenden"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> entfernt"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle kürzlich verwendeten Apps wurden entfernt."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Infos zur App \"<xliff:g id="APP">%s</xliff:g>\" öffnen."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> wird gestartet."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Benachrichtigung geschlossen"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du verwendest dein Arbeitsprofil."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prozentzahl für Akkustand in Statusleistensymbol anzeigen, wenn das Gerät nicht geladen wird"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Zum Bearbeiten doppeltippen."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Zum Hinzufügen doppeltippen."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Zum Auswählen doppeltippen."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> wurde entfernt"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> an Position <xliff:g id="POSITION">%2$d</xliff:g> verschoben"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor für Schnelleinstellungen."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Die App funktioniert unter Umständen bei geteiltem Bildschirm nicht."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5ec3133..8809cdf 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Παράβλεψη <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Απορρίφθηκαν <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Έγινε παράβλεψη όλων των πρόσφατων εφαρμογών."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Άνοιγμα πληροφοριών εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Έναρξη <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Η ειδοποίηση έχει απορριφθεί."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Χρησιμοποιείτε το προφίλ εργασίας σας"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Εμφάνιση ποσοστού ενσωματωμένης μπαταρίας"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Εμφάνιση ποσοστού επιπέδου μπαταρίας μέσα στο εικονίδιο της γραμμής κατάστασης όταν δεν γίνεται φόρτιση"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Η εφαρμογή ενδέχεται να μη λειτουργεί με τη λειτουργία πολλαπλών παραθύρων"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Πατήστε δύο φορές για επεξεργασία."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Πατήστε δύο φορές για προσθήκη."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>. Πατήστε δύο φορές για επιλογή."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Το <xliff:g id="TILE_NAME">%1$s</xliff:g> καταργείται"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Το <xliff:g id="TILE_NAME">%1$s</xliff:g> μετακινήθηκε στη θέση <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Επεξεργασία γρήγορων ρυθμίσεων."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Δεν είναι δυνατή η λειτουργία της εφαρμογής με διαχωρισμό οθόνης."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f08894f..218cbbd 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Open <xliff:g id="APP">%s</xliff:g> application info."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Double tap to select."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is removed"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> moved to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Quick settings editor."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f08894f..218cbbd 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Open <xliff:g id="APP">%s</xliff:g> application info."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Double tap to select."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is removed"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> moved to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Quick settings editor."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f08894f..218cbbd 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Open <xliff:g id="APP">%s</xliff:g> application info."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Double tap to select."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is removed"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> moved to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Quick settings editor."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b5a10e1..c612431 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rechazar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartada."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se descartaron todas las aplicaciones recientes."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abre la información de la aplicación de <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar el original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador de IU del sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de la batería integrada"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentaje del nivel de batería en el ícono de la barra de estado cuando no se está cargando"</string>
@@ -538,7 +543,7 @@
<string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string>
<string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string>
- <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string>
+ <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Es posible que la app no se ejecute con la función Multiventana"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Presiona dos veces para editarla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Presiona dos veces para agregarlo."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posición <xliff:g id="POSITION">%1$d</xliff:g>. Presiona dos veces para seleccionarla."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Se quitó <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Se movió <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de Configuración rápida"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Es posible que la app no funcione en el modo de pantalla dividida."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"La app no es compatible con la función de pantalla dividida."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index d8affc9..c6ef4cc 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Se ha eliminado <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se han ignorado todas las aplicaciones recientes."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abre la información de la aplicación <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar la versión original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Configurador de IU del sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de batería insertado"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar el porcentaje del nivel de batería en el icono de la barra de estado cuando no se esté cargando"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dos veces para cambiarla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dos veces para añadirlo."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posición <xliff:g id="POSITION">%1$d</xliff:g>. Toca dos veces para seleccionarla."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> se ha quitado"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> se ha movido a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de ajustes rápidos."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Es posible que la aplicación no funcione con la pantalla dividida."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"La aplicación no admite la pantalla dividida."</string>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index f18bf05..664748b 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rakendusest <xliff:g id="APP">%s</xliff:g> loobumine."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Loobusite rakendusest <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kõikidest hiljutistest rakendustest on loobutud"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Rakenduse <xliff:g id="APP">%s</xliff:g> teabe avamine."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Rakenduse <xliff:g id="APP">%s</xliff:g> käivitamine."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g>, <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Märguandest on loobutud."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on helitugevuse dialoog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Originaali taastamiseks puudutage."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Kasutate oma tööprofiili"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Süsteemi kasutajaliidese tuuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Kuva lisatud akutaseme protsent"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Akutaseme protsendi kuvamine olekuriba ikoonil, kui akut ei laeta"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Rakendus ei pruugi mitme akna režiimis töötada"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Asend <xliff:g id="POSITION">%1$d</xliff:g>, paan <xliff:g id="TILE_NAME">%2$s</xliff:g>. Topeltpuudutage muutmiseks."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Topeltpuudutage lisamiseks."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Asend <xliff:g id="POSITION">%1$d</xliff:g>. Topeltpuudutage valimiseks."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Paan <xliff:g id="TILE_NAME">%1$s</xliff:g> eemaldati"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Paan <xliff:g id="TILE_NAME">%1$s</xliff:g> teisaldati asendisse <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Kiirseadete redigeerija."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Rakendus ei toeta jagatud ekraani."</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 575f8749..287f73f 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Baztertu <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> baztertu da."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Azken aplikazio guztiak baztertu da."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Ireki <xliff:g id="APP">%s</xliff:g> aplikazioari buruzko informazioa."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> hasten."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Jakinarazpena baztertu da."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> da bolumenaren leihoa"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Ukitu jatorrizkora leheneratzeko"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Work profila erabiltzen ari zara"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sistemako erabiltzaile-interfazearen konfiguratzailea"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Erakutsi txertatutako bateriaren ehunekoa"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Erakutsi bateria-mailaren ehunekoa egoera-barraren ikonoan, kargatzen ari ez denean"</string>
@@ -537,11 +542,11 @@
<string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Laguntzailea"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Arakatzailea"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktuak"</string>
- <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Helbide elektronikoa"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Posta"</string>
<string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Istanteko mezularitza"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musika"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
- <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Egutegia"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
<string name="tuner_full_zen_title" msgid="4540823317772234308">"Erakutsi bolumena kontrolatzeko aukerekin"</string>
<string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ez molestatu"</string>
<string name="volume_dnd_silent" msgid="4363882330723050727">"Bolumen-botoietarako lasterbidea"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Baliteke aplikazioak ez funtzionatzea leiho anitzetan."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. posizioa, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Editatzeko, sakatu birritan."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gehitzeko, sakatu birritan."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. posizioa. Hautatzeko, sakatu birritan."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Kendu da <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>. posiziora eraman da"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Ezarpen bizkorren editorea."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikazioak ez du onartzen pantaila zatitua"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 322197e..5020bd8 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"رد کردن <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> نادیده گرفته شد."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"همه برنامههای اخیر رد شدند."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"باز کردن اطلاعات برنامه <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> در حال شروع به کار است."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"اعلان ردشد."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترلکننده صدا است"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"برای بازیابی کنترلکننده اصلی، لمس کنید."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"درحال استفاده از نمایه کاریتان هستید"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"تنظیمکننده واسط کاربری سیستم"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"نمایش درصد شارژ باتری جاسازی شده"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"نمایش درصد سطح باتری در نماد نوار وضعیت، هنگامی که باتری شارژ نمیشود"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"برنامه ممکن است با چندپنجره کار نکند"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. برای ویرایش دو ضربه سریع بزنید."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. برای افزودن دو ضربه سریع بزنید."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>. برای انتخاب دو ضربه سریع بزنید."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> حذف میشود"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> به موقعیت <xliff:g id="POSITION">%2$d</xliff:g> منتقل شد"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ویرایشگر تنظیمات سریع."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ممکن است برنامه با تقسیم صفحه کار نکند."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 6db0a3e..dca5b12 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hylätään <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> hylättiin."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kaikki viimeisimmät sovellukset on hylätty."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Avaa sovelluksen <xliff:g id="APP">%s</xliff:g> tiedot."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Käynnistetään <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ilmoitus hylätty."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on äänenvoimakkuusvalinta."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Palauta alkuperäinen koskettamalla."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Käytät työprofiilia."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Näytä akun varaus kuvakkeessa"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Näyttää akun varausprosentin tilapalkin kuvakkeessa, kun laitetta ei ladata."</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Sovellus ei ehkä toimi usean ikkunan tilassa."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Muokkaa kaksoisnapauttamalla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lisää kaksoisnapauttamalla."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>. Valitse kaksoisnapauttamalla."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> poistettiin."</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> siirrettiin paikkaan <xliff:g id="POSITION">%2$d</xliff:g>."</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Pika-asetusten muokkausnäkymä"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Sovellus ei ehkä toimi jaetulla näytöllä."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Sovellus ei tue jaetun näytön tilaa."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 89c6826..76a3438 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Ouvre les détails de l\'application <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Lancement de <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touchez pour restaurer l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de charge"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Afficher le pourcentage correspondant au niveau de la pile dans l\'icône de la barre d\'état lorsque l\'appareil n\'est pas en charge."</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Il est possible que l\'application ne fonctionne pas en mode Multi-fenêtre."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Touchez deux fois pour modifier."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Touchez deux fois pour ajouter."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position : <xliff:g id="POSITION">%1$d</xliff:g>. Touchez deux fois pour sélectionner."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> a été supprimé"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> a été déplacé à la position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Éditeur de paramètres rapides."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'application n\'est pas compatible avec l\'écran partagé."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2f99b94..d1ba9e3 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Ouvre les informations sur l\'application <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Lancement de <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> : <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Appuyez pour restaurer l\'interface d\'origine."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de la batterie"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Affichez le pourcentage correspondant au niveau de la batterie dans l\'icône de la barre d\'état lorsque l\'appareil n\'est pas en charge."</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Il est possible que l\'application ne fonctionne pas en mode multifenêtre."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Appuyer deux fois pour modifier."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Appuyer deux fois pour ajouter."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Appuyer deux fois pour sélectionner."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Le bloc \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" a bien été supprimé."</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Le bloc \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" a bien été déplacé à la position <xliff:g id="POSITION">%2$d</xliff:g>."</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Éditeur de configuration rapide."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Application incompatible avec l\'écran partagé."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 45c3626..0f6bedc 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rexeitar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Rexeitouse <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Rexeitáronse todas as aplicacións recentes."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abre a información da aplicación <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación rexeitada"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é o cadro de diálogo de volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar o orixinal."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando o perfil de traballo"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Configurador da IU do sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaxe de batería inserida"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentaxe do nivel de batería na icona da barra de estado cando non está en carga"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Pode que a aplicación non funcione con varias ventás."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dúas veces o elemento para editalo."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dúas veces o elemento para engadilo"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posición <xliff:g id="POSITION">%1$d</xliff:g>. Toca dúas veces o elemento para seleccionalo."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Eliminouse <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> moveuse á posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de configuración rápida."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Pode que a aplicación non funcione coa pantalla dividida."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"A aplicación non é compatible coa función de pantalla dividida."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index ef6a49c..f937362 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખો."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખી."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"તમામ તાજેતરની એપ્લિકેશનો કાઢી નાખી."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ઍપ્લિકેશન માહિતી ખોલો."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી રહ્યું છે."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"સૂચના કાઢી નાખી."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ વૉલ્યૂમ સંવાદ છે"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"મૂળને પુનઃસ્થાપિત કરવા માટે ટચ કરો."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"તમે તમારી કાર્ય પ્રોફાઇલનો ઉપયોગ કરી રહ્યાં છો"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"સિસ્ટમ UI ટ્યૂનર"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"એમ્બેડ કરેલ બૅટરી ટકા બતાવો"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"જ્યારે ચાર્જ ન થઈ રહ્યું હોય ત્યારે સ્થિતિ બાર આયકનની અંદર બૅટરી સ્તર ટકા બતાવો"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"બહુ-વિંડો સાથે અૅપ્લિકેશન કદાચ કામ ન કરે"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"સ્થિતિ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. સંપાદિત કરવા માટે બે વાર ટૅપ કરો."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ઉમેરવા માટે બે વાર ટૅપ કરો."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"સ્થિતિ <xliff:g id="POSITION">%1$d</xliff:g>. પસંદ કરવા માટે બે વાર ટૅપ કરો."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> દૂર કરવામાં આવ્યું છે"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ને <xliff:g id="POSITION">%2$d</xliff:g> સ્થિતિ પર ખસેડ્યું"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ઝડપી સેટિંગ્સ સંપાદક."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"વિભાજિત-સ્ક્રીન સાથે ઍપ્લિકેશન કદાચ કામ ન કરે."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 1ba0caf..b30d7a6 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> को ख़ारिज करें."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खा़रिज कर दिया गया."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"हाल ही के सभी ऐप्लिकेशन ख़ारिज कर दिए गए."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन जानकारी खोलें."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ हो रहा है."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"नोटिफिकेशन खारिज की गई."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> वॉल्यूम संवाद है"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूल वॉल्यूम को फिर से लाने के लिए स्पर्श करें."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आप अपनी कार्य प्रोफ़ाइल का उपयोग कर रहे हैं"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम UI ट्यूनर"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेड किया गया बैटरी प्रतिशत दिखाएं"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"जब चार्ज नहीं किया जा रहा हो तब स्थिति बार आइकन में बैटरी स्तर का प्रतिशत दिखाएं"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"हो सकता है कि ऐप्लिकेशन एकाधिक विंडो के साथ काम ना करे"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करने के लिए डबल टैप करें."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. जोड़ने के लिए डबल टैप करें."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>. चुनने के लिए डबल टैप करें."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> निकाल दिया गया है"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को <xliff:g id="POSITION">%2$d</xliff:g> स्थिति में ले जाया गया"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"त्वरित सेटिंग संपादक."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 81c6276..24e8f8d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbacivanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> odbačena je."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Odbačene su sve nedavne aplikacije."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otvaranje informacija o aplikaciji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavijest je odbačena."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> predstavlja dijaloški okvir za upravljanje glasnoćom"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili izvorno."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Upotrebljavate radni profil"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Ugađanje korisničkog sučelja sustava"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikazivanje postotka razine baterije na ikoni trake statusa kada se ne puni"</string>
@@ -597,7 +602,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput da biste uredili."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dodirnite dvaput da biste dodali."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>. Dodirnite dvaput da biste odabrali."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Pločica <xliff:g id="TILE_NAME">%1$s</xliff:g> uklonjena"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Pločica <xliff:g id="TILE_NAME">%1$s</xliff:g> premještena je na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Uređivač brzih postavki."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podijeljeni zaslon."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b7ac8a4..cf69932 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"A(z) <xliff:g id="APP">%s</xliff:g> elvetése."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eltávolítva."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Az összes alkalmazás eltávolítva a nemrég használtak közül."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"A(z) <xliff:g id="APP">%s</xliff:g> alkalmazás adatainak megnyitása."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"A(z) <xliff:g id="APP">%s</xliff:g> indítása."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Értesítés elvetve."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás kezeli a hangerőt"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Érintse meg az eredeti érték visszaállításához."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"A munkaprofilt használja"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Kezelőfelület-hangoló"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"A beépített akkumulátor töltöttségi szintjének megjelenítése"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Az akkumulátor töltöttségi szintjének megjelenítése az állapotsori ikonban, amikor az eszköz nem töltődik"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. pozíció: <xliff:g id="TILE_NAME">%2$s</xliff:g>. Koppintson duplán a szerkesztéshez."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Koppintson duplán a hozzáadáshoz."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. pozíció. Koppintson duplán a kiválasztáshoz."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"A(z) <xliff:g id="TILE_NAME">%1$s</xliff:g> eltávolítva"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"A(z) <xliff:g id="TILE_NAME">%1$s</xliff:g> áthelyezve a(z) <xliff:g id="POSITION">%2$d</xliff:g>. pozícióba"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Gyorsbeállítások szerkesztője"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 7e4e01a..d58b63e 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Անտեսել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>-ը անտեսված է:"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Բոլոր վերջին հավելվածները հեռացվել են ցուցակից:"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Բացել <xliff:g id="APP">%s</xliff:g> հավելվածի մասին տեղեկությունները"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Մեկնարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ծանուցումը անտեսվեց:"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Դիպչեք՝ սկզբնօրինակը վերականգնելու համար:"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Դուք օգտագործում եք ձեր աշխատանքային պրոֆիլը"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Համակարգի ՕՄ-ի կարգավորիչ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Ցուցադրել ներկառուցված մարտկոցի տոկոսայնությունը"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Ցուցադրել մարտկոցի լիցքավորման տոկոսայնությունը կարգավիճակի գոտու պատկերակի վրա, երբ այն չի լիցքավորվում"</string>
@@ -533,7 +538,7 @@
<string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Ծանուցումներ"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Ստեղնային դյուրանցումներ"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Փոխարկել մուտքագրման եղանակը"</string>
- <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Գործադիրներ"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Հավելվածներ"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Օգնություն"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Դիտարկիչ"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Կոնտակտներ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Հավելվածը չի կարող աշխատել բազմապատուհան ռեժիմում"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>: Կրկնակի հպեք՝ փոխելու համար:"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>: Կրկնակի հպեք՝ ավելացնելու համար:"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>: Կրկնակի հպեք՝ ընտրելու համար:"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը հեռացվել է"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը տեղափոխվել է դեպի <xliff:g id="POSITION">%2$d</xliff:g> դիրք"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Արագ կարգավորումների խմբագրիչ:"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում:"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 2b51426..cab43c1 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Menyingkirkan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> disingkirkan."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaru telah ditutup."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Buka info aplikasi <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Memulai <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifikasi disingkirkan."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda menggunakan profil kerja"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Penyetel Antarmuka Pengguna Sistem"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Tampilkan persentase baterai yang tersemat"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Tampilkan persentase tingkat baterai dalam ikon bilah status saat tidak mengisi daya"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ketuk dua kali untuk mengedit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ketuk dua kali untuk menambahkan."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>. Ketuk dua kali untuk memilih."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> dihapus"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> dpindahkan ke posisi <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor setelan cepat."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App tidak mendukung layar terpisah."</string>
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 1dc37df..f67f4c1 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hunsa <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> vísað frá."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Öll nýleg forrit fjarlægð."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Opna forritsupplýsingar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Ræsir <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Tilkynningu lokað."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er hljóðstyrksvalmyndin"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Snertu til að færa í upprunalegt horf."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Þú ert að nota vinnusniðið"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Fínstillingar kerfisviðmóts"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Sýna innfellda rafhlöðustöðu"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Sýna rafhlöðustöðuna í stöðustikunni þegar tækið er ekki í hleðslu"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Hugsanlegt er að forritið virki ekki í mörgum gluggum"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Staða <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ýttu tvisvar til að breyta."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ýttu tvisvar til að bæta við."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Staða <xliff:g id="POSITION">%1$d</xliff:g>. Ýttu tvisvar til að velja."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> var fjarlægð"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> færð í stöðu <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Flýtistillingaritill."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Hugsanlega virkar forritið ekki ef skjánum er skipt upp."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Forritið styður ekki að skjánum sé skipt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 4a8ba99..ea1bb00 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Elimina <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eliminata."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tutte le applicazioni recenti sono state rimosse."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Mostra informazioni sull\'applicazione <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Avvio di <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifica eliminata."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> rappresenta la finestra di dialogo relativa al volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tocca per ripristinare l\'originale."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Stai utilizzando il profilo di lavoro"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintetizzatore interfaccia utente di sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostra percentuale batteria incorporata"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra la percentuale di carica della batteria nell\'icona della barra di stato quando non è in carica"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"L\'app potrebbe non funzionare con la modalità multi-finestra"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tocca due volte per modificare."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tocca due volte per aggiungere."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>. Tocca due volte per selezionare."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Il riquadro <xliff:g id="TILE_NAME">%1$s</xliff:g> è stato rimosso"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Il riquadro <xliff:g id="TILE_NAME">%1$s</xliff:g> è stato spostato nella posizione <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor di impostazioni rapide."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"L\'app potrebbe non funzionare con lo schermo diviso."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'app non supporta la modalità Schermo diviso."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index d41d50d..88bfafc 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"סגור את <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> נדחה."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"כל האפליקציות האחרונות נסגרו."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"פתח מידע על האפליקציה <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"מפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"הודעה נדחתה."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"אתה משתמש בפרופיל העבודה שלך"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"הצג בשורת הסטטוס את אחוז עוצמת הסוללה"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"הצג את אחוז עוצמת הסוללה בתוך הסמל שבשורת הסטטוס כשהמכשיר אינו בטעינה"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"ייתכן שהאפליקציה לא תפעל עם ריבוי חלונות"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. הקש פעמיים כדי לערוך."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. הקש פעמיים כדי להוסיף."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>. הקש פעמיים כדי לבחור."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> הוסר"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> הועבר למיקום <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"עורך הגדרות מהירות."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ייתכן שהיישום לא יפעל עם מסך מפוצל."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"האפליקציה אינה תומכת במסך מפוצל."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 83a9888..04a392c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>を削除します。"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>は削除されました。"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近のアプリケーションをすべて消去しました。"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"「<xliff:g id="APP">%s</xliff:g>」のアプリ情報を開きます。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>を開始しています。"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知が削除されました。"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"タップすると元の音量ダイアログが復元されます。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"仕事用プロファイルを使用しています"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"システムUI調整ツール"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"内蔵電池の残量の割合を表示する"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"充電していないときには電池残量の割合をステータスバーアイコンに表示する"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"アプリはマルチウィンドウでは動作しないことがあります"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> の <xliff:g id="TILE_NAME">%2$s</xliff:g> を編集するにはダブルタップします。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を追加するにはダブルタップします。"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> に配置します。選択するにはダブルタップします。"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を削除しました"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> をポジション <xliff:g id="POSITION">%2$d</xliff:g> に移動しました"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"クイック設定エディタ"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"アプリは分割画面では動作しないことがあります。"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"アプリで分割画面がサポートされていません。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 5008fe0..fbd97f0 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-ის უგულებელყოფა."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ყველა ბოლო აპლიკაცია გაუქმდა."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> აპლიკაციის ინფორმაციის გახსნა."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> იწყება."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"შეტყობინება წაიშალა."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ხმოვან დიალოგშია"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ორიგინალის აღდგენისათვის, შეეხეთ."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"თქვენ სამსახურის პროფილს იყენებთ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"სისტემის UI ტუნერი"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"ჩამაგრებული ბატარეის პროცენტის ჩვენება"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ბატარეის დონის პროცენტის ჩვენება სტატუსის ზოლის ხატულას შიგნით, როდესაც არ იტენება"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"აპმა შეიძლება არ იმუშაოს მრავალი ფანჯრის რეჟიმში"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. რედაქტირებისთვის, შეეხეთ ორმაგად."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. დასამატებლად, შეეხეთ ორმაგად."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>. ასარჩევად, შეეხეთ ორმაგად."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ამოიშალა"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> გადატანილია პოზიციაზე <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"სწრაფი პარამეტრების რედაქტორი."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index ff33f05..4bc585a 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> қолданбасынан бас тарту."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> алынып тасталған."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Барлық жақындағы қабылданбаған қолданбалар."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> қолданбасы туралы ақпаратты ашады."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> іске қосылуда."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Хабар алынып тасталды."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнұсқаны қалпына келтіру үшін түртіңіз."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Сіз жұмыс профиліңізді пайдаланып жатырсыз"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Жүйелік пайдаланушылық интерфейс тюнері"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Ендірілген батарея пайыздық шамасын көрсету"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Зарядталмай тұрғанда, күй жолағы белгішесінің ішінде батарея деңгейінің пайыздық шамасын көрсетеді"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Қолданба көп тереземен жұмыс істемеуі мүмкін"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g> орны, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Өңдеу үшін екі рет түртіңіз."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Қосу үшін екі рет түртіңіз."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> орны. Таңдау үшін екі рет түртіңіз."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> жойылды"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> орнына жылжытылды"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Жылдам параметрлер өңдегіші."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Қолданба бөлінген экранда жұмыс істемеуі мүмкін."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Қодланба бөлінген экранды қолдамайды."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index b69f893..9f66f3b 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"បោះបង់ <xliff:g id="APP">%s</xliff:g> ។"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"កម្មវិធីថ្មីៗទាំងអស់ត្រូវបានបោះបង់។"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"បើកព័ត៌មានកម្មវិធី <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"ចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ។"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"បានបដិសេធការជូនដំណឹង"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ប៉ះដើម្បីស្តារច្បាប់ដើម។"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"អ្នកកំពុងប្រើប្រវត្តិរូបការងាររបស់អ្នក"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"កម្មវិធីសម្រួល UI ប្រព័ន្ធ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"បង្ហាញភាគរយថាមពលថ្មដែលបានបង្កប់"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"បង្ហាញភាគរយនៃកម្រិតថាមពលថ្មនៅក្នុងរូបតំណាងរបារស្ថានភាពនៅពេលមិនសាកថ្ម"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"កម្មវិធីអាចនឹងមិនដំណើរការជាមួយពហុវិនដូទេ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ទីតាំង <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>, ប៉ះពីរដងដើម្បីកែ"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>, ប៉ះពីរដងដើម្បីបន្ថែម"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ទីតាំង <xliff:g id="POSITION">%1$d</xliff:g>, ប៉ះពីរដងដើម្បីជ្រើស"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ត្រូវបានយកចេញ"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> បានផ្លាស់ទីទៅទីតាំង <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"កម្មវិធីកែការកំណត់រហ័ស"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"កម្មវិធីអាចនឹងមិនដំណើរការនៅលើអេក្រង់បំបែកទេ"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 1ce14dd5..41537a39 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸು."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ಇತ್ತೀಚಿನ ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ ತೆರೆಯಿರಿ."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ಅಧಿಸೂಚನೆ ವಜಾಗೊಂಡಿದೆ."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ಮೂಲ ಮರುಸ್ಥಾಪಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ನೀವು ಬಳಸುತ್ತಿರುವಿರಿ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"ಎಂಬೆಡ್ ಮಾಡಲಾದ ಬ್ಯಾಟರಿ ಶೇಕಡಾ ತೋರಿಸಿ"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ಚಾರ್ಜ್ ಮಾಡದಿರುವಾಗ ಸ್ಥಿತಿ ಪಟ್ಟಿ ಐಕಾನ್ ಒಳಗೆ ಬ್ಯಾಟರಿ ಮಟ್ಟದ ಶೇಕಡಾವನ್ನು ತೋರಿಸಿ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"ಬಹು ವಿಂಡೋದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ಸ್ಥಾನ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ಸಂಪಾದಿಸಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ಸೇರಿಸಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ಸ್ಥಾನ <xliff:g id="POSITION">%1$d</xliff:g>. ಆಯ್ಕೆಮಾಡಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="POSITION">%2$d</xliff:g> ಸ್ಥಾನಕ್ಕೆ <xliff:g id="TILE_NAME">%1$s</xliff:g> ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಸಂಪಾದಕ."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ವಿಭಜಿಸಿದ ಪರದೆಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index a8a2a0a..702c489 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>을(를) 숨깁니다."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>이(가) 제거되었습니다."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"최근 사용한 애플리케이션을 모두 닫았습니다."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> 애플리케이션 정보를 엽니다."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>을(를) 시작하는 중입니다."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"알림이 제거되었습니다."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"원본을 복원하려면 터치하세요."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"직장 프로필을 사용하고 있습니다."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"시스템 UI 튜너"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"내장형 배터리 잔량 비율 표시"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"충전 중이 아닌 경우 상태 표시줄 아이콘 내에 배터리 잔량 비율 표시"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"앱이 멀티 윈도우에서 작동하지 않을 수 있습니다."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"위치 <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. 수정하려면 두 번 탭하세요."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. 추가하려면 두 번 탭하세요."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"위치 <xliff:g id="POSITION">%1$d</xliff:g>. 선택하려면 두 번 탭하세요."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 타일이 삭제되었습니다."</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 타일을 위치 <xliff:g id="POSITION">%2$d</xliff:g>(으)로 이동함"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"빠른 설정 편집기"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"앱이 화면 분할을 지원하지 않습니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 6a2d77f..23349eb 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> этибарга албоо."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> жок болду."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Акыркы колдонмолордун баары көз жаздымда калтырылды."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> колдонмосу жөнүндө маалыматты ачыңыз."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> иштеп баштоодо."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Эскертме жок кылынды."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> үндү катуулатуу диалогу"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнусканы калыбына келтирүү үчүн тийип коюңуз."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Жумуш профилиңизди колдонуп жатасыз"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Батарянын кубатнын деңгээли пайыз менен көрсөтлсүн"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Түзмөк кубаттанбай турганда, батареянын деңгээли статус тилкесинде көрүнүп турат"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Бир нече терезе режиминде колдонмо иштебей калышы мүмкүн"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Түзөтүү үчүн эки жолу таптаңыз."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Кошуу үчүн эки жолу таптаңыз."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>. Тандоо үчүн эки жолу таптаңыз."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> алынып салынды"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> деген <xliff:g id="POSITION">%2$d</xliff:g>-орунга жылдырылды"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Ыкчам жөндөөлөр түзөткүчү."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Колдонмодо экран бөлүнбөшү мүмкүн."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Колдонмодо экран бөлүнбөйт."</string>
</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 26a81c8..c40797c 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -24,4 +24,14 @@
<dimen name="docked_divider_handle_width">2dp</dimen>
<dimen name="docked_divider_handle_height">16dp</dimen>
+
+ <dimen name="qs_tile_margin_top">2dp</dimen>
+ <dimen name="qs_brightness_padding_top">0dp</dimen>
+
+ <dimen name="battery_detail_graph_space_top">9dp</dimen>
+ <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
+
+ <integer name="quick_settings_num_columns">4</integer>
+ <bool name="quick_settings_wide">true</bool>
+ <dimen name="qs_detail_margin_top">0dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 601cc2a..22acd02 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ປິດ <xliff:g id="APP">%s</xliff:g> ໄວ້."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"ປິດ <xliff:g id="APP">%s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ທຸກແອັບພລິເຄຊັນບໍ່ດົນມານີ້ຖືກປ່ອຍໄປ."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"ເປີດຂໍ້ມູນແອັບພລິເຄຊັນ <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"ກຳລັງເປີດ <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ປິດການແຈ້ງເຕືອນແລ້ວ."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນໜ້າຕ່າງລະດັບສຽງ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາຜັດເພື່ອກູ້ຄືນຕົ້ນສະບັບ."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ທ່ານກຳລັງໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"ສະແດງເປີເຊັນແບັດເຕີຣີທີ່ຕິດມາ"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ສະແດງເປີເຊັນລະດັບແບັດເຕີຣີຢູ່ດ້ານໃນໄອຄອນແຖບສະຖານະ ເມື່ອບໍ່ສາກຢູ່"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ກັບຫຼາຍໜ້າຈໍ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອແກ້ໄຂ."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອເພີ່ມ."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>. ແຕະສອງເທື່ອເພື່ອເລືອກ."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"ລຶບ <xliff:g id="TILE_NAME">%1$s</xliff:g> ອອກແລ້ວ"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ຍ້າຍໄປຕຳແໜ່ງ <xliff:g id="POSITION">%2$d</xliff:g> ແລ້ວ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 866abf3..ac32b30 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Atsisakyti <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Atsisakyta programos „<xliff:g id="APP">%s</xliff:g>“."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Atsisakyta visų naujausių programų."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Atidaryti programos „<xliff:g id="APP">%s</xliff:g>“ informaciją."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Paleidžiama <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"„<xliff:g id="APP">%1$s</xliff:g>“ <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pranešimo atsisakyta."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra garsumo valdymo dialogo langas"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Palieskite, kad atkurtumėte originalą."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Naudojate darbo profilį"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sistemos naudotojo sąsajos derinimo priemonė"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Rodyti įterptą akumuliat. įkrovos procentinę vertę"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Rodyti akumuliatoriaus įkrovos lygio procentinę vertę būsenos juostos piktogramoje, kai įrenginys nėra įkraunamas"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Naudojant kelių langų funkciją programa gali neveikti"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g> padėtis, išklotinės elementas „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Dukart palieskite, kad redaguotumėte."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Dukart palieskite, kad pridėtumėte."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> padėtis. Dukart palieskite, kad pasirinktumėte."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ pašalintas"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ perkeltas į <xliff:g id="POSITION">%2$d</xliff:g> padėtį"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Sparčiųjų nustatymų redagavimo priemonė."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Programa gali neveikti naudojant skaidytą ekraną."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programoje nepalaikomas skaidytas ekranas."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 9c32b31..218178a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Nerādīt lietotni <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Lietotne <xliff:g id="APP">%s</xliff:g> vairs netiek rādīta."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Visas nesen izmantotās lietojumprogrammas tika noņemtas."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Atveriet lietojumprogrammas <xliff:g id="APP">%s</xliff:g> informāciju."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Notiek lietotnes <xliff:g id="APP">%s</xliff:g> palaišana."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Paziņojums netiek rādīts."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ir skaļuma dialoglodziņš"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Pieskarieties, lai atjaunotu sākotnējo."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jūs izmantojat darba profilu."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sistēmas saskarnes regulators"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Rādīt akumulatora uzlādes līmeni procentos"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Rādīt akumulatora uzlādes līmeni procentos statusa joslas ikonā, kad netiek veikta uzlāde"</string>
@@ -597,7 +602,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Iespējams, lietotnē nedarbosies vairāku logu režīms."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. pozīcija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Lai rediģētu, veiciet dubultskārienu."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lai pievienotu, veiciet dubultskārienu."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. pozīcija. Lai atlasītu, veiciet dubultskārienu."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Elements <xliff:g id="TILE_NAME">%1$s</xliff:g> ir noņemts"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Elements <xliff:g id="TILE_NAME">%1$s</xliff:g> ir pārvietots uz <xliff:g id="POSITION">%2$d</xliff:g>. pozīciju"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Ātro iestatījumu redaktors."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Iespējams, lietotnē nedarbosies ekrāna sadalīšana."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 7f2fc15..8d25796 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отфрли <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> е отфрлена."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Сите неодамнешни апликации се отфрлени."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Отвори информации за апликацијата <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Се стартува <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известувањето е отфрлено."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> е дијалог за јачина на звук"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Допрете за да го вратите оригиналот."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Го користите работниот профил"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Адаптер на УИ на системот"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Прикажи вграден процент на батеријата"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Прикажи процент на ниво на батеријата во внатрешноста на иконата со статусна лента кога не се полни"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Апликацијата може да не работи со повеќе прозорци"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Место <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Допрете двапати за уредување."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Допрете двапати за додавање."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Место <xliff:g id="POSITION">%1$d</xliff:g>. Допрете двапати за избирање."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> е отстранета"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> е преместена на место <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Уредник за брзи поставки."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Апликацијата можеби нема да работи во поделен екран."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Апликацијата не поддржува поделен екран."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index dfe992c..e44642d2 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> നിരസിക്കുക."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> നിരസിച്ചു."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"അടുത്തിടെയുള്ള എല്ലാ അപ്ലിക്കേഷനും നിരസിച്ചു."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ആപ്പ് വിവരങ്ങൾ തുറക്കുക."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കുന്നു."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"അറിയിപ്പ് നിരസിച്ചു."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ആദ്യത്തേത് പുനഃസ്ഥാപിക്കാൻ സ്പർശിക്കുക."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"സിസ്റ്റം UI ട്യൂണർ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"എംബഡ് ചെയ്ത ബാറ്ററി ശതമാനം കാണിക്കുക"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ചാർജ്ജുചെയ്യാതിരിക്കുമ്പോൾ സ്റ്റാറ്റസ് ബാർ ഐക്കണിൽ ബാറ്ററി ലെവൽ ശതമാനം കാണിക്കുക"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"മൾട്ടി-വിൻഡോയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. എഡിറ്റുചെയ്യുന്നതിന് രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ചേർക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>. തിരഞ്ഞെടുക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കംചെയ്യുന്നു"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"സ്ഥാനം <xliff:g id="POSITION">%2$d</xliff:g>-ലേക്ക് <xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കി"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ദ്രുത ക്രമീകരണ എഡിറ്റർ."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"സ്പ്ലിറ്റ്-സ്ക്രീനിനൊപ്പം ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 80cb8f2..e3fd349 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -166,8 +166,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-г хаах."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> байхгүй."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Хамгийн сүүлийн бүх програмыг арилгасан байна."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> апп-н мэдээллийг нээнэ үү."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж байна."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Мэдэгдэл хаагдсан."</string>
@@ -419,6 +418,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Анхны хувилбарыг эргүүлэн хадгалахыг хүсвэл хүрнэ үү."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Та өөрийн ажлын профайлыг ашиглаж байна"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Системийн UI Тохируулагч"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Залгаатай тэжээлийн хувийг харуулах"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Тэжээлийн хувийг цэнэглээгүй байх үед статусын хэсэгт харуулна уу"</string>
@@ -594,7 +599,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Олон цонхтой үед апп ажиллахгүй байж болзошгүй"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Байршил <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Засахын тулд 2 удаа дарна уу."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Нэмэхийн тулд 2 удаа дарна уу."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Албан тушаал <xliff:g id="POSITION">%1$d</xliff:g>. Сонгохын тулд 2 удаа дарна уу."</string>
@@ -604,4 +608,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г устгасан"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г <xliff:g id="POSITION">%2$d</xliff:g> байршилд зөөсөн"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Түргэн тохиргоо засварлагч."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Апп хуваагдсан дэлгэцэд ажиллахгүй."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 76dfcd5..2cd5ed8 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> डिसमिस करा."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> डिसमिस केला."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"अलीकडील सर्व अनुप्रयोग डिसमिस झाले."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> अनुप्रयोग माहिती उघडा."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करीत आहे."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना डिसमिस केल्या."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा व्हॉल्यूम संवाद आहे"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूळ पुनर्संचयित करण्यासाठी स्पर्श करा."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आपण आपले कार्य प्रोफाईल वापरत आहात"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज होत नसताना स्टेटस बार चिन्हामध्ये बॅटरी पातळी टक्केवारी दर्शवा"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"एकाधिक-विंडो सह अॅप कार्य करू शकत नाही"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिती <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करण्यासाठी दोनदा टॅप करा."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> . जोडण्यासाठी दोनदा टॅप करा."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिती <xliff:g id="POSITION">%1$d</xliff:g>. निवडण्यासाठी दोनदा टॅप करा."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ला काढले आहे"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ला <xliff:g id="POSITION">%2$d</xliff:g> स्थितीवर हलविले"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"द्रुत सेटिंग्ज संपादक."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 9401198..e11f7ff 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ketepikan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ditolak."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaharu diketepikan."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Buka maklumat aplikasi <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Memulakan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan diketepikan."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah dialog kelantangan"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan yang asal."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda sedang menggunakan profil kerja"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Penala UI Sistem"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Tunjukkan peratusan bateri terbenam"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Tunjukkan peratusan aras bateri dalam ikon bar status semasa tidak mengecas"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Apl mungkin tidak berfungsi dengan berbilang tetingkap"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dwiketik untuk mengedit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dwiketik untuk menambah."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>. Dwiketik untuk memilih."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> dialih keluar"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> dialihkan ke kedudukan <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor tetapan pantas."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Apl mungkin tidak berfungsi dengan skrin pisah."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Apl tidak menyokong skrin pisah."</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 6964750..67ce1fc 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ကို ပယ်လိုက်ရန်"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ထုတ်ထားသည်။"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"မကြာသေးမီက အပလီကေးရှင်းများအားလုံး ဖယ်ထုတ်ပြီးပါပြီ။"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> အက်ပ်အချက်အလက်ကို ဖွင့်ပါ။"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>ကို စတင်နေသည်။"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g><xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"အကြောင်းကြားချက်ကိုဖယ်ရှားပြီး"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အသံဒိုင်ယာလော့ခ်ဖြစ်သည်"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"မူရင်းအားပြန်လည်သိမ်းဆည်းရန် ထိပါ။"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"သင်သည် အလုပ်ပရိုဖိုင်းအား သုံးနေသည်"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"စနစ် UI ဖမ်းစက်"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"မြုတ်ထားသည့် ဘတ်ထရီ ရာခိုင်နှုန်းကို ပြပါ"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"အားမသွင်းနေစဉ်တွင် ဘတ်ထရီအဆင့် ရာခိုင်နှုန်းကို အခြေနေပြဘား အိုင်ကွန်တွင် ပြပါ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"အက်ပ်သည် ဝင်းဒိုးများတပြိုင်နက်ဖွင့်ခြင်းကို မပံ့ပိုးပါ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>၊ <xliff:g id="TILE_NAME">%2$s</xliff:g> နေရာ။ တည်းဖြတ်ရန် နှစ်ချက်တို့ပါ။"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>။ ပေါင်းထည့်ရန် နှစ်ချက်တို့ပါ။"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> နေရာ။ ရွေးချယ်ရန် နှစ်ချက်တို့ပါ။"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကိုဖယ်ရှားလိုက်ပါပြီ"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကို <xliff:g id="POSITION">%2$d</xliff:g> နေရာသို့ ရွှေ့လိုက်ပါပြီ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"မျက်နှာပြင် ခွဲခြမ်းပြသမှုဖြင့် အက်ပ်သည် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index eed5f36..6d68342 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Avvis <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> avvist."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle nylig brukte apper er avvist."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Åpne appinformasjonen for <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starter <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Varselet ble skjult."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er volumdialogen"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Trykk for å gå tilbake til den opprinnelige volumdialogen."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruker jobbprofilen din"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Vis prosent for det innebygde batteriet"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Vis batterinivåprosenten inni statusfeltikonet når du ikke lader"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Plassering <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dobbelttrykk for å endre."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dobbelttrykk for å legge til."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Plassering <xliff:g id="POSITION">%1$d</xliff:g>. Dobbelttrykk for å velge."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> er fjernet"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> er flyttet til plassering <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigeringsvindu for hurtiginnstillinger."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Det kan hende at appen ikke fungerer med delt skjerm."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen støtter ikke delt skjerm."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 836dc4b..231a28a 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> खारेज गर्नुहोस्।"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"सबै हालका अनुप्रयोगहरू खारेज गरियो।"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> अनुप्रयोग सम्बन्धी जानकारी खोल्नुहोस्।"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>सुरु गर्दै।"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारेज।"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"तपाईँले कार्य प्रोफाइल प्रयोग गर्दै हुनुहुन्छ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"प्रणाली UI ट्युनर"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज नगरेको बेला वस्तुस्थिति पट्टी आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"अनुप्रयोग बहु-विन्डोमा काम नगर्न सक्छ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। सम्पादन गर्नका लागि डबल ट्याप गर्नुहोस्।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। थप्नका लागि डबल ट्याप गर्नुहोस्।"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>। चयन गर्नका लागि डबल ट्याप गर्नुहोस्।"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई हटाइयो"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई स्थिति <xliff:g id="POSITION">%2$d</xliff:g> मा सारियो"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"द्रुत सेटिङ सम्पादक।"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"अनुप्रयोगले विभाजित-स्क्रिनमा काम नगर्न सक्छ।"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 41075e39..700fd88 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> sluiten."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwijderd."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle recente apps gesloten."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"App-gegevens voor <xliff:g id="APP">%s</xliff:g> openen."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> starten."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Melding verwijderd."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is het volumedialoogvenster"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tik hierop om het origineel te herstellen."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"U gebruikt je werkprofiel"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Systeem-UI-tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu weergeven"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Accupercentage weergeven in het pictogram op de statusbalk wanneer er niet wordt opgeladen"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"De app werkt mogelijk niet met meerdere vensters"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Positie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te bewerken."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om toe te voegen."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Positie <xliff:g id="POSITION">%1$d</xliff:g>. Dubbeltik om te selecteren."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is verwijderd"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is verplaatst naar positie <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor voor \'Snelle instellingen\'."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"App werkt mogelijk niet met gesplitst scherm."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App biedt geen ondersteuning voor gesplitst scherm."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 1703a2f..d2166a4a 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ਰੱਦ ਕੀਤਾ।"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ਸਾਰੀਆਂ ਹਾਲੀਆ ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੱਦ ਕੀਤੀਆਂ।"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ਐਪਲੀਕੇਸ਼ਨਾਂ ਜਾਣਕਾਰੀ ਖੋਲ੍ਹੋ।"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ਸੂਚਨਾ ਰੱਦ ਕੀਤੀ।"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ਅਸਲੀ ਨੂੰ ਰੀਸਟੋਰ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI ਟਿਊਨਰ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"ਜੋਡ਼ੀ ਗਈ ਬੈਟਰੀ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ਜਦੋਂ ਚਾਰਜ ਨਾ ਹੋ ਰਹੀ ਹੋਵੇ ਤਾਂ ਸਥਿਤੀ ਬਾਰ ਦੇ ਅੰਦਰ ਬੈਟਰੀ ਪੱਧਰ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਮਲਟੀ-ਵਿੰਡੋ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ਸੰਪਾਦਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>। ਚੁਣਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ ਹਟਾਇਆ ਗਿਆ"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ <xliff:g id="POSITION">%2$d</xliff:g> ਸਥਿਤੀ \'ਤੇ ਤਬਦੀਲ ਕੀਤਾ ਗਿਆ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 297b849..2f1f889 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Usuń stąd <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>: zamknięto."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Wszystkie ostatnie aplikacje zostały zamknięte."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otwórz informacje o aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Uruchamiam <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Zamknięto powiadomienie."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> steruje głośnością"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dotknij, by przywrócić pierwotną."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Używasz profilu do pracy"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Kalibrator System UI"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Pokaż procent naładowania baterii"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Pokaż procent naładowania baterii w ikonie na pasku stanu, gdy telefon się nie ładuje"</string>
@@ -598,7 +603,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Położenie <xliff:g id="POSITION">%1$d</xliff:g>, kafelek <xliff:g id="TILE_NAME">%2$s</xliff:g>. Kliknij dwukrotnie, by edytować."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"Kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g>. Kliknij dwukrotnie, by dodać."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Położenie <xliff:g id="POSITION">%1$d</xliff:g>. Kliknij dwukrotnie, by wybrać."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g> został usunięty"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g> przeniesiony w położenie <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Edytor szybkich ustawień."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacja może nie działać przy podzielonym ekranie."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacja nie obsługuje dzielonego ekranu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index eb08d99..9b778cc 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abre informações do app <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentagem de nível de bateria dentro do ícone da barra de status quando não estiver carregando"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"É possível que o app não funcione com várias janelas"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posição <xliff:g id="POSITION">%1$d</xliff:g>. Toque duas vezes para selecionar."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> é removido"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> movido para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de configurações rápidas."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"É possível que o app não funcione com o recurso de divisão de tela."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"O app não é compatível com a divisão de tela."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index bba2f3e..69a4dad 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ignorado."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todas as aplicações recentes foram ignoradas."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abrir as informações da aplicação <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"A iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação ignorada."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo do volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Está a utilizar o seu perfil de trabalho"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador da interface do sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar percentagem da bateria incorporada"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar a percentagem do nível da bateria no ícone da barra de estado quando não estiver a carregar"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"A aplicação pode não funcionar com multijanelas"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posição <xliff:g id="POSITION">%1$d</xliff:g>. Toque duas vezes para selecionar."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> removido"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> movido para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de definições rápidas."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"A aplicação pode não funcionar com o ecrã dividido."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"A aplicação não é compatível com o ecrã dividido."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index eb08d99..9b778cc 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Abre informações do app <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentagem de nível de bateria dentro do ícone da barra de status quando não estiver carregando"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"É possível que o app não funcione com várias janelas"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posição <xliff:g id="POSITION">%1$d</xliff:g>. Toque duas vezes para selecionar."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> é removido"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> movido para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de configurações rápidas."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"É possível que o app não funcione com o recurso de divisão de tela."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"O app não é compatível com a divisão de tela."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 81d0456..50289f3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Închideți <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> a fost eliminată."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toate aplicațiile recente au fost închise."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Deschideți informațiile despre aplicația <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Se inițiază <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificarea a fost închisă."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> afișează caseta de dialog pentru volum"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Atingeți pentru a reveni la setarea inițială."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Acum folosiți profilul de serviciu"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Afișați procentajul bateriei încorporat"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Afișați procentajul cu nivelul bateriei în interiorul pictogramei din bara de stare, atunci când nu se încarcă"</string>
@@ -597,7 +602,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Este posibil ca aplicația să nu funcționeze cu ferestre multiple"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Atingeți de două ori pentru a edita."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Atingeți de două ori pentru a adăuga."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>. Atingeți de două ori pentru a selecta."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Caseta <xliff:g id="TILE_NAME">%1$s</xliff:g> este eliminată"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Caseta <xliff:g id="TILE_NAME">%1$s</xliff:g> a fost mutată pe poziția <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editorul pentru setări rapide."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplicația nu acceptă ecranul împărțit."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 86f0ec4..0347b03 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Удаление приложения <xliff:g id="APP">%s</xliff:g> из списка."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" удалено из списка."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Все недавние приложения закрыты."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Открыть информацию о приложении \"<xliff:g id="APP">%s</xliff:g>\""</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запуск приложения <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Уведомление закрыто"</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> назначено регулятором громкости"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Нажмите, чтобы восстановить приложение по умолчанию."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Вы перешли в рабочий профиль"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Показывать уровень заряда батареи в процентах"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Когда устройство работает в автономном режиме, процент заряда батареи показан в строке состояния"</string>
@@ -541,7 +546,7 @@
<string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакты"</string>
<string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Эл. почта"</string>
<string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Чат"</string>
- <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка."</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календарь"</string>
<string name="tuner_full_zen_title" msgid="4540823317772234308">"Показывать при нажатии кнопок регулировки громкости"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложение не поддерживает многооконный режим"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, кнопка \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Чтобы изменить, нажмите дважды."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"Кнопка \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\". Чтобы добавить, нажмите дважды."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>. Чтобы выбрать, нажмите дважды."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Кнопка \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" удалена"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Кнопка \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" теперь занимает позицию <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Редактор быстрых настроек."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Приложение не поддерживает разделение экрана."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Приложение не поддерживает разделение экрана."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 5a2f849..d92b0e8 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ඉවතලන්න."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> අස් කර ඇත."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"සියලුම මෑත යෙඳුම් අස් කරන ලදි."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> යෙදුම් තොරතුරු විවෘත කරයි."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කරමින්."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"දැනුම්දීම නිෂ්ප්රභා කරඇත."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"මුල් තත්ත්වය නැවත ප්රතිසාධනය කිරීමට ස්පර්ශ කරන්න."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ඔබ ඔබේ කාර්යාල පැතිකඩ භාවිත කරමින් සිටී"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"පද්ධති UI සුසරකය"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"කාවද්දන ලද බැටරි ප්රතිශතය පෙන්වන්න"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ආරෝපණය නොවන විට තත්ත්ව තීරු නිරූපකය ඇතුළත බැටරි මට්ටම් ප්රතිශතය පෙන්වන්න"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"යෙදුම බහු-කවුළුව සමඟ ක්රියා නොකළ හැකිය."</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. වෙනස් කිරීමට දෙවරක් තට්ටු කරන්න."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. එක් කිරීමට දෙවරක් තට්ටු කරන්න."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>. තෝරා ගැනීමට දෙවරක් තට්ටු කරන්න."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ඉවත් කරන ලදි"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> වන ස්ථානයට ගෙන යන ලදි"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ඉක්මන් සැකසුම් සංස්කාරකය."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"යෙදුම බෙදුම්-තිරය සමග ක්රියා නොකළ හැකිය."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9468fcf..b606d01 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zrušiť aplikáciu <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikácia <xliff:g id="APP">%s</xliff:g> bola zrušená."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všetky nedávne aplikácie boli odmietnuté."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Otvoriť informácie o aplikácii <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Spúšťa sa aplikácia <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Upozornenie bolo zrušené."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialóg hlasitosti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používate svoj pracovný profil."</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Tuner používateľského rozhrania systému"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Zobraziť percentá vloženej batérie"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Percentuálne zobrazenie nabitia batérie vnútri ikony v stavovom riadku, keď neprebieha nabíjanie"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikácia nemusí fungovať v režime viacerých okien"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozícia <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Upravíte ju dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Pridáte ju dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozícia <xliff:g id="POSITION">%1$d</xliff:g>. Vyberiete ju dvojitým klepnutím."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Dlaždica <xliff:g id="TILE_NAME">%1$s</xliff:g> bola odstránená"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Dlaždica <xliff:g id="TILE_NAME">%1$s</xliff:g> bola presunutá na pozíciu <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor rýchlych nastavení"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikácia nemusí fungovať so zapnutou rozdelenou obrazovkou."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikácia nepodporuje rozdelenú obrazovku."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c5a43f9..3c71c09 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Opusti aplikacijo <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> je bila odstranjena."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Vse nedavne aplikacije so bile opuščene."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Odpiranje podatkov o aplikaciji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Zaganjanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obvestilo je bilo odstranjeno."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pogovorno okno glede prostornine"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dotaknite se, če želite obnoviti izvirnik."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Uporabljate delovni profil"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Uglaševalnik uporabniškega vmesnika sistema"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži odstotek napolnjenosti vgraj. akumulatorja"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikaz odstotka napolnjenosti akumulatorja znotraj ikone v vrstici stanja, ko se ne polni"</string>
@@ -598,7 +603,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Če želite urediti, se dvakrat dotaknite."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Če želite dodati, se dvakrat dotaknite."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Položaj: <xliff:g id="POSITION">%1$d</xliff:g>. Če želite izbrati, se dvakrat dotaknite."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> je odstranjeno"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> premaknjeno na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Urejevalnik hitrih nastavitev."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podpira načina razdeljenega zaslona."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 0188e5b..fe79425 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Largo <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> është hequr."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Të gjitha aplikacionet e fundit u larguan."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Hap informacionin e aplikacionit <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Po nis <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Njoftimi është hequr."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> është dialogu i volumit"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Prek për të restauruar origjinalin."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Po përdor profilin tënd të punës"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Shfaq përqindjen e baterisë së integruar"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Shfaq përqindjen e nivelit të baterisë brenda ikonës së shiritit të statusit kur nuk është duke u ngarkuar."</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Trokit dy herë për ta redaktuar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Trokit dy herë për ta shtuar."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>. Trokit dy herë për ta zgjedhur."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> u hoq"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> u zhvendos te pozicioni <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redaktori i cilësimeve të shpejta."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacioni nuk mbështet ekranin e ndarë."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 501a3e3..772aca4 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -169,8 +169,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Одбаците <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Апликација <xliff:g id="APP">%s</xliff:g> је одбачена."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Све недавно коришћене апликације су одбачене."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Отворите информације о апликацији <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Покрећемо <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Обавештење је одбачено."</string>
@@ -422,6 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> је дијалог за јачину звука"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Додирните да бисте вратили оригинал."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Користите профил за Work"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Тјунер за кориснички интерфејс система"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Приказуј уграђени проценат батерије"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Приказивање нивоа напуњености батерије у процентима унутар иконе на статусној траци када се батерија не пуни"</string>
@@ -597,7 +602,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Апликација можда неће функционисати са више прозора"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двапут додирните да бисте изменили."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двапут додирните да бисте додали."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција. Двапут додирните да бисте изабрали."</string>
@@ -607,4 +611,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Плочица <xliff:g id="TILE_NAME">%1$s</xliff:g> је уклоњена"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Плочица <xliff:g id="TILE_NAME">%1$s</xliff:g> је премештена на <xliff:g id="POSITION">%2$d</xliff:g>. позицију"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Уређивач за Брза подешавања."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Апликација можда неће функционисати са подељеним екраном."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Апликација не подржава подељени екран."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 959128e..5acbc61 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ta bort <xliff:g id="APP">%s</xliff:g> från listan."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> togs bort permanent."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alla appar har tagits bort från listan Senaste."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Öppna appinformation för <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Startar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Meddelandet ignorerades."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> används som volymkontroll"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tryck här om du vill återställa den ursprungliga appen."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du använder din jobbprofil"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Inställningar för systemgränssnitt"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Visa inbäddad batteriprocent"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Visa batterinivå i procent i statusfältsikonen när enheten inte laddas"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryck snabbt två gånger om du vill redigera positionen."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lägg till genom att trycka snabbt två gånger."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Välj den genom att trycka snabbt två gånger."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> har tagits bort"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> har flyttats till position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigerare för snabbinställningar."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen kanske inte fungerar med delad skärm."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen har inte stöd för delad skärm."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 4b936c9..d4d278d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ondoa <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> imeondolewa."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Programu za hivi majuzi zimeondolewa."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Fungua maelezo kuhusu programu ya <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Inaanzisha <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Arifa imetupwa."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ni mazungumzo ya sauti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Gusa ili urejeshe ya awali."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Unatumia wasifu wako wa kazini"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Kipokea Ishara cha SystemUI"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Onyesha asilimia ya betri iliyopachikwa"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Onyesha asilimia ya kiwango cha betri ndani ya aikoni ya sehemu ya arifa inapokuwa haichaji"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Huenda programu isifanye kazi kwenye madirisha mengi"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Gonga mara mbili ili ubadilishe."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gonga mara mbili ili uongeze."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>. Gonga mara mbili ili uchague."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> imeondolewa"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> imehamishiwa kwenye nafasi ya <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Kihariri cha Mipangilio ya haraka."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programu haiwezi kutumia skrini iliyogawanywa."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw410dp/config.xml b/packages/SystemUI/res/values-sw410dp/config.xml
new file mode 100644
index 0000000..08b2f88
--- /dev/null
+++ b/packages/SystemUI/res/values-sw410dp/config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <integer name="quick_settings_num_rows">2</integer>
+</resources>
diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml
new file mode 100644
index 0000000..5ce6524
--- /dev/null
+++ b/packages/SystemUI/res/values-sw410dp/dimens.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <dimen name="qs_detail_items_padding_top">16dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw540dp/config.xml b/packages/SystemUI/res/values-sw540dp/config.xml
new file mode 100644
index 0000000..e554fc6d
--- /dev/null
+++ b/packages/SystemUI/res/values-sw540dp/config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <integer name="quick_settings_num_rows">3</integer>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 4ed15d5..49a7a29 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -40,4 +40,8 @@
<dimen name="battery_detail_graph_space_top">27dp</dimen>
<dimen name="battery_detail_graph_space_bottom">27dp</dimen>
+
+ <dimen name="qs_tile_margin_top">16dp</dimen>
+ <dimen name="qs_brightness_padding_top">6dp</dimen>
+ <dimen name="qs_detail_margin_top">28dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 5489be9..3714c06 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ஐ நிராகரி."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> விலக்கப்பட்டது."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"எல்லா சமீபத்திய பயன்பாடுகளும் விலக்கப்பட்டன."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> பயன்பாட்டின் தகவலைத் திற."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ஐத் தொடங்குகிறது."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"அறிவிப்பு நிராகரிக்கப்பட்டது."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"அசலை மீட்டமைக்கத் தொடவும்."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"உள்ளிணைந்த பேட்டரி சதவீதத்தைக் காட்டு"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"சார்ஜ் செய்யாத போது, நிலைப் பட்டி ஐகானின் உள்ளே பேட்டரி அளவு சதவீதத்தைக் காட்டும்"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"பல சாளர அம்சத்தில் பயன்பாடு வேலைசெய்யாமல் போகக்கூடும்"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"நிலை <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. திருத்த, இருமுறை தட்டவும்."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. சேர்க்க, இருமுறை தட்டவும்."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"நிலை <xliff:g id="POSITION">%1$d</xliff:g>. தேர்ந்தெடுக்க, இருமுறை தட்டவும்."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> அகற்றப்பட்டது"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> நிலை <xliff:g id="POSITION">%2$d</xliff:g>க்கு நகர்த்தப்பட்டது"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"விரைவு அமைப்புகள் திருத்தி."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"திரைப் பிரிப்பில் பயன்பாடு வேலைசெய்யாமல் போகக்கூடும்."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"திரையைப் பிரிப்பதைப் பயன்பாடு ஆதரிக்கவில்லை."</string>
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 3a72809..1dd7254b 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ని తీసివేయండి."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> తీసివేయబడింది."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"అన్ని ఇటీవలి అనువర్తనాలు తీసివేయబడ్డాయి."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> అనువర్తన సమాచారాన్ని తెరుస్తుంది."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభిస్తోంది."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"నోటిఫికేషన్ తీసివేయబడింది."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> అనేది వాల్యూమ్ డైలాగ్"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"అసలుదాన్ని పునరుద్ధరించడానికి తాకండి."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"మీరు మీ కార్యాలయ ప్రొఫైల్ను ఉపయోగిస్తున్నారు"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"సిస్టమ్ UI ట్యూనర్"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"పొందుపరిచిన బ్యాటరీ శాతం చూపు"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"ఛార్జింగ్లో లేనప్పుడు స్థితి పట్టీ చిహ్నం లోపల బ్యాటరీ స్థాయి శాతం చూపుతుంది"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"అనువర్తనం బహుళ విండోల రూపంలో పని చేయకపోవచ్చు"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. సవరించడానికి రెండుసార్లు నొక్కండి."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. జోడించడానికి రెండుసార్లు నొక్కండి."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>. ఎంచుకోవడానికి రెండుసార్లు నొక్కండి."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> తీసివేయబడింది"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>వ స్థానానికి తరలించబడింది"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"శీఘ్ర సెట్టింగ్ల ఎడిటర్."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"స్క్రీన్ విభజనతో అనువర్తనం పని చేయకపోవచ్చు."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 4844c84..59b420d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ยกเลิก <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ถูกลบไปแล้ว"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ปิดแอปพลิเคชันล่าสุดทั้งหมดแล้ว"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"เปิดข้อมูลแอปพลิเคชัน <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"กำลังเริ่มต้น <xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ปิดการแจ้งเตือนแล้ว"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"แตะเพื่อคืนค่าดั้งเดิม"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"คุณกำลังใช้โปรไฟล์งานของคุณ"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"ตัวรับสัญญาณ UI ระบบ"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"แสดงเปอร์เซ็นต์ของแบตเตอรี่ในตัว"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"แสดงเปอร์เซ็นต์ของระดับแบตเตอรี่ภายในไอคอนแถบสถานะเมื่อไม่มีการชาร์จ"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"แอปอาจทำงานกับหลายหน้าต่างไม่ได้"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g> <xliff:g id="TILE_NAME">%2$s</xliff:g> แตะ 2 ครั้งเพื่อแก้ไข"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> แตะ 2 ครั้งเพื่อเพิ่ม"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g> แตะ 2 ครั้งเพื่อเลือก"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"นำ <xliff:g id="TILE_NAME">%1$s</xliff:g> ออกแล้ว"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"ย้าย <xliff:g id="TILE_NAME">%1$s</xliff:g> ไปยังตำแหน่ง <xliff:g id="POSITION">%2$d</xliff:g> แล้ว"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"ตัวแก้ไขการตั้งค่าด่วน"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"แอปอาจใช้ไม่ได้กับโหมดแยกหน้าจอ"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"แอปไม่สนับสนุนการแยกหน้าจอ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0672959..629963d 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"I-dismiss ang <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Hindi pinansin ang <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Na-dismiss ang lahat ng kamakailang application."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Buksan ang impormasyon ng <xliff:g id="APP">%s</xliff:g> application."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Sinisimulan ang <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Na-dismiss ang notification."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ginagamit mo ang iyong profile sa trabaho"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Tuner ng System UI"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Ipakita ang naka-embed na porsyento ng baterya"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Ipakita ang porsyento ng antas ng baterya na nasa icon ng status bar kapag nagcha-charge"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. I-double tap upang i-edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. I-double tap upang idagdag."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>. I-double tap upang piliin."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Inalis ang <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Inilipat ang <xliff:g id="TILE_NAME">%1$s</xliff:g> sa posisyon <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor ng Mga mabilisang setting."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Maaaring hindi gumana ang app sa split-screen."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Hindi sinusuportahan ng app ang split-screen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 58d488c..02c0d59 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> uygulamasını kapat."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> kaldırıldı."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tüm son uygulamalar kapatıldı."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> uygulaması bilgilerini açın."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> başlatılıyor."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildirim kapatıldı."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ses denetimi iletişim kutusu olarak ayarlandı"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinali geri yüklemek için dokunun."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi kullanıyorsunuz"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Sistem Arayüzü Ayarlayıcısı"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Yerleşik pil yüzdesini göster"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Şarj olmazken durum çubuğu simgesinin içinde pil düzeyi yüzdesini göster"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Uygulama birden fazla pencerede çalışmayabilir"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>. konum, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Düzenlemek için iki kez hafifçe dokunun."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Eklemek için iki kez hafifçe dokunun."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g>. konum. Seçmek için iki kez hafifçe dokunun."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> kaldırıldı"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>. konumuna taşındı"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Hızlı ayar düzenleyicisi."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Uygulama bölünmüş ekranda çalışmayabilir."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Uygulama bölünmüş ekranı desteklemiyor."</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index c75891c..a1b2ee1 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -170,8 +170,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Видалити додаток <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Програму <xliff:g id="APP">%s</xliff:g> закрито."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Усі останні додатки закрито."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Відкрити інформацію про додаток <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запуск додатка <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Сповіщення відхилено."</string>
@@ -423,6 +422,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> призначено регулятором гучності"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Торкніться, щоб відновити оригінал."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ви в робочому профілі"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Показувати заряд акумулятора у відсотках"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Показувати заряд акумулятора у відсотках в рядку стану, коли пристрій не заряджається"</string>
@@ -598,7 +603,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Додаток може не працювати в багатовіконному режимі"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двічі торкніться, щоб змінити."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двічі торкніться, щоб додати."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>. Двічі торкніться, щоб вибрати."</string>
@@ -608,4 +612,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> видалено"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> переміщено на позицію <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Редактор швидких налаштувань."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Додаток може не працювати в режимі розділеного екрана."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Додаток не підтримує розділення екрана."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 807a923..5c4ae9a 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> کو مسترد کریں۔"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> کو ہٹا دیا گیا۔"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"سبھی حالیہ ایپلیکیشنز کو برخاست کر دیا گیا۔"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ایپلیکیشن معلومات کھولیں۔"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> شروع ہو رہی ہے۔"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"اطلاع مسترد ہوگئی۔"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"اصل کو بحال کرنے کیلئے ٹچ کریں۔"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"آپ اپنا دفتری پروفائل استعمال کر رہے ہیں۔"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"سسٹم UI ٹیونر"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"سرایت کردہ بیٹری کی فیصد دکھائیں"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"جب چارج نہ ہو رہا ہو تو بیٹری کی سطح کی فیصد اسٹیٹس بار آئیکن کے اندر دکھائیں"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"ایپ شاید ملٹی ونڈو کے ساتھ کام نہ کرے"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>۔ ترمیم کرنے کیلئے دو بار تھپتھپائیں۔"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>۔ شامل کرنے کیلئے دو بار تھپتھپائیں۔"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>۔ منتخب کرنے کیلئے دو بار تھپتھپائیں۔"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ہٹا دیا گیا"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="POSITION">%2$d</xliff:g> پوزیشن پر <xliff:g id="TILE_NAME">%1$s</xliff:g> منتقل ہو گیا ہے"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"فوری ترتیبات کا ایڈیٹر۔"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"ممکن ہے کہ ایپ سپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index fe67b52..27039d6 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Olib tashlash: <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> olib tashlangan."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Yaqinda ishlatilgan barcha ilovalar olib tashlandi."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ilovasi haqidagi ma’lumotlarni ochadi."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ishga tushirilmoqda."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Xabarnoma e‘tiborsiz qoldirildi."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"SystemUI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Batareya foizi ko‘rsatilsin"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Batareya quvvat olmayotgan vaqtda uning foizi holat qatorida ko‘rsatilsin"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"Ilova ko‘p oynali rejimni qo‘llab-quvvatlamaydi"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"<xliff:g id="POSITION">%1$d</xliff:g>-joy, “<xliff:g id="TILE_NAME">%2$s</xliff:g>” tugmasi. Tahrirlash uchun ustiga ikki marta bosing."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasi. Qo‘shish uchun ustiga ikki marta bosing."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Joylashuv: <xliff:g id="POSITION">%1$d</xliff:g>. Belgilash uchun ustiga ikki marta bosing."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasi o‘chirildi"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasi endi <xliff:g id="POSITION">%2$d</xliff:g>-joyni egallanmoqda"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Tezkor sozlamalar muharriri"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Ilova ekranni ikkiga bo‘lish rejimini qo‘llab-quvvatlamaydi."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index ca7c59b..ef87f01 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Xóa bỏ <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> đã bị loại bỏ."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Đã bỏ qua tất cả các ứng dụng gần đây."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Mở thông tin ứng dụng <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Bắt đầu <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> là hộp thoại khối lượng"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Chạm để khôi phục bản gốc."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Bạn đang sử dụng hồ sơ công việc của mình"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Bộ điều hướng giao diện người dùng hệ thống"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Hiển thị tỷ lệ phần trăm pin được nhúng"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Hiển thị tỷ lệ phần trăm mức pin bên trong biểu tượng thanh trạng thái khi không sạc"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Nhấn đúp để chỉnh sửa."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Nhấn đúp để thêm."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>. Nhấn đúp để chọn."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> được di chuyển"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> được di chuyển sang vị trí <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Trình chỉnh sửa cài đặt nhanh."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Ứng dụng không hỗ trợ chia đôi màn hình."</string>
</resources>
diff --git a/packages/SystemUI/res/values-w550dp-land/dimens.xml b/packages/SystemUI/res/values-w550dp-land/dimens.xml
index cd17bed..4160c83 100644
--- a/packages/SystemUI/res/values-w550dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-w550dp-land/dimens.xml
@@ -20,7 +20,4 @@
<dimen name="notification_panel_width">544dp</dimen>
<dimen name="qs_expand_margin">32dp</dimen>
-
- <dimen name="battery_detail_graph_space_top">9dp</dimen>
- <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a25b9f1..85c8bf6 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"移除<xliff:g id="APP">%s</xliff:g>。"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"已删除<xliff:g id="APP">%s</xliff:g>"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"已关闭所有最近用过的应用。"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"打开<xliff:g id="APP">%s</xliff:g>应用信息。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在启动<xliff:g id="APP">%s</xliff:g>。"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"已关闭通知。"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"触摸即可恢复原始设置。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您当前正在使用工作资料"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"系统界面调谐器"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"嵌入式显示电池电量百分比 显示嵌入的电池电量百分比"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"未充电时在状态栏图标内显示电池电量百分比"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"应用可能无法在多窗口模式下正常运行"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。点按两次即可修改。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。点按两次即可添加。"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"位置 <xliff:g id="POSITION">%1$d</xliff:g>。点按两次即可选择。"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"已移除<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"已将<xliff:g id="TILE_NAME">%1$s</xliff:g>移至位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"快捷设置编辑器。"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"应用可能无法在分屏模式下正常运行。"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"应用不支持分屏。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 083cd5e..4d5e495 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"所有最近使用的應用程式均已關閉。"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"開啟「<xliff:g id="APP">%s</xliff:g>」應用程式的資料。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g><xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知已關閉。"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」為音量對話框"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸即可復原。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用工作設定檔"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調諧器"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入的電池百分比"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"非充電時,在狀態列圖示顯示電量百分比"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多重視窗下運作"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕按兩下即可編輯。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕按兩下即可新增。"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"位置 <xliff:g id="POSITION">%1$d</xliff:g>。輕按兩下即可選取。"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 已移除"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 已移至位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"快速設定編輯工具。"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"應用程式不支援分割畫面。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 3c95a93..6d15234 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近使用的應用程式已全部關閉。"</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"開啟「<xliff:g id="APP">%s</xliff:g>」應用程式資訊。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"已關閉通知。"</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸這裡即可恢復原始設定。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用 Work 設定檔"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調整精靈"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入式電池百分比"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"未充電時在狀態列圖示中顯示電量百分比"</string>
@@ -596,7 +601,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>
- <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多視窗模式下運作"</string>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕按兩下即可編輯。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕按兩下即可新增。"</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"位置 <xliff:g id="POSITION">%1$d</xliff:g>。輕按兩下即可選取。"</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"已移除 <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"已將 <xliff:g id="TILE_NAME">%1$s</xliff:g> 移到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"快速設定編輯器。"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"這個應用程式不支援分割畫面。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e03e642..4d63511 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -168,8 +168,7 @@
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Cashisa i-<xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ivaliwe."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Zonke izinhlelo zokusebenza zakamuva zicashisiwe."</string>
- <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
- <skip />
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Vula ulwazi lohlelo lokusebenza le-<xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iqala i-<xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Isaziso sichithiwe."</string>
@@ -421,6 +420,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> yingxoxo yevolumu"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Thinta ukuze ubuyisele kokwangempela."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Usebenzisa iphrofayela yakho yomsebenzi"</string>
+ <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+ <skip />
+ <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+ <skip />
<string name="system_ui_tuner" msgid="708224127392452018">"Isishuni se-UI yesistimu"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Bonisa amaphesenti ebhethri elinamathiselwe"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Bonisa amaphesenti eleveli yebhethri ngaphakathi kwesithonjana sebha yesimo uma kungashajwa"</string>
@@ -596,7 +601,6 @@
<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>
<string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Isimo esingu-<xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Thepha kabili ukuze uhlele."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Thepha kabili ukuze ungeze."</string>
<string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Isimo esingu-<xliff:g id="POSITION">%1$d</xliff:g>. Thepha kabili ukuze ukhethe."</string>
@@ -606,4 +610,6 @@
<string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"I-<xliff:g id="TILE_NAME">%1$s</xliff:g> isusiwe"</string>
<string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"I-<xliff:g id="TILE_NAME">%1$s</xliff:g> ihanjiswe kusimo esingu-<xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Isihleli sezilungiselelo ezisheshayo."</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 1e979fd..1543360 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -53,10 +53,14 @@
<enum name="vertical" value="1" />
</attr>
<declare-styleable name="UserAvatarView">
+ <attr name="avatarPadding" format="dimension" />
<attr name="frameWidth" format="dimension" />
<attr name="framePadding" format="dimension" />
+ <!-- {@deprecated Use a statelist in frameColor instead.} -->
<attr name="activeFrameColor" format="color" />
- <attr name="frameColor" />
+ <attr name="frameColor" format="color" />
+ <attr name="badgeDiameter" format="dimension" />
+ <attr name="badgeMargin" format="dimension" />
</declare-styleable>
<declare-styleable name="UserDetailItemView">
<attr name="regularFontFamily" format="string" />
@@ -97,5 +101,9 @@
<declare-styleable name="DensityContainer">
<attr name="android:layout" />
</declare-styleable>
+
+ <declare-styleable name="AutoSizingList">
+ <attr name="itemHeight" format="dimension" />
+ </declare-styleable>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b874e7c..d9fcf42 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -151,7 +151,7 @@
<color name="docked_divider_background">#ff000000</color>
<color name="docked_divider_handle">#ffffff</color>
- <drawable name="forced_resizable_background">#80000000</drawable>
+ <drawable name="forced_resizable_background">#40000000</drawable>
<color name="default_remote_input_background">@*android:color/notification_default_color</color>
<color name="remote_input_hint">#99ffffff</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 6ce2a5d..42798a4 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -92,11 +92,8 @@
<!-- The number of columns in the QuickSettings -->
<integer name="quick_settings_num_columns">3</integer>
- <!-- The maximum number of rows in the QuickSettings -->
- <integer name="quick_settings_max_rows">4</integer>
-
- <!-- The maximum number of rows in the QuickSettings when on the keyguard -->
- <integer name="quick_settings_max_rows_keyguard">3</integer>
+ <!-- The number of rows in the QuickSettings -->
+ <integer name="quick_settings_num_rows">1</integer>
<!-- The number of columns that the top level tiles span in the QuickSettings -->
<integer name="quick_settings_user_time_settings_tile_span">1</integer>
@@ -116,9 +113,6 @@
<integer name="quick_settings_brightness_dialog_short_timeout">2000</integer>
<integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
- <!-- The maximum number of items to be displayed in quick settings -->
- <integer name="quick_settings_detail_max_item_count">5</integer>
-
<!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
<bool name="config_show4GForLTE">true</bool>
diff --git a/packages/SystemUI/res/values/config_tv.xml b/packages/SystemUI/res/values/config_tv.xml
index 22b7578..40e3b12 100644
--- a/packages/SystemUI/res/values/config_tv.xml
+++ b/packages/SystemUI/res/values/config_tv.xml
@@ -16,6 +16,10 @@
<resources>
<!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+ when the PIP menu is shown with settings. -->
+ <string translatable="false" name="pip_settings_bounds">"662 54 1142 324"</string>
+
+ <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
when the PIP menu is shown in center. -->
<string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 75e57b0..cf2e338 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -172,6 +172,7 @@
<dimen name="qs_tile_height">88dp</dimen>
<dimen name="qs_tile_margin">16dp</dimen>
+ <dimen name="qs_tile_margin_top">16dp</dimen>
<dimen name="qs_quick_tile_size">48dp</dimen>
<dimen name="qs_quick_tile_padding">12dp</dimen>
<dimen name="qs_date_anim_translation">32dp</dimen>
@@ -201,10 +202,12 @@
<dimen name="qs_detail_item_primary_text_size">16sp</dimen>
<dimen name="qs_detail_item_secondary_text_size">14sp</dimen>
<dimen name="qs_detail_empty_text_size">14sp</dimen>
+ <dimen name="qs_detail_margin_top">28dp</dimen>
<dimen name="qs_data_usage_text_size">14sp</dimen>
<dimen name="qs_data_usage_usage_text_size">36sp</dimen>
<dimen name="qs_expand_margin">0dp</dimen>
<dimen name="qs_battery_padding">2dp</dimen>
+ <dimen name="qs_detail_items_padding_top">4dp</dimen>
<dimen name="segmented_button_spacing">0dp</dimen>
<dimen name="borderless_button_radius">2dp</dimen>
@@ -385,6 +388,9 @@
quick settings header -->
<dimen name="max_avatar_size">48dp</dimen>
+ <!-- Size of user icon + frame in the qs/keyguard user picker (incl. frame) -->
+ <dimen name="framed_avatar_size">54dp</dimen>
+
<!-- Margin on the left side of the carrier text on Keyguard -->
<dimen name="keyguard_carrier_text_margin">16dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml
index 4e6a4b1..f536f86 100644
--- a/packages/SystemUI/res/values/dimens_tv.xml
+++ b/packages/SystemUI/res/values/dimens_tv.xml
@@ -57,4 +57,6 @@
<!-- Extra space around the PIP control button icon to match with the focused circle -->
<dimen name="tv_pip_button_icon_padding">5dp</dimen>
+ <!-- Values for entering Recents and exiting Recents -->
+ <dimen name="recents_tv_home_recents_shift">125dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/integers_tv.xml b/packages/SystemUI/res/values/integers_tv.xml
index 20cd330..6984d5a 100644
--- a/packages/SystemUI/res/values/integers_tv.xml
+++ b/packages/SystemUI/res/values/integers_tv.xml
@@ -17,5 +17,11 @@
<integer name="item_scale_anim_duration">150</integer>
<integer name="dismiss_short_duration">200</integer>
<integer name="dismiss_long_duration">400</integer>
+
<integer name="recents_tv_pip_focus_anim_duration">200</integer>
+
+ <!-- Duration for how long it takes cards to slide in or out when going to and from recents. -->
+ <integer name="recents_home_duration">400</integer>
+ <!-- Delay between the start of slide in animation for each card. -->
+ <integer name="recents_home_delay">40</integer>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 060e050..a33b7a3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1082,6 +1082,10 @@
<string name="volume_stream_limited_dnd" translatable="false">%s — Priority only</string>
<string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string>
+ <string name="volume_stream_content_description_unmute">%1$s. Tap to unmute.</string>
+ <string name="volume_stream_content_description_vibrate">%1$s. Tap to set to vibrate. Accessibility services may be muted.</string>
+ <string name="volume_stream_content_description_mute">%1$s. Tap to mute. Accessibility services may be muted.</string>
+
<!-- Name of special SystemUI debug settings -->
<string name="system_ui_tuner">System UI Tuner</string>
@@ -1557,9 +1561,6 @@
<!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
<string name="accessibility_action_divider_move_right">Move right</string>
- <!-- 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>
@@ -1587,4 +1588,10 @@
<!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
+ <!-- Multi-Window strings -->
+ <!-- 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="dock_forced_resizable">App may not work with split-screen.</string>
+ <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
+ <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
+
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 2b134af..f560a13 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -49,6 +49,9 @@
<style name="Animation.ForcedResizable" parent="@android:style/Animation">
<item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
+
+ <!-- If the target stack doesn't have focus, we do a task to front animation. -->
+ <item name="android:taskToFrontEnterAnimation">@anim/forced_resizable_enter</item>
<item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
</style>
@@ -180,6 +183,11 @@
<item name="android:textColor">@color/data_usage_secondary</item>
</style>
+ <style name="TextAppearance.QS.TileLabel">
+ <item name="android:textSize">@dimen/qs_tile_text_size</item>
+ <item name="android:fontFamily">sans-serif-condensed</item>
+ </style>
+
<style name="BaseBrightnessDialogContainer">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
diff --git a/packages/SystemUI/src/com/android/systemui/BitmapHelper.java b/packages/SystemUI/src/com/android/systemui/BitmapHelper.java
deleted file mode 100644
index 1933bbc..0000000
--- a/packages/SystemUI/src/com/android/systemui/BitmapHelper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.graphics.Shader;
-
-public class BitmapHelper {
- /**
- * Generate a new bitmap (width x height pixels, ARGB_8888) with the input bitmap scaled
- * to fit and clipped to an inscribed circle.
- * @param input Bitmap to resize and clip
- * @param width Width of output bitmap (and diameter of circle)
- * @param height Height of output bitmap
- * @return A shiny new bitmap for you to use
- */
- public static Bitmap createCircularClip(Bitmap input, int width, int height) {
- if (input == null) return null;
-
- final int inWidth = input.getWidth();
- final int inHeight = input.getHeight();
- final Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- final Canvas canvas = new Canvas(output);
- final Paint paint = new Paint();
- paint.setShader(new BitmapShader(input, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
- paint.setAntiAlias(true);
- final RectF srcRect = new RectF(0, 0, inWidth, inHeight);
- final RectF dstRect = new RectF(0, 0, width, height);
- final Matrix m = new Matrix();
- m.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.CENTER);
- canvas.setMatrix(m);
- canvas.drawCircle(inWidth / 2, inHeight / 2, inWidth / 2, paint);
- return output;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/ResizingSpace.java b/packages/SystemUI/src/com/android/systemui/ResizingSpace.java
new file mode 100644
index 0000000..c2bc53e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ResizingSpace.java
@@ -0,0 +1,104 @@
+/*
+ * 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.systemui;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+
+public class ResizingSpace extends View {
+
+ private final int mWidth;
+ private final int mHeight;
+
+ public ResizingSpace(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ if (getVisibility() == VISIBLE) {
+ setVisibility(INVISIBLE);
+ }
+ TypedArray a = context.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout);
+ mWidth = a.getResourceId(android.R.styleable.ViewGroup_Layout_layout_width, 0);
+ mHeight = a.getResourceId(android.R.styleable.ViewGroup_Layout_layout_height, 0);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ LayoutParams params = getLayoutParams();
+ boolean changed = false;
+ if (mWidth > 0) {
+ int width = getContext().getResources().getDimensionPixelOffset(mWidth);
+ if (width != params.width) {
+ params.width = width;
+ changed = true;
+ }
+ }
+ if (mHeight > 0) {
+ int height = getContext().getResources().getDimensionPixelOffset(mHeight);
+ if (height != params.height) {
+ params.height = height;
+ changed = true;
+ }
+ }
+ if (changed) {
+ setLayoutParams(params);
+ }
+ }
+
+ /**
+ * Draw nothing.
+ *
+ * @param canvas an unused parameter.
+ */
+ @Override
+ public void draw(Canvas canvas) {
+ }
+
+ /**
+ * Compare to: {@link View#getDefaultSize(int, int)}
+ * If mode is AT_MOST, return the child size instead of the parent size
+ * (unless it is too big).
+ */
+ private static int getDefaultSize2(int size, int measureSpec) {
+ int result = size;
+ int specMode = MeasureSpec.getMode(measureSpec);
+ int specSize = MeasureSpec.getSize(measureSpec);
+
+ switch (specMode) {
+ case MeasureSpec.UNSPECIFIED:
+ result = size;
+ break;
+ case MeasureSpec.AT_MOST:
+ result = Math.min(size, specSize);
+ break;
+ case MeasureSpec.EXACTLY:
+ result = specSize;
+ break;
+ }
+ return result;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(
+ getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec),
+ getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec));
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 0d822cb..0798590 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -250,7 +250,6 @@
FalsingLog.i("onSucccessfulUnlock", "");
}
mDataCollector.onSucccessfulUnlock();
- sessionExitpoint(true /* force */);
}
public void onBouncerShown() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e00bf6c..66754a7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -804,7 +804,7 @@
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumTimeToLock(null, userId);
+ .getMaximumTimeToLockForUserAndProfiles(userId);
long timeout;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java
new file mode 100644
index 0000000..00e6221
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java
@@ -0,0 +1,121 @@
+/*
+ * 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.systemui.qs;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import com.android.systemui.R;
+
+/**
+ * Similar to a ListView, but it will show only as many items as fit on screen and
+ * bind those instead of scrolling.
+ */
+public class AutoSizingList extends LinearLayout {
+
+ private static final String TAG = "AutoSizingList";
+ private final int mItemSize;
+ private final Handler mHandler;
+
+ private ListAdapter mAdapter;
+ private int mCount;
+
+ public AutoSizingList(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+
+ mHandler = new Handler();
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoSizingList);
+ mItemSize = a.getDimensionPixelSize(R.styleable.AutoSizingList_itemHeight, 0);
+ }
+
+ public void setAdapter(ListAdapter adapter) {
+ if (mAdapter != null) {
+ mAdapter.unregisterDataSetObserver(mDataObserver);
+ }
+ mAdapter = adapter;
+ if (adapter != null) {
+ adapter.registerDataSetObserver(mDataObserver);
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int requestedHeight = MeasureSpec.getSize(heightMeasureSpec);
+ if (requestedHeight != 0) {
+ int count = Math.min(requestedHeight / mItemSize, getDesiredCount());
+ if (mCount != count) {
+ postRebindChildren();
+ mCount = count;
+ }
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ private int getDesiredCount() {
+ return mAdapter != null ? mAdapter.getCount() : 0;
+ }
+
+ private void postRebindChildren() {
+ mHandler.post(mBindChildren);
+ }
+
+ private void rebindChildren() {
+ if (mAdapter == null) {
+ return;
+ }
+ for (int i = 0; i < mCount; i++) {
+ View v = i < getChildCount() ? getChildAt(i) : null;
+ View newView = mAdapter.getView(i, v, this);
+ if (newView != v) {
+ if (v != null) {
+ removeView(v);
+ }
+ addView(newView, i);
+ }
+ }
+ // Ditch extra views.
+ while (getChildCount() > mCount) {
+ removeViewAt(getChildCount() - 1);
+ }
+ }
+
+ private final Runnable mBindChildren = new Runnable() {
+ @Override
+ public void run() {
+ rebindChildren();
+ }
+ };
+
+ private final DataSetObserver mDataObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ if (mCount > getDesiredCount()) {
+ mCount = getDesiredCount();
+ }
+ postRebindChildren();
+ }
+
+ @Override
+ public void onInvalidated() {
+ postRebindChildren();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 115c9d0..5a23610 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -1,6 +1,8 @@
package com.android.systemui.qs;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
@@ -199,11 +201,22 @@
@Override
public boolean updateResources() {
- if (super.updateResources()) {
- mMaxRows = mColumns != 3 ? 2 : 3;
- return true;
+ final int rows = getRows();
+ boolean changed = rows != mMaxRows;
+ if (changed) {
+ mMaxRows = rows;
+ requestLayout();
}
- return false;
+ return super.updateResources() || changed;
+ }
+
+ private int getRows() {
+ final Resources res = getContext().getResources();
+ if (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ // Always have 3 rows in portrait.
+ return 3;
+ }
+ return Math.max(1, res.getInteger(R.integer.quick_settings_num_rows));
}
public void setMaxRows(int maxRows) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index de8eec4..4d959d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -157,7 +157,7 @@
for (QSTile<?> tile : tiles) {
QSTileBaseView tileView = mQsPanel.getTileView(tile);
final TextView label = ((QSTileView) tileView).getLabel();
- final View tileIcon = tileView.getIcon();
+ final View tileIcon = tileView.getIcon().getIconView();
if (count < mNumQuickTiles && mAllowFancy) {
// Quick tiles.
QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 5d06aeb..e3a4909 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -47,10 +47,10 @@
private final Rect mQsBounds = new Rect();
private int mHeightOverride = -1;
- private QSPanel mQSPanel;
+ protected QSPanel mQSPanel;
private QSDetail mQSDetail;
protected BaseStatusBarHeader mHeader;
- private float mQsExpansion;
+ protected float mQsExpansion;
private boolean mQsExpanded;
private boolean mHeaderAnimating;
private boolean mKeyguardShowing;
@@ -100,7 +100,13 @@
// Since we control our own bottom, be whatever size we want.
// Otherwise the QSPanel ends up with 0 height when the window is only the
// size of the status bar.
- super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
+ mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
+ MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.UNSPECIFIED));
+ int width = mQSPanel.getMeasuredWidth();
+ int height = ((LayoutParams) mQSPanel.getLayoutParams()).topMargin
+ + mQSPanel.getMeasuredHeight();
+ super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
// QSCustomizer is always be the height of the screen, but do this after
// other measuring to avoid changing the height of the QSContainer.
@@ -156,14 +162,18 @@
}
private void updateBottom() {
- int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
- int height = mQSCustomizer.isCustomizing() ? mQSCustomizer.getHeight()
- : (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
- + mHeader.getCollapsedHeight();
+ int height = calculateContainerHeight();
setBottom(getTop() + height);
mQSDetail.setBottom(getTop() + height);
}
+ protected int calculateContainerHeight() {
+ int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
+ return mQSCustomizer.isCustomizing() ? mQSCustomizer.getHeight()
+ : (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
+ + mHeader.getCollapsedHeight();
+ }
+
private void updateQsState() {
boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
mQSPanel.setExpanded(mQsExpanded);
@@ -296,4 +306,8 @@
updateQsState();
}
};
+
+ public int getQsMinExpansionHeight() {
+ return mHeader.getHeight();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
index 25b9105..2dd4a0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
@@ -28,11 +28,10 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
-
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
@@ -45,16 +44,17 @@
private final Context mContext;
private final H mHandler = new H();
+ private final Adapter mAdapter = new Adapter();
private String mTag;
private Callback mCallback;
private boolean mItemsVisible = true;
- private LinearLayout mItems;
+ private AutoSizingList mItemList;
private View mEmpty;
- private View mMinHeightSpacer;
private TextView mEmptyText;
private ImageView mEmptyIcon;
- private int mMaxItems;
+
+ private Item[] mItems;
public QSDetailItems(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -73,27 +73,22 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mItems = (LinearLayout) findViewById(android.R.id.list);
- mItems.setVisibility(GONE);
+ mItemList = (AutoSizingList) findViewById(android.R.id.list);
+ mItemList.setVisibility(GONE);
+ mItemList.setAdapter(mAdapter);
mEmpty = findViewById(android.R.id.empty);
mEmpty.setVisibility(GONE);
mEmptyText = (TextView) mEmpty.findViewById(android.R.id.title);
mEmptyIcon = (ImageView) mEmpty.findViewById(android.R.id.icon);
- mMinHeightSpacer = findViewById(R.id.min_height_spacer);
-
- // By default, a detail item view has fixed size.
- mMaxItems = getResources().getInteger(
- R.integer.quick_settings_detail_max_item_count);
- setMinHeightInItems(mMaxItems);
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
FontSizeUtils.updateFontSize(mEmptyText, R.dimen.qs_detail_empty_text_size);
- int count = mItems.getChildCount();
+ int count = mItemList.getChildCount();
for (int i = 0; i < count; i++) {
- View item = mItems.getChildAt(i);
+ View item = mItemList.getChildAt(i);
FontSizeUtils.updateFontSize(item, android.R.id.title,
R.dimen.qs_detail_item_primary_text_size);
FontSizeUtils.updateFontSize(item, android.R.id.summary,
@@ -110,16 +105,6 @@
mEmptyText.setText(text);
}
- /**
- * Set the minimum height of this detail view, in item count.
- */
- public void setMinHeightInItems(int minHeightInItems) {
- ViewGroup.LayoutParams lp = mMinHeightSpacer.getLayoutParams();
- lp.height = minHeightInItems * getResources().getDimensionPixelSize(
- R.dimen.qs_detail_item_height);
- mMinHeightSpacer.setLayoutParams(lp);
- }
-
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -153,65 +138,82 @@
}
private void handleSetItems(Item[] items) {
- final int itemCount = items != null ? Math.min(items.length, mMaxItems) : 0;
+ final int itemCount = items != null ? items.length : 0;
mEmpty.setVisibility(itemCount == 0 ? VISIBLE : GONE);
- mItems.setVisibility(itemCount == 0 ? GONE : VISIBLE);
- for (int i = mItems.getChildCount() - 1; i >= itemCount; i--) {
- mItems.removeViewAt(i);
- }
- for (int i = 0; i < itemCount; i++) {
- bind(items[i], mItems.getChildAt(i));
- }
+ mItemList.setVisibility(itemCount == 0 ? GONE : VISIBLE);
+ mItems = items;
+ mAdapter.notifyDataSetChanged();
}
private void handleSetItemsVisible(boolean visible) {
if (mItemsVisible == visible) return;
mItemsVisible = visible;
- for (int i = 0; i < mItems.getChildCount(); i++) {
- mItems.getChildAt(i).setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
+ for (int i = 0; i < mItemList.getChildCount(); i++) {
+ mItemList.getChildAt(i).setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
}
}
- private void bind(final Item item, View view) {
- if (view == null) {
- view = LayoutInflater.from(mContext).inflate(R.layout.qs_detail_item, this, false);
- mItems.addView(view);
+ private class Adapter extends BaseAdapter {
+
+ @Override
+ public int getCount() {
+ return mItems != null ? mItems.length : 0;
}
- view.setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
- final ImageView iv = (ImageView) view.findViewById(android.R.id.icon);
- iv.setImageResource(item.icon);
- iv.getOverlay().clear();
- if (item.overlay != null) {
- item.overlay.setBounds(0, 0, item.overlay.getIntrinsicWidth(),
- item.overlay.getIntrinsicHeight());
- iv.getOverlay().add(item.overlay);
+
+ @Override
+ public Object getItem(int position) {
+ return mItems[position];
}
- final TextView title = (TextView) view.findViewById(android.R.id.title);
- title.setText(item.line1);
- final TextView summary = (TextView) view.findViewById(android.R.id.summary);
- final boolean twoLines = !TextUtils.isEmpty(item.line2);
- title.setMaxLines(twoLines ? 1 : 2);
- summary.setVisibility(twoLines ? VISIBLE : GONE);
- summary.setText(twoLines ? item.line2 : null);
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mCallback != null) {
- mCallback.onDetailItemClick(item);
- }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ final Item item = mItems[position];
+ if (view == null) {
+ view = LayoutInflater.from(mContext).inflate(R.layout.qs_detail_item, parent,
+ false);
}
- });
- final ImageView disconnect = (ImageView) view.findViewById(android.R.id.icon2);
- disconnect.setVisibility(item.canDisconnect ? VISIBLE : GONE);
- disconnect.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mCallback != null) {
- mCallback.onDetailItemDisconnect(item);
- }
+ view.setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
+ final ImageView iv = (ImageView) view.findViewById(android.R.id.icon);
+ iv.setImageResource(item.icon);
+ iv.getOverlay().clear();
+ if (item.overlay != null) {
+ item.overlay.setBounds(0, 0, item.overlay.getIntrinsicWidth(),
+ item.overlay.getIntrinsicHeight());
+ iv.getOverlay().add(item.overlay);
}
- });
- }
+ final TextView title = (TextView) view.findViewById(android.R.id.title);
+ title.setText(item.line1);
+ final TextView summary = (TextView) view.findViewById(android.R.id.summary);
+ final boolean twoLines = !TextUtils.isEmpty(item.line2);
+ title.setMaxLines(twoLines ? 1 : 2);
+ summary.setVisibility(twoLines ? VISIBLE : GONE);
+ summary.setText(twoLines ? item.line2 : null);
+ view.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mCallback != null) {
+ mCallback.onDetailItemClick(item);
+ }
+ }
+ });
+ final ImageView disconnect = (ImageView) view.findViewById(android.R.id.icon2);
+ disconnect.setVisibility(item.canDisconnect ? VISIBLE : GONE);
+ disconnect.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mCallback != null) {
+ mCallback.onDetailItemDisconnect(item);
+ }
+ }
+ });
+ return view;
+ }
+ };
private class H extends Handler {
private static final int SET_ITEMS = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
index 546f8c3..6c224f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -30,9 +30,9 @@
public class QSIconView extends ViewGroup {
- private final View mIcon;
- private final int mIconSizePx;
- private final int mTilePaddingBelowIconPx;
+ protected final View mIcon;
+ protected final int mIconSizePx;
+ protected final int mTilePaddingBelowIconPx;
private boolean mAnimationEnabled = true;
public QSIconView(Context context) {
@@ -50,6 +50,10 @@
mAnimationEnabled = false;
}
+ public View getIconView() {
+ return mIcon;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int w = MeasureSpec.getSize(widthMeasureSpec);
@@ -109,11 +113,11 @@
return icon;
}
- protected static int exactly(int size) {
+ protected final int exactly(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
- protected static void layout(View child, int left, int top) {
+ protected final void layout(View child, int left, int top) {
child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index a05818a..1149c59 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -85,20 +85,7 @@
R.layout.quick_settings_brightness_dialog, this, false);
addView(mBrightnessView);
- mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
- R.layout.qs_paged_tile_layout, this, false);
- addView((View) mTileLayout);
- findViewById(android.R.id.edit).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View v) {
- mHost.startRunnableDismissingKeyguard(new Runnable() {
- @Override
- public void run() {
- showEdit(v);
- }
- });
- }
- });
+ setupTileLayout();
mFooter = new QSFooter(this, context);
addView(mFooter.getView());
@@ -111,6 +98,14 @@
}
+ protected void setupTileLayout() {
+ mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
+ R.layout.qs_paged_tile_layout, this, false);
+ addView((View) mTileLayout);
+ findViewById(android.R.id.edit).setOnClickListener(view ->
+ mHost.startRunnableDismissingKeyguard(() -> showEdit(view)));
+ }
+
public boolean isShowingCustomize() {
return mCustomizePanel != null && mCustomizePanel.isCustomizing();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 57a1a4a..c3766e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -33,7 +33,6 @@
/** View that represents a standard quick settings tile. **/
public class QSTileView extends QSTileBaseView {
protected final Context mContext;
- private QSIconView mIconView;
private final int mTileSpacingPx;
private int mTilePaddingTopPx;
@@ -44,7 +43,6 @@
super(context, icon);
mContext = context;
- mIconView = icon;
final Resources res = context.getResources();
mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing);
@@ -82,13 +80,13 @@
}
protected void createLabel() {
- final Resources res = mContext.getResources();
View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
mLabel = (TextView) view.findViewById(R.id.tile_label);
mPadLock = (ImageView) view.findViewById(R.id.restricted_padlock);
addView(view);
}
+ @Override
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
if (!Objects.equal(mLabel.getText(), state.label)) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 55eda98..1e3c458 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -19,11 +19,12 @@
private static final String TAG = "TileLayout";
protected int mColumns;
- private int mCellWidth;
- private int mCellHeight;
- private int mCellMargin;
+ protected int mCellWidth;
+ protected int mCellHeight;
+ protected int mCellMargin;
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
+ private int mCellMarginTop;
public TileLayout(Context context) {
this(context, null);
@@ -60,9 +61,10 @@
final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin);
+ mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
if (mColumns != columns) {
mColumns = columns;
- postInvalidate();
+ requestLayout();
return true;
}
return false;
@@ -81,7 +83,8 @@
record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
previousView = record.tileView.updateAccessibilityOrder(previousView);
}
- setMeasuredDimension(width, (mCellHeight + mCellMargin) * rows);
+ setMeasuredDimension(width,
+ (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin));
}
private static int exactly(int size) {
@@ -114,7 +117,7 @@
}
private int getRowTop(int row) {
- return row * (mCellHeight + mCellMargin) + mCellMargin;
+ return row * (mCellHeight + mCellMargin) + mCellMarginTop;
}
private int getColumnStart(int column) {
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 6114573..6b20681 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -138,7 +138,7 @@
mListening = listening;
try {
if (listening) {
- if (mServiceManager.getType() == TileService.TILE_MODE_PASSIVE) {
+ if (!mServiceManager.isActiveTile()) {
mServiceManager.setBindRequested(true);
mService.onStartListening();
}
@@ -209,7 +209,7 @@
} catch (RemoteException e) {
}
try {
- if (mServiceManager.getType() == TileService.TILE_MODE_ACTIVE) {
+ if (mServiceManager.isActiveTile()) {
mServiceManager.setBindRequested(true);
mService.onStartListening();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 8910d44..5a26a4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui.qs.external;
-import libcore.util.Objects;
-
import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -25,6 +23,7 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.Handler;
@@ -34,9 +33,11 @@
import android.service.quicksettings.IQSService;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
+import libcore.util.Objects;
import java.util.Set;
@@ -98,6 +99,17 @@
}
}
+ public boolean isActiveTile() {
+ try {
+ ServiceInfo info = mContext.getPackageManager().getServiceInfo(mIntent.getComponent(),
+ PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA);
+ return info.metaData != null
+ && info.metaData.getBoolean(TileService.META_DATA_ACTIVE_TILE, false);
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
/**
* Binds just long enough to send any queued messages, then unbinds.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index 664ddd6..ab21532 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -21,7 +21,6 @@
import android.os.Handler;
import android.os.UserHandle;
import android.service.quicksettings.IQSTileService;
-import android.service.quicksettings.TileService;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
@@ -51,7 +50,6 @@
private int mPriority;
private boolean mJustBound;
private long mLastUpdate;
- private int mType;
private boolean mShowingDialog;
// Whether we have a pending bind going out to the service without a response yet.
// This defaults to true to ensure tiles start out unavailable.
@@ -69,25 +67,11 @@
mServices = tileServices;
mHandler = handler;
mStateManager = tileLifecycleManager;
- mType = tileServices.getContext().getSharedPreferences(PREFS_FILE, 0)
- .getInt(tileLifecycleManager.getComponent().flattenToString(),
- TileService.TILE_MODE_UNSET);
mStateManager.setQSService(tileServices);
- if (mType == TileService.TILE_MODE_UNSET) {
- bindService();
- mStateManager.onTileAdded();
- }
}
- public int getType() {
- return mType;
- }
-
- public void setType(int type) {
- mServices.getContext().getSharedPreferences(PREFS_FILE, 0).edit()
- .putInt(mStateManager.getComponent().flattenToString(), type).commit();
- mType = type;
- mServices.recalculateBindAllowance();
+ public boolean isActiveTile() {
+ return mStateManager.isActiveTile();
}
public void setShowingDialog(boolean dialog) {
@@ -114,7 +98,7 @@
public void setLastUpdate(long lastUpdate) {
mLastUpdate = lastUpdate;
- if (mBound && mType == TileService.TILE_MODE_ACTIVE) {
+ if (mBound && isActiveTile()) {
mStateManager.onStopListening();
setBindRequested(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 5bb2a35..f36d013 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -153,7 +153,7 @@
return;
}
TileServiceManager service = mServices.get(customTile);
- if (service.getType() != TileService.TILE_MODE_ACTIVE) {
+ if (!service.isActiveTile()) {
return;
}
service.setBindRequested(true);
@@ -165,17 +165,6 @@
}
@Override
- public void setTileMode(ComponentName component, int mode) {
- verifyCaller(component.getPackageName());
- CustomTile customTile = getTileForComponent(component);
- if (customTile != null) {
- synchronized (mServices) {
- mServices.get(customTile).setType(mode);
- }
- }
- }
-
- @Override
public void updateQsTile(Tile tile) {
ComponentName componentName = tile.getComponentName();
verifyCaller(componentName.getPackageName());
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 2032783..e494fd8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -25,6 +25,7 @@
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
@@ -207,18 +208,21 @@
}
}
});
+ final TextView batterySaverTitle =
+ (TextView) mCurrentView.findViewById(android.R.id.title);
+ final TextView batterySaverSummary =
+ (TextView) mCurrentView.findViewById(android.R.id.summary);
if (mCharging) {
- ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
- R.string.battery_detail_charging_summary);
- mCurrentView.findViewById(android.R.id.icon).setVisibility(View.INVISIBLE);
+ mCurrentView.findViewById(R.id.switch_container).setAlpha(.7f);
+ batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
+ batterySaverTitle.setText(R.string.battery_detail_charging_summary);
mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.GONE);
mCurrentView.findViewById(R.id.switch_container).setClickable(false);
} else {
- ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
- R.string.battery_detail_switch_title);
- ((TextView) mCurrentView.findViewById(android.R.id.summary)).setText(
- R.string.battery_detail_switch_summary);
- mCurrentView.findViewById(android.R.id.icon).setVisibility(View.VISIBLE);
+ mCurrentView.findViewById(R.id.switch_container).setAlpha(1);
+ batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
+ batterySaverTitle.setText(R.string.battery_detail_switch_title);
+ batterySaverSummary.setText(R.string.battery_detail_switch_summary);
mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.VISIBLE);
mCurrentView.findViewById(R.id.switch_container).setClickable(true);
mCurrentView.findViewById(R.id.switch_container).setOnClickListener(this);
@@ -227,7 +231,7 @@
private void bindBatteryInfo(BatteryInfo info) {
SpannableStringBuilder builder = new SpannableStringBuilder();
- builder.append(info.batteryPercentString, new RelativeSizeSpan(2),
+ builder.append(info.batteryPercentString, new RelativeSizeSpan(2.6f),
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
if (info.remainingLabel != null) {
if (mContext.getResources().getBoolean(R.bool.quick_settings_wide)) {
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 1fef8f1..63c85db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -216,7 +216,6 @@
mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
R.string.quick_settings_bluetooth_detail_empty_text);
mItems.setCallback(this);
- mItems.setMinHeightInItems(0);
updateItems();
setItemsVisible(mState.value);
return mItems;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index fcf758b..99eae02 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -30,6 +30,7 @@
import android.widget.TextView;
import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.drawable.UserIconDrawable;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.UserAvatarView;
@@ -87,25 +88,29 @@
return (UserDetailItemView) convertView;
}
- public void bind(String name, Bitmap picture) {
+ public void bind(String name, Bitmap picture, int userId) {
mName.setText(name);
- mAvatar.setBitmap(picture);
+ mAvatar.setAvatarWithBadge(picture, userId);
}
- public void bind(String name, Drawable picture) {
+ public void bind(String name, Drawable picture, int userId) {
mName.setText(name);
- mAvatar.setDrawable(picture);
+ mAvatar.setDrawableWithBadge(picture, userId);
+ }
+
+ public void setAvatarEnabled(boolean enabled) {
+ mAvatar.setEnabled(enabled);
}
public void setDisabledByAdmin(boolean disabled) {
mRestrictedPadlock.setVisibility(disabled ? View.VISIBLE : View.GONE);
mName.setEnabled(!disabled);
- mAvatar.setDisabled(disabled);
+ mAvatar.setEnabled(!disabled);
}
public void setEnabled(boolean enabled) {
mName.setEnabled(enabled);
- mAvatar.setDisabled(!enabled);
+ mAvatar.setEnabled(enabled);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index da98762..d4fa765 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -76,9 +76,9 @@
}
String name = getName(mContext, item);
if (item.picture == null) {
- v.bind(name, getDrawable(mContext, item));
+ v.bind(name, getDrawable(mContext, item), item.resolveId());
} else {
- v.bind(name, item.picture);
+ v.bind(name, item.picture, item.info.id);
}
v.setActivated(item.isCurrent);
v.setDisabledByAdmin(item.isDisabledByAdmin);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index aba05aa..fda340d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.View.MeasureSpec;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -36,7 +37,6 @@
import android.util.MutableBoolean;
import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewConfiguration;
import com.android.internal.logging.MetricsLogger;
@@ -45,7 +45,6 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.ForcedResizableEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
@@ -125,13 +124,6 @@
loader.loadTasks(mContext, plan, launchOpts);
}
}
-
- @Override
- public void onActivityForcedResizable(String packageName, int taskId) {
- EventBus.getDefault().sendOntoMainThread(
- new ForcedResizableEvent(packageName, taskId));
-
- }
}
protected static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -608,23 +600,25 @@
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
- int taskViewWidth = taskViewBounds.width();
- synchronized (mHeaderBarLock) {
- if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
- mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
- mHeaderBar.measure(
- View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY));
+ if (!taskViewBounds.isEmpty()) {
+ int taskViewWidth = taskViewBounds.width();
+ synchronized (mHeaderBarLock) {
+ if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
+ mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
+ mHeaderBar.measure(
+ MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
+ }
+ mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
}
- mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
- }
- // Update the transition bitmap to match the new header bar height
- if (mThumbTransitionBitmapCache == null ||
- (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
- (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
- mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
- mTaskBarHeight, Bitmap.Config.ARGB_8888);
+ // Update the transition bitmap to match the new header bar height
+ if (mThumbTransitionBitmapCache == null ||
+ (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
+ (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
+ mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
+ mTaskBarHeight, Bitmap.Config.ARGB_8888);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
deleted file mode 100644
index cdcabf0..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when recents received the information that an activity got forced resizable, and we need
- * to inform the user about that.
- */
-public class ForcedResizableEvent extends EventBus.Event {
-
- public final String packageName;
- public final int taskId;
-
- public ForcedResizableEvent(String packageName, int taskId) {
- this.packageName = packageName;
- this.taskId = taskId;
- }
-}
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 1a4b40f..2d5addb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -144,6 +144,7 @@
public void onPinnedActivityRestartAttempt() { }
public void onPinnedStackAnimationEnded() { }
public void onActivityForcedResizable(String packageName, int taskId) { }
+ public void onActivityDismissingDockedStack() { }
}
/**
@@ -182,6 +183,11 @@
mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, 0, packageName)
.sendToTarget();
}
+
+ @Override
+ public void onActivityDismissingDockedStack() throws RemoteException {
+ mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
+ }
};
/**
@@ -1091,6 +1097,7 @@
private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 3;
private static final int ON_PINNED_STACK_ANIMATION_ENDED = 4;
private static final int ON_ACTIVITY_FORCED_RESIZABLE = 5;
+ private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 6;
@Override
public void handleMessage(Message msg) {
@@ -1126,6 +1133,12 @@
}
break;
}
+ case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onActivityDismissingDockedStack();
+ }
+ break;
+ }
}
}
}
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 f9f851a..13e1a14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -37,14 +37,12 @@
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
import com.android.systemui.recents.events.ui.UserInteractionEvent;
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -53,7 +51,9 @@
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.tv.animations.HomeRecentsEnterExitAnimationHolder;
import com.android.systemui.recents.tv.views.RecentsTvView;
+import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.tv.pip.PipManager;
@@ -76,11 +76,14 @@
private RecentsPackageMonitor mPackageMonitor;
private long mLastTabKeyEventTime;
private boolean mIgnoreAltTabRelease;
+ private boolean mLaunchedFromHome;
private RecentsTvView mRecentsView;
private View mPipView;
private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
+ private TaskStackHorizontalGridView mTaskStackHorizontalGridView;
private FinishRecentsRunnable mFinishLaunchHomeRunnable;
+ private HomeRecentsEnterExitAnimationHolder mHomeRecentsEnterExitAnimationHolder;
private final PipManager mPipManager = PipManager.getInstance();
private final PipManager.Listener mPipListener = new PipManager.Listener() {
@@ -174,6 +177,7 @@
if (!plan.hasTasks()) {
loader.preloadTasks(plan, -1, launchState.launchedFromHome);
}
+ mLaunchedFromHome = launchState.launchedFromHome;
TaskStack stack = plan.getTaskStack();
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.runningTaskId = launchState.launchedToTaskId;
@@ -187,7 +191,8 @@
Collections.reverse(stackTasks);
if (mTaskStackViewAdapter == null) {
mTaskStackViewAdapter = new TaskStackHorizontalViewAdapter(stackTasks);
- mRecentsView.setTaskStackViewAdapter(mTaskStackViewAdapter);
+ mTaskStackHorizontalGridView = mRecentsView
+ .setTaskStackViewAdapter(mTaskStackViewAdapter);
} else {
mTaskStackViewAdapter.setNewStackTasks(stackTasks);
}
@@ -229,17 +234,24 @@
}
void dismissRecentsToHome(boolean animateTaskViews) {
- DismissRecentsToHomeAnimationStarted dismissEvent =
- new DismissRecentsToHomeAnimationStarted(animateTaskViews);
- dismissEvent.addPostAnimationCallback(mFinishLaunchHomeRunnable);
- dismissEvent.addPostAnimationCallback(new Runnable() {
+ Runnable closeSystemWindows = new Runnable() {
@Override
public void run() {
Recents.getSystemServices().sendCloseSystemWindows(
BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
}
- });
- EventBus.getDefault().send(dismissEvent);
+ };
+ DismissRecentsToHomeAnimationStarted dismissEvent =
+ new DismissRecentsToHomeAnimationStarted(animateTaskViews);
+ dismissEvent.addPostAnimationCallback(mFinishLaunchHomeRunnable);
+ dismissEvent.addPostAnimationCallback(closeSystemWindows);
+
+ if(mTaskStackHorizontalGridView.getChildCount() > 0) {
+ mHomeRecentsEnterExitAnimationHolder.startExitAnimation(dismissEvent);
+ } else {
+ closeSystemWindows.run();
+ mFinishLaunchHomeRunnable.run();
+ }
}
boolean dismissRecentsToHomeIfVisible(boolean animated) {
@@ -319,6 +331,19 @@
// Update the recent tasks
updateRecentsTasks();
+ mHomeRecentsEnterExitAnimationHolder = new HomeRecentsEnterExitAnimationHolder(
+ getApplicationContext(), mTaskStackHorizontalGridView);
+ if(mTaskStackHorizontalGridView != null &&
+ mTaskStackHorizontalGridView.getChildCount() > 0) {
+ if(mLaunchedFromHome) {
+ mHomeRecentsEnterExitAnimationHolder.setEnterFromHomeStartingAnimationValues();
+ } else {
+ mHomeRecentsEnterExitAnimationHolder.setEnterFromAppStartingAnimationValues();
+ }
+ } else {
+ mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
+ }
+
// 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
@@ -340,6 +365,9 @@
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
+ if(mLaunchedFromHome) {
+ mHomeRecentsEnterExitAnimationHolder.startEnterAnimation();
+ }
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
@@ -444,12 +472,6 @@
}
}
- public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
- EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
- mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
- mRecentsView.invalidate();
- }
-
public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
int launchToTaskId = launchState.launchedToTaskId;
@@ -489,6 +511,11 @@
@Override
public boolean onPreDraw() {
mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+ if(mLaunchedFromHome) {
+ mHomeRecentsEnterExitAnimationHolder.setEnterFromHomeStartingAnimationValues();
+ } else {
+ mHomeRecentsEnterExitAnimationHolder.setEnterFromAppStartingAnimationValues();
+ }
// We post to make sure that this information is delivered after this traversals is
// finished.
mRecentsView.post(new Runnable() {
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 fb62aff..fd31872 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -25,15 +25,19 @@
import android.os.SystemClock;
import android.os.UserHandle;
+import com.android.systemui.SystemUIApplication;
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.model.ThumbnailData;
import com.android.systemui.recents.tv.views.TaskCardView;
+import com.android.systemui.statusbar.tv.TvStatusBar;
public class RecentsTvImpl extends RecentsImpl{
public final static String RECENTS_TV_ACTIVITY =
@@ -81,16 +85,7 @@
}
if (!useThumbnailTransition) {
- // If there is no thumbnail transition, but is launching from home into recents, then
- // use a quick home transition and do the animation from home
- if (hasRecentTasks) {
- ActivityOptions opts = getHomeTransitionActivityOptions();
- startRecentsActivity(topTask, opts, true /* fromHome */, false /* fromThumbnail */);
- } else {
- // Otherwise we do the normal fade from an unknown source
- ActivityOptions opts = getUnknownTransitionActivityOptions();
- startRecentsActivity(topTask, opts, true /* fromHome */, false /* fromThumbnail */);
- }
+ startRecentsActivity(topTask, null, true /* fromHome */, false /* fromThumbnail */);
}
mLastToggleTime = SystemClock.elapsedRealtime();
}
@@ -124,14 +119,26 @@
*/
private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
ActivityManager.RunningTaskInfo topTask) {
- Bitmap thumbnail = mThumbTransitionBitmapCache;
Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
- if (thumbnail != null) {
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ ThumbnailData thumbnailData = ssp.getTaskThumbnail(topTask.id);
+ if (thumbnailData.thumbnail != null) {
+ Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
+ rect.height(), false);
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
- null, (int) rect.left, (int) rect.top,
- (int) rect.width(), (int) rect.height(), mHandler, null);
+ thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
+ (int) rect.height(), mHandler, null);
}
// If both the screenshot and thumbnail fails, then just fall back to the default transition
return getUnknownTransitionActivityOptions();
}
+
+ @Override
+ public void onVisibilityChanged(Context context, boolean visible) {
+ SystemUIApplication app = (SystemUIApplication) context;
+ TvStatusBar statusBar = app.getComponent(TvStatusBar.class);
+ if (statusBar != null) {
+ statusBar.updateRecentsVisibility(visible);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
index 8996d0b..fbcfa97 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
@@ -18,9 +18,8 @@
import android.animation.Animator;
import android.content.res.Resources;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.view.View;
import android.widget.LinearLayout;
+import com.android.systemui.Interpolators;
import com.android.systemui.recents.tv.views.TaskCardView;
import com.android.systemui.R;
@@ -28,7 +27,6 @@
public class DismissAnimationsHolder {
private LinearLayout mDismissArea;
private LinearLayout mTaskCardView;
- private FastOutSlowInInterpolator mFastOutSlowIn;
private int mCardYDelta;
private long mShortDuration;
private long mLongDuration;
@@ -36,7 +34,6 @@
public DismissAnimationsHolder(TaskCardView taskCardView) {
mTaskCardView = (LinearLayout) taskCardView.findViewById(R.id.recents_tv_card);
mDismissArea = (LinearLayout) taskCardView.findViewById(R.id.card_dismiss);
- mFastOutSlowIn = new FastOutSlowInInterpolator();
Resources res = taskCardView.getResources();
mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down);
@@ -45,36 +42,42 @@
}
public void startEnterAnimation() {
- mDismissArea.animate().setDuration(mShortDuration);
- mDismissArea.animate().setInterpolator(mFastOutSlowIn);
- mDismissArea.animate().alpha(1.0f);
+ mDismissArea.animate()
+ .setDuration(mShortDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .alpha(1.0f);
- mTaskCardView.animate().setDuration(mShortDuration);
- mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
- mTaskCardView.animate().translationYBy(mCardYDelta);
- mTaskCardView.animate().alpha(0.5f);
+ mTaskCardView.animate()
+ .setDuration(mShortDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .translationYBy(mCardYDelta)
+ .alpha(0.5f);
}
public void startExitAnimation() {
- mDismissArea.animate().setDuration(mShortDuration);
- mDismissArea.animate().setInterpolator(mFastOutSlowIn);
- mDismissArea.animate().alpha(0.0f);
+ mDismissArea.animate()
+ .setDuration(mShortDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .alpha(0.0f);
- mTaskCardView.animate().setDuration(mShortDuration);
- mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
- mTaskCardView.animate().translationYBy(-mCardYDelta);
- mTaskCardView.animate().alpha(1.0f);
+ mTaskCardView.animate()
+ .setDuration(mShortDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .translationYBy(-mCardYDelta)
+ .alpha(1.0f);
}
public void startDismissAnimation(Animator.AnimatorListener listener) {
- mDismissArea.animate().setDuration(mShortDuration);
- mDismissArea.animate().setInterpolator(mFastOutSlowIn);
- mDismissArea.animate().alpha(0.0f);
+ mDismissArea.animate()
+ .setDuration(mShortDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .alpha(0.0f);
- mTaskCardView.animate().setDuration(mLongDuration);
- mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
- mTaskCardView.animate().translationYBy(mCardYDelta);
- mTaskCardView.animate().alpha(0.0f);
- mTaskCardView.animate().setListener(listener);
+ mTaskCardView.animate()
+ .setDuration(mLongDuration)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .translationYBy(mCardYDelta)
+ .alpha(0.0f)
+ .setListener(listener);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java
new file mode 100644
index 0000000..278de87
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java
@@ -0,0 +1,91 @@
+/*
+ * 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.systemui.recents.tv.animations;
+
+import android.content.Context;
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.tv.views.TaskCardView;
+import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
+
+
+public class HomeRecentsEnterExitAnimationHolder {
+
+ private Context mContext;
+ private TaskStackHorizontalGridView mGridView;
+ private long mDelay;
+ private int mDuration;
+ private int mTranslationX;
+
+ public HomeRecentsEnterExitAnimationHolder(Context context,
+ TaskStackHorizontalGridView gridView) {
+ mContext = context;
+ mGridView = gridView;
+ mTranslationX = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.recents_tv_home_recents_shift);
+ mDelay = mContext.getResources().getInteger(R.integer.recents_home_delay);
+ mDuration = mContext.getResources().getInteger(R.integer.recents_home_duration);
+ }
+
+ public void startEnterAnimation() {
+ for(int i = 0; i < mGridView.getChildCount(); i++) {
+ TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+ view.setTranslationX(-mTranslationX);
+ view.setAlpha(0.0f);
+ view.animate()
+ .alpha(1.0f)
+ .translationX(0)
+ .setDuration(mDuration)
+ .setStartDelay(mDelay * i)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ }
+ }
+
+ public void startExitAnimation(DismissRecentsToHomeAnimationStarted dismissEvent) {
+ for(int i = mGridView.getChildCount() - 1; i >= 0; i--) {
+ TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+ view.animate()
+ .alpha(0.0f)
+ .translationXBy(-mTranslationX)
+ .setDuration(mDuration)
+ .setStartDelay(mDelay * (mGridView.getChildCount() - 1 - i))
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ if(i == 0) {
+ view.animate().setListener(dismissEvent.getAnimationTrigger()
+ .decrementOnAnimationEnd());
+ dismissEvent.getAnimationTrigger().increment();
+ }
+ }
+ }
+
+ public void setEnterFromHomeStartingAnimationValues() {
+ for(int i = 0; i < mGridView.getChildCount(); i++) {
+ TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+ view.setTranslationX(-mTranslationX);
+ view.setAlpha(0.0f);
+ }
+ }
+
+ public void setEnterFromAppStartingAnimationValues() {
+ for(int i = 0; i < mGridView.getChildCount(); i++) {
+ TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+ view.setTranslationX(0);
+ view.setAlpha(1.0f);
+ }
+ }
+}
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 a69f8a2..fb1127e 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
@@ -16,8 +16,10 @@
package com.android.systemui.recents.tv.views;
import android.annotation.Nullable;
+import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -120,8 +122,10 @@
}
try {
Rect taskRect = taskView.getFocusedThumbnailRect();
+ Bitmap thumbnail = Bitmap.createScaledBitmap(task.thumbnail, taskRect.width(),
+ taskRect.height(), false);
WindowManagerGlobal.getWindowManagerService()
- .overridePendingAppTransitionAspectScaledThumb(task.thumbnail, taskRect.left,
+ .overridePendingAppTransitionAspectScaledThumb(thumbnail, taskRect.left,
taskRect.top, taskRect.width(), taskRect.height(), callback, true);
} catch (RemoteException e) {
Log.w(TAG, "Failed to override transition: " + e);
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 9da8eed..53fdf62 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
@@ -18,7 +18,10 @@
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
@@ -32,15 +35,15 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
import com.android.systemui.recents.events.activity.LaunchTvTaskEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
-
-import java.util.ArrayList;
-import java.util.List;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
/**
* Top level layout of recents for TV. This will show the TaskStacks using a HorizontalGridView.
@@ -58,7 +61,7 @@
private Rect mSystemInsets = new Rect();
private RecentsTvTransitionHelper mTransitionHelper;
private Handler mHandler;
-
+ private OnScrollListener mScrollListener;
public RecentsTvView(Context context) {
this(context, null);
}
@@ -111,8 +114,7 @@
if (mTaskStackHorizontalView != null) {
Task task = mTaskStackHorizontalView.getFocusedTask();
if (task != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ launchTaskFomRecents(task);
return true;
}
}
@@ -125,25 +127,53 @@
TaskStack stack = mTaskStackHorizontalView.getStack();
Task task = stack.getLaunchTarget();
if (task != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ launchTaskFomRecents(task);
return true;
}
}
return false;
}
- /** Launches a given task. */
- public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
- if (mTaskStackHorizontalView != null) {
- // Iterate the stack views and try and find the given task.
- if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
- return true;
+ /**
+ * Launch the given task from recents with animation. If the task is not focused, this will
+ * attempt to scroll to focus the task before launching.
+ * @param task
+ */
+ private void launchTaskFomRecents(final Task task) {
+ if(task != mTaskStackHorizontalView.getFocusedTask()) {
+ if(mScrollListener != null) {
+ mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
}
+ mScrollListener = new OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ if(newState == RecyclerView.SCROLL_STATE_IDLE) {
+ TaskCardView cardView = mTaskStackHorizontalView.getChildViewForTask(task);
+ if(cardView != null) {
+ mTransitionHelper.launchTaskFromRecents(mStack, task,
+ mTaskStackHorizontalView, cardView, null, INVALID_STACK_ID);
+ } else {
+ // This should not happen normally. If this happens then the data in
+ // the grid view was altered during the scroll. Log error and launch
+ // task with no animation.
+ Log.e(TAG, "Card view for task : " + task + ", returned null.");
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ }
+ mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
+ }
+ }
+ };
+ mTaskStackHorizontalView.addOnScrollListener(mScrollListener);
+ mTaskStackHorizontalView.setSelectedPositionSmooth(
+ ((TaskStackHorizontalViewAdapter) mTaskStackHorizontalView.getAdapter())
+ .getPositionOfTask(task));
+ } else {
+ mTransitionHelper.launchTaskFromRecents(mStack, task, mTaskStackHorizontalView,
+ mTaskStackHorizontalView.getChildViewForTask(task), null,
+ INVALID_STACK_ID);
}
- return false;
}
/**
@@ -218,9 +248,15 @@
}
}
- public void setTaskStackViewAdapter(TaskStackHorizontalViewAdapter taskStackViewAdapter) {
+ public TaskStackHorizontalGridView setTaskStackViewAdapter(
+ TaskStackHorizontalViewAdapter taskStackViewAdapter) {
if(mTaskStackHorizontalView != null) {
mTaskStackHorizontalView.setAdapter(taskStackViewAdapter);
}
+ return mTaskStackHorizontalView;
+ }
+
+ public TaskStackHorizontalGridView getGridView() {
+ return mTaskStackHorizontalView;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index d605748..99d478b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -64,6 +64,7 @@
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
mThumbnailView = (ImageView) findViewById(R.id.card_view_thumbnail);
mTitleTextView = (TextView) findViewById(R.id.card_title_text);
mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
@@ -91,13 +92,6 @@
public Rect getFocusedThumbnailRect() {
Rect r = new Rect();
mThumbnailView.getGlobalVisibleRect(r);
- TypedValue out = new TypedValue();
- getContext().getResources().getValue(R.integer.selected_scale, out, true);
- float deltaScale = (out.getFloat() - 1.0f) / 2;
- r.set((int) (r.left - r.left * deltaScale),
- (int) (r.top - r.top * deltaScale),
- (int) (r.right + r.right * deltaScale),
- (int) (r.bottom + r.bottom * deltaScale));
return r;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
index 3788719..97712ea 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
@@ -131,4 +131,9 @@
mTaskList.remove(position);
notifyItemRemoved(position);
}
+
+ public int getPositionOfTask(Task task) {
+ int position = mTaskList.indexOf(task);
+ return (position >= 0) ? position : 0;
+ }
}
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 9eec2ce..fd8df99 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -116,6 +116,7 @@
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+ stackView.cancelAllTaskViewAnimations();
if (screenPinningRequested) {
// Request screen pinning after the animation runs
@@ -133,6 +134,7 @@
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+ stackView.cancelAllTaskViewAnimations();
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 33d5bb7..a867bde 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -19,15 +19,20 @@
import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Point;
+import android.graphics.Rect;
+import android.provider.Settings;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.widget.Toast;
+import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
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.ConfigurationChangedEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
@@ -81,12 +86,20 @@
private float mDragSlop;
private DropTarget mLastDropTarget;
+ private DividerSnapAlgorithm mDividerSnapAlgorithm;
private ArrayList<DropTarget> mDropTargets = new ArrayList<>();
private ArrayList<TaskStack.DockState> mVisibleDockStates = new ArrayList<>();
public RecentsViewTouchHandler(RecentsView rv) {
mRv = rv;
mDragSlop = ViewConfiguration.get(rv.getContext()).getScaledTouchSlop();
+ updateSnapAlgorithm();
+ }
+
+ private void updateSnapAlgorithm() {
+ Rect insets = new Rect();
+ SystemServicesProxy.getInstance(mRv.getContext()).getStableInsets(insets);
+ mDividerSnapAlgorithm = DividerSnapAlgorithm.create(mRv.getContext(), insets);
}
/**
@@ -150,7 +163,8 @@
mTaskView.setTranslationY(y);
mVisibleDockStates.clear();
- if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask()) {
+ if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask()
+ && mDividerSnapAlgorithm.isSplitScreenFeasible()) {
if (!event.task.isDockable) {
Toast.makeText(mRv.getContext(), R.string.recents_drag_non_dockable_task_message,
Toast.LENGTH_SHORT).show();
@@ -176,6 +190,10 @@
mLastDropTarget = null;
}
+ public final void onBusEvent(ConfigurationChangedEvent event) {
+ updateSnapAlgorithm();
+ }
+
/**
* Handles dragging touch events
*/
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 f8ed700..6e585ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -146,6 +146,8 @@
AnimateableViewBounds mViewBounds;
private AnimatorSet mTransformAnimation;
+ private ObjectAnimator mDimAnimator;
+ private ObjectAnimator mOutlineAnimator;
private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform();
private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
@@ -308,14 +310,14 @@
} else {
// Both the progress and the update are a function of the bounds movement of the task
if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
- ObjectAnimator anim = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
+ mDimAnimator = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
toTransform.dimAlpha);
- mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+ mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mDimAnimator));
}
if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
- ObjectAnimator anim = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
+ mOutlineAnimator = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
- mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+ mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mOutlineAnimator));
}
if (updateCallback != null) {
ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
@@ -358,6 +360,8 @@
*/
public void cancelTransformAnimation() {
Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation);
+ Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+ Utilities.cancelAnimationWithoutCallbacks(mOutlineAnimator);
}
/** Enables/disables handling touch on this task view. */
@@ -537,13 +541,15 @@
@Override
public void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger) {
+ Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+
// Dim the view after the app window transitions down into recents
postAnimationTrigger.increment();
AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
- Animator anim = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
+ mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
DIM_ALPHA_WITHOUT_HEADER, getDimAlpha(), transform.dimAlpha));
- anim.addListener(postAnimationTrigger.decrementOnAnimationEnd());
- anim.start();
+ mDimAnimator.addListener(postAnimationTrigger.decrementOnAnimationEnd());
+ mDimAnimator.start();
if (screenPinningEnabled) {
showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
@@ -553,11 +559,13 @@
@Override
public void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
ReferenceCountedTrigger postAnimationTrigger) {
+ Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+
// Un-dim the view before/while launching the target
AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
- Animator anim = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
+ mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
DIM_ALPHA, getDimAlpha(), 0));
- anim.start();
+ mDimAnimator.start();
postAnimationTrigger.increment();
hideActionButton(true /* fadeOut */, duration,
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
index f728dab..d4922c3 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
@@ -23,6 +23,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
+import android.widget.TextView;
import com.android.systemui.R;
@@ -45,6 +46,8 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.forced_resizable_activity);
+ TextView tv = (TextView) findViewById(com.android.internal.R.id.message);
+ tv.setText(R.string.dock_forced_resizable);
getWindow().getDecorView().setOnTouchListener(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 9b56037..9294ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -20,12 +20,14 @@
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
-import android.util.ArrayMap;
import android.util.ArraySet;
+import android.widget.Toast;
+import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
-import com.android.systemui.recents.events.activity.ForcedResizableEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.stackdivider.events.StartedDragingEvent;
import com.android.systemui.stackdivider.events.StoppedDragingEvent;
@@ -53,6 +55,18 @@
public ForcedResizableInfoActivityController(Context context) {
mContext = context;
EventBus.getDefault().register(this);
+ SystemServicesProxy.getInstance(context).registerTaskStackListener(
+ new TaskStackListener() {
+ @Override
+ public void onActivityForcedResizable(String packageName, int taskId) {
+ activityForcedResizable(packageName, taskId);
+ }
+
+ @Override
+ public void onActivityDismissingDockedStack() {
+ activityDismissingDockedStack();
+ }
+ });
}
public void notifyDockedStackExistsChanged(boolean exists) {
@@ -61,14 +75,6 @@
}
}
- public final void onBusEvent(ForcedResizableEvent forcedResizableEvent) {
- if (debounce(forcedResizableEvent.packageName)) {
- return;
- }
- mPendingTaskIds.add(forcedResizableEvent.taskId);
- postTimeout();
- }
-
public final void onBusEvent(AppTransitionFinishedEvent event) {
if (!mDividerDraging) {
showPending();
@@ -85,6 +91,20 @@
showPending();
}
+ private void activityForcedResizable(String packageName, int taskId) {
+ if (debounce(packageName)) {
+ return;
+ }
+ mPendingTaskIds.add(taskId);
+ postTimeout();
+ }
+
+ private void activityDismissingDockedStack() {
+ Toast toast = Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
+ Toast.LENGTH_SHORT);
+ toast.show();
+ }
+
private void showPending() {
mHandler.removeCallbacks(mTimeoutRunnable);
for (int i = mPendingTaskIds.size() - 1; i >= 0; i--) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 29b6908..1b2393a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -287,9 +287,10 @@
private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
- // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- // so we just dump our cache ...
+ // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or
+ // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ...
mUsersAllowingPrivateNotifications.clear();
+ mUsersAllowingNotifications.clear();
// ... and refresh all the notifications
updateNotifications();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 3067714..2045ec8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar;
import android.content.Context;
+import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.View;
@@ -51,6 +52,12 @@
|| touchY > mContent.getY() + mContent.getHeight();
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ mDismissButton.setText(R.string.clear_all_notifications_text);
+ }
+
public boolean isButtonVisible() {
return mDismissButton.getAlpha() != 0.0f;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7ca7d12..e25f9de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -618,6 +618,19 @@
return mOnKeyguard;
}
+ public void removeAllChildren() {
+ List<ExpandableNotificationRow> notificationChildren
+ = mChildrenContainer.getNotificationChildren();
+ ArrayList<ExpandableNotificationRow> clonedList = new ArrayList<>(notificationChildren);
+ for (int i = 0; i < clonedList.size(); i++) {
+ ExpandableNotificationRow row = clonedList.get(i);
+ mChildrenContainer.removeNotification(row);
+ mHeaderUtil.restoreNotificationHeader(row);
+ row.setIsChildInGroup(false, null);
+ }
+ onChildrenCountChanged();
+ }
+
public interface ExpansionLogger {
public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 646efa2..11aaedf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -17,16 +17,24 @@
package com.android.systemui.statusbar;
import android.app.AlertDialog;
+import android.app.AppGlobals;
import android.app.Dialog;
+import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Icon;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.Looper;
+import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
@@ -42,8 +50,10 @@
import android.view.WindowManager.KeyboardShortcutsReceiver;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.internal.app.AssistUtils;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
@@ -58,7 +68,6 @@
*/
public final class KeyboardShortcuts {
private static final String TAG = KeyboardShortcuts.class.getSimpleName();
-
private final SparseArray<String> mSpecialCharacterNames = new SparseArray<>();
private final SparseArray<String> mModifierNames = new SparseArray<>();
private final SparseArray<Drawable> mSpecialCharacterDrawables = new SparseArray<>();
@@ -66,6 +75,7 @@
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Context mContext;
+ private final IPackageManager mPackageManager;
private final OnClickListener dialogCloseListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismissKeyboardShortcutsDialog();
@@ -77,6 +87,7 @@
public KeyboardShortcuts(Context context) {
this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_Material_Light);
+ this.mPackageManager = AppGlobals.getPackageManager();
loadResources(context);
}
@@ -251,68 +262,11 @@
@Override
public void onKeyboardShortcutsReceived(
final List<KeyboardShortcutGroup> result) {
- KeyboardShortcutGroup systemGroup = new KeyboardShortcutGroup(
- mContext.getString(R.string.keyboard_shortcut_group_system), true);
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_system_home),
- KeyEvent.KEYCODE_ENTER, KeyEvent.META_META_ON));
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_system_back),
- KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON));
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_system_recents),
- KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_ON));
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_system_notifications),
- KeyEvent.KEYCODE_N, KeyEvent.META_META_ON));
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_system_shortcuts_helper),
- KeyEvent.KEYCODE_SLASH, KeyEvent.META_META_ON));
- systemGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_system_switch_input),
- KeyEvent.KEYCODE_SPACE, KeyEvent.META_META_ON));
- result.add(systemGroup);
-
- KeyboardShortcutGroup applicationGroup = new KeyboardShortcutGroup(
- mContext.getString(R.string.keyboard_shortcut_group_applications),
- true);
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_assist),
- KeyEvent.KEYCODE_UNKNOWN, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_browser),
- KeyEvent.KEYCODE_B, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_contacts),
- KeyEvent.KEYCODE_C, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_email),
- KeyEvent.KEYCODE_E, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_im),
- KeyEvent.KEYCODE_T, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_music),
- KeyEvent.KEYCODE_P, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_youtube),
- KeyEvent.KEYCODE_Y, KeyEvent.META_META_ON));
- applicationGroup.addItem(new KeyboardShortcutInfo(
- mContext.getString(
- R.string.keyboard_shortcut_group_applications_calendar),
- KeyEvent.KEYCODE_L, KeyEvent.META_META_ON));
- result.add(applicationGroup);
-
+ result.add(getSystemShortcuts());
+ final KeyboardShortcutGroup appShortcuts = getDefaultApplicationShortcuts();
+ if (appShortcuts != null) {
+ result.add(appShortcuts);
+ }
showKeyboardShortcutsDialog(result);
}
}, deviceId);
@@ -357,6 +311,160 @@
}
}
+ private KeyboardShortcutGroup getSystemShortcuts() {
+ final KeyboardShortcutGroup systemGroup = new KeyboardShortcutGroup(
+ mContext.getString(R.string.keyboard_shortcut_group_system), true);
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_system_home),
+ KeyEvent.KEYCODE_ENTER,
+ KeyEvent.META_META_ON));
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_system_back),
+ KeyEvent.KEYCODE_DEL,
+ KeyEvent.META_META_ON));
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_system_recents),
+ KeyEvent.KEYCODE_TAB,
+ KeyEvent.META_ALT_ON));
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(
+ R.string.keyboard_shortcut_group_system_notifications),
+ KeyEvent.KEYCODE_N,
+ KeyEvent.META_META_ON));
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(
+ R.string.keyboard_shortcut_group_system_shortcuts_helper),
+ KeyEvent.KEYCODE_SLASH,
+ KeyEvent.META_META_ON));
+ systemGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(
+ R.string.keyboard_shortcut_group_system_switch_input),
+ KeyEvent.KEYCODE_SPACE,
+ KeyEvent.META_META_ON));
+ return systemGroup;
+ }
+
+ private KeyboardShortcutGroup getDefaultApplicationShortcuts() {
+ final int userId = mContext.getUserId();
+ final KeyboardShortcutGroup applicationGroup = new KeyboardShortcutGroup(
+ mContext.getString(R.string.keyboard_shortcut_group_applications),
+ true);
+
+ // Assist.
+ final AssistUtils assistUtils = new AssistUtils(mContext);
+ final ComponentName assistComponent = assistUtils.getAssistComponentForUser(userId);
+ PackageInfo assistPackageInfo = null;
+ try {
+ assistPackageInfo = mPackageManager.getPackageInfo(
+ assistComponent.getPackageName(), 0, userId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "PackageManagerService is dead");
+ }
+
+ if (assistPackageInfo != null) {
+ final Icon assistIcon = Icon.createWithResource(
+ assistPackageInfo.applicationInfo.packageName,
+ assistPackageInfo.applicationInfo.icon);
+
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_assist),
+ assistIcon,
+ KeyEvent.KEYCODE_UNKNOWN,
+ KeyEvent.META_META_ON));
+ }
+
+ // Browser.
+ final Icon browserIcon = getIconForIntentCategory(Intent.CATEGORY_APP_BROWSER, userId);
+ if (browserIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
+ browserIcon,
+ KeyEvent.KEYCODE_B,
+ KeyEvent.META_META_ON));
+ }
+
+
+ // Contacts.
+ final Icon contactsIcon = getIconForIntentCategory(Intent.CATEGORY_APP_CONTACTS, userId);
+ if (contactsIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
+ contactsIcon,
+ KeyEvent.KEYCODE_C,
+ KeyEvent.META_META_ON));
+ }
+
+ // Email.
+ final Icon emailIcon = getIconForIntentCategory(Intent.CATEGORY_APP_EMAIL, userId);
+ if (emailIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_email),
+ emailIcon,
+ KeyEvent.KEYCODE_E,
+ KeyEvent.META_META_ON));
+ }
+
+ // Messaging.
+ final Icon messagingIcon = getIconForIntentCategory(Intent.CATEGORY_APP_MESSAGING, userId);
+ if (messagingIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_im),
+ messagingIcon,
+ KeyEvent.KEYCODE_T,
+ KeyEvent.META_META_ON));
+ }
+
+ // Music.
+ final Icon musicIcon = getIconForIntentCategory(Intent.CATEGORY_APP_MUSIC, userId);
+ if (musicIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_music),
+ musicIcon,
+ KeyEvent.KEYCODE_P,
+ KeyEvent.META_META_ON));
+ }
+
+ // Calendar.
+ final Icon calendarIcon = getIconForIntentCategory(Intent.CATEGORY_APP_CALENDAR, userId);
+ if (calendarIcon != null) {
+ applicationGroup.addItem(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
+ calendarIcon,
+ KeyEvent.KEYCODE_L,
+ KeyEvent.META_META_ON));
+ }
+
+ return applicationGroup.getItems().size() == 0 ? null : applicationGroup;
+ }
+
+ private Icon getIconForIntentCategory(String intentCategory, int userId) {
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(intentCategory);
+
+ final PackageInfo packageInfo = getPackageInfoForIntent(intent, userId);
+ if (packageInfo != null && packageInfo.applicationInfo.icon != 0) {
+ return Icon.createWithResource(
+ packageInfo.applicationInfo.packageName,
+ packageInfo.applicationInfo.icon);
+ }
+ return null;
+ }
+
+ private PackageInfo getPackageInfoForIntent(Intent intent, int userId) {
+ try {
+ ResolveInfo handler;
+ handler = mPackageManager.resolveIntent(
+ intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), 0, userId);
+ if (handler == null || handler.activityInfo == null) {
+ return null;
+ }
+ return mPackageManager.getPackageInfo(handler.activityInfo.packageName, 0, userId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "PackageManagerService is dead", e);
+ return null;
+ }
+ }
+
private void showKeyboardShortcutsDialog(
final List<KeyboardShortcutGroup> keyboardShortcutGroups) {
// Need to post on the main thread.
@@ -414,9 +522,23 @@
}
View shortcutView = inflater.inflate(R.layout.keyboard_shortcut_app_item,
shortcutContainer, false);
- TextView textView = (TextView) shortcutView
+
+ if (info.getIcon() != null) {
+ ImageView shortcutIcon = (ImageView) shortcutView
+ .findViewById(R.id.keyboard_shortcuts_icon);
+ shortcutIcon.setImageIcon(info.getIcon());
+ shortcutIcon.setVisibility(View.VISIBLE);
+ }
+
+ TextView shortcutKeyword = (TextView) shortcutView
.findViewById(R.id.keyboard_shortcuts_keyword);
- textView.setText(info.getLabel());
+ shortcutKeyword.setText(info.getLabel());
+ if (info.getIcon() != null) {
+ RelativeLayout.LayoutParams lp =
+ (RelativeLayout.LayoutParams) shortcutKeyword.getLayoutParams();
+ lp.removeRule(RelativeLayout.ALIGN_PARENT_START);
+ shortcutKeyword.setLayoutParams(lp);
+ }
ViewGroup shortcutItemsContainer = (ViewGroup) shortcutView
.findViewById(R.id.keyboard_shortcuts_item_container);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c9fe2bd..6570221 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -34,6 +34,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Map;
import java.util.Objects;
/**
@@ -257,16 +258,21 @@
}
public void add(Entry entry, RankingMap ranking) {
- mEntries.put(entry.notification.getKey(), entry);
- updateRankingAndSort(ranking);
+ synchronized (mEntries) {
+ mEntries.put(entry.notification.getKey(), entry);
+ }
mGroupManager.onEntryAdded(entry);
+ updateRankingAndSort(ranking);
}
public Entry remove(String key, RankingMap ranking) {
- Entry removed = mEntries.remove(key);
+ Entry removed = null;
+ synchronized (mEntries) {
+ removed = mEntries.remove(key);
+ }
if (removed == null) return null;
- updateRankingAndSort(ranking);
mGroupManager.onEntryRemoved(removed);
+ updateRankingAndSort(ranking);
return removed;
}
@@ -316,9 +322,30 @@
return Ranking.IMPORTANCE_UNSPECIFIED;
}
+ public String getOverrideGroupKey(String key) {
+ if (mRankingMap != null) {
+ mRankingMap.getRanking(key, mTmpRanking);
+ return mTmpRanking.getOverrideGroupKey();
+ }
+ return null;
+ }
+
private void updateRankingAndSort(RankingMap ranking) {
if (ranking != null) {
mRankingMap = ranking;
+ synchronized (mEntries) {
+ final int N = mEntries.size();
+ for (int i = 0; i < N; i++) {
+ Entry entry = mEntries.valueAt(i);
+ final StatusBarNotification oldSbn = entry.notification.clone();
+ final String overrideGroupKey = getOverrideGroupKey(entry.key);
+ if (!Objects.equals(oldSbn.getOverrideGroupKey(), overrideGroupKey)) {
+ entry.notification.setOverrideGroupKey(overrideGroupKey);
+ mGroupManager.onEntryUpdated(entry, oldSbn);
+ }
+ //mGroupManager.onEntryBundlingUpdated(entry, getOverrideGroupKey(entry.key));
+ }
+ }
}
filterAndSort();
}
@@ -328,16 +355,18 @@
public void filterAndSort() {
mSortedAndFiltered.clear();
- final int N = mEntries.size();
- for (int i = 0; i < N; i++) {
- Entry entry = mEntries.valueAt(i);
- StatusBarNotification sbn = entry.notification;
+ synchronized (mEntries) {
+ final int N = mEntries.size();
+ for (int i = 0; i < N; i++) {
+ Entry entry = mEntries.valueAt(i);
+ StatusBarNotification sbn = entry.notification;
- if (shouldFilterOut(sbn)) {
- continue;
+ if (shouldFilterOut(sbn)) {
+ continue;
+ }
+
+ mSortedAndFiltered.add(entry);
}
-
- mSortedAndFiltered.add(entry);
}
Collections.sort(mSortedAndFiltered, mRankingComparator);
@@ -398,16 +427,17 @@
NotificationData.Entry e = mSortedAndFiltered.get(active);
dumpEntry(pw, indent, active, e);
}
-
- int M = mEntries.size();
- pw.print(indent);
- pw.println("inactive notifications: " + (M - active));
- int inactiveCount = 0;
- for (int i = 0; i < M; i++) {
- Entry entry = mEntries.valueAt(i);
- if (!mSortedAndFiltered.contains(entry)) {
- dumpEntry(pw, indent, inactiveCount, entry);
- inactiveCount++;
+ synchronized (mEntries) {
+ int M = mEntries.size();
+ pw.print(indent);
+ pw.println("inactive notifications: " + (M - active));
+ int inactiveCount = 0;
+ for (int i = 0; i < M; i++) {
+ Entry entry = mEntries.valueAt(i);
+ if (!mSortedAndFiltered.contains(entry)) {
+ dumpEntry(pw, indent, inactiveCount, entry);
+ inactiveCount++;
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
new file mode 100644
index 0000000..03b51c6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
@@ -0,0 +1,271 @@
+/*
+ * 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.systemui.statusbar.car;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProfile.ServiceListener;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.systemui.statusbar.policy.BatteryController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * A {@link BatteryController} that is specific to the Auto use-case. For Auto, the battery icon
+ * displays the battery status of a device that is connected via bluetooth and not the system's
+ * battery.
+ */
+public class CarBatteryController extends BroadcastReceiver implements BatteryController {
+ private static final String TAG = "CarBatteryController";
+
+ // According to the Bluetooth HFP 1.5 specification, battery levels are indicated by a
+ // value from 1-5, where these values represent the following:
+ // 0%% - 0, 1-25%% - 1, 26-50%% - 2, 51-75%% - 3, 76-99%% - 4, 100%% - 5
+ // As a result, set the level as the average within that range.
+ private static final int BATTERY_LEVEL_EMPTY = 0;
+ private static final int BATTERY_LEVEL_1 = 12;
+ private static final int BATTERY_LEVEL_2 = 28;
+ private static final int BATTERY_LEVEL_3 = 63;
+ private static final int BATTERY_LEVEL_4 = 87;
+ private static final int BATTERY_LEVEL_FULL = 100;
+
+ private static final int INVALID_BATTERY_LEVEL = -1;
+
+ private final Context mContext;
+
+ private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
+ private BluetoothHeadsetClient mBluetoothHeadsetClient;
+
+ private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+
+ private int mLevel;
+
+ /**
+ * An interface indicating the container of a View that will display what the information
+ * in the {@link CarBatteryController}.
+ */
+ public interface BatteryViewHandler {
+ void hideBatteryView();
+ void showBatteryView();
+ }
+
+ private BatteryViewHandler mBatteryViewHandler;
+
+ public CarBatteryController(Context context) {
+ mContext = context;
+
+ mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
+ BluetoothProfile.HEADSET_CLIENT);
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("CarBatteryController state:");
+ pw.print(" mLevel=");
+ pw.println(mLevel);
+ }
+
+ @Override
+ public void setPowerSaveMode(boolean powerSave) {
+ // No-op. No power save mode for the car.
+ }
+
+ @Override
+ public void addStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
+ mChangeCallbacks.add(cb);
+
+ // There is no way to know if the phone is plugged in or charging via bluetooth, so pass
+ // false for these values.
+ cb.onBatteryLevelChanged(mLevel, false /* pluggedIn */, false /* charging */);
+ cb.onPowerSaveChanged(false /* isPowerSave */);
+ }
+
+ @Override
+ public void removeStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
+ mChangeCallbacks.remove(cb);
+ }
+
+ public void addBatteryViewHandler(BatteryViewHandler batteryViewHandler) {
+ mBatteryViewHandler = batteryViewHandler;
+ }
+
+ public void startListening() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
+ mContext.registerReceiver(this, filter);
+ }
+
+ public void stopListening() {
+ mContext.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onReceive(). action: " + action);
+ }
+
+ if (BluetoothHeadsetClient.ACTION_AG_EVENT.equals(action)) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Received ACTION_AG_EVENT");
+ }
+
+ int batteryLevel = intent.getIntExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL,
+ INVALID_BATTERY_LEVEL);
+
+ updateBatteryLevel(batteryLevel);
+
+ if (batteryLevel != INVALID_BATTERY_LEVEL && mBatteryViewHandler != null) {
+ mBatteryViewHandler.showBatteryView();
+ }
+ } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
+ Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED event: "
+ + oldState + " -> " + newState);
+
+ }
+ BluetoothDevice device =
+ (BluetoothDevice)intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
+ updateBatteryIcon(device, newState);
+ }
+ }
+
+ /**
+ * Converts the battery level to a percentage that can be displayed on-screen and notifies
+ * any {@link BatteryStateChangeCallback}s of this.
+ */
+ private void updateBatteryLevel(int batteryLevel) {
+ if (batteryLevel == INVALID_BATTERY_LEVEL) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Battery level invalid. Ignoring.");
+ }
+ return;
+ }
+
+ // The battery level is a value between 0-5. Let the default battery level be 0.
+ switch (batteryLevel) {
+ case 5:
+ mLevel = BATTERY_LEVEL_FULL;
+ break;
+ case 4:
+ mLevel = BATTERY_LEVEL_4;
+ break;
+ case 3:
+ mLevel = BATTERY_LEVEL_3;
+ break;
+ case 2:
+ mLevel = BATTERY_LEVEL_2;
+ break;
+ case 1:
+ mLevel = BATTERY_LEVEL_1;
+ break;
+ case 0:
+ default:
+ mLevel = BATTERY_LEVEL_EMPTY;
+ }
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Battery level: " + batteryLevel + "; setting mLevel as: " + mLevel);
+ }
+
+ notifyBatteryLevelChanged();
+ }
+
+ /**
+ * Updates the display of the battery icon depending on the given connection state from the
+ * given {@link BluetoothDevice}.
+ */
+ private void updateBatteryIcon(BluetoothDevice device, int newState) {
+ if (newState == BluetoothProfile.STATE_CONNECTED) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Device connected");
+ }
+
+ if (mBatteryViewHandler != null) {
+ mBatteryViewHandler.showBatteryView();
+ }
+
+ if (mBluetoothHeadsetClient == null || device == null) {
+ return;
+ }
+
+ // Check if battery information is available and immediately update.
+ Bundle featuresBundle = mBluetoothHeadsetClient.getCurrentAgEvents(device);
+ if (featuresBundle == null) {
+ return;
+ }
+
+ int batteryLevel = featuresBundle.getInt(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL,
+ INVALID_BATTERY_LEVEL);
+ updateBatteryLevel(batteryLevel);
+ } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Device disconnected");
+ }
+
+ if (mBatteryViewHandler != null) {
+ mBatteryViewHandler.hideBatteryView();
+ }
+ }
+ }
+
+ @Override
+ public boolean isPowerSave() {
+ // Power save is not valid for the car, so always return false.
+ return false;
+ }
+
+ private void notifyBatteryLevelChanged() {
+ for (int i = 0, size = mChangeCallbacks.size(); i < size; i++) {
+ mChangeCallbacks.get(i)
+ .onBatteryLevelChanged(mLevel, false /* pluggedIn */, false /* charging */);
+ }
+ }
+
+ private final ServiceListener mHfpServiceListener = new ServiceListener() {
+ @Override
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ if (profile == BluetoothProfile.HEADSET_CLIENT) {
+ mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(int profile) {
+ if (profile == BluetoothProfile.HEADSET_CLIENT) {
+ mBluetoothHeadsetClient = null;
+ }
+ }
+ };
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 4add3cb..811687c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -22,37 +22,75 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewStub;
import android.view.WindowManager;
-
+import com.android.systemui.BatteryMeterView;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.PhoneStatusBarView;
+import com.android.systemui.statusbar.policy.BatteryController;
/**
* A status bar (and navigation bar) tailored for the automotive use case.
*/
-public class CarStatusBar extends PhoneStatusBar {
+public class CarStatusBar extends PhoneStatusBar implements
+ CarBatteryController.BatteryViewHandler {
+ private static final String TAG = "CarStatusBar";
+
private TaskStackListenerImpl mTaskStackListener;
private CarNavigationBarView mCarNavigationBar;
private CarNavigationBarController mController;
private FullscreenUserSwitcher mFullscreenUserSwitcher;
+ private CarBatteryController mCarBatteryController;
+ private BatteryMeterView mBatteryMeterView;
+
@Override
public void start() {
super.start();
mTaskStackListener = new TaskStackListenerImpl();
SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
registerPackageChangeReceivers();
+
+ mCarBatteryController.startListening();
+ }
+
+ @Override
+ public void destroy() {
+ mCarBatteryController.stopListening();
+ super.destroy();
+ }
+
+ @Override
+ protected PhoneStatusBarView makeStatusBarView() {
+ PhoneStatusBarView statusBarView = super.makeStatusBarView();
+
+ mBatteryMeterView = ((BatteryMeterView) statusBarView.findViewById(R.id.battery));
+
+ // By default, the BatteryMeterView should not be visible. It will be toggled visible
+ // when a device has connected by bluetooth.
+ mBatteryMeterView.setVisibility(View.GONE);
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
+ }
+
+ return statusBarView;
+ }
+
+ @Override
+ protected BatteryController createBatteryController() {
+ mCarBatteryController = new CarBatteryController(mContext);
+ mCarBatteryController.addBatteryViewHandler(this);
+ return mCarBatteryController;
}
@Override
@@ -85,6 +123,28 @@
}
+ @Override
+ public void showBatteryView() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
+ }
+
+ if (mBatteryMeterView != null) {
+ mBatteryMeterView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void hideBatteryView() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "hideBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
+ }
+
+ if (mBatteryMeterView != null) {
+ mBatteryMeterView.setVisibility(View.GONE);
+ }
+ }
+
private BroadcastReceiver mPackageChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 260c969..ec45d60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -182,7 +182,7 @@
private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
for (int i = 0; i < buttons.length; i++) {
- inflateButton(buttons[i], parent, landscape);
+ inflateButton(buttons[i], parent, landscape, i);
}
}
@@ -195,7 +195,8 @@
}
@Nullable
- protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) {
+ protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+ int indexInParent) {
LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
float size = extractSize(buttonSpec);
String button = extractButton(buttonSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index f7a6b271..fffb20a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -26,6 +26,8 @@
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Objects;
/**
* A class to handle notifications and their corresponding groups.
@@ -36,6 +38,7 @@
private OnGroupChangeListener mListener;
private int mBarState = -1;
private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
+ private HeadsUpManager mHeadsUpManager;
public void setOnGroupChangeListener(OnGroupChangeListener listener) {
mListener = listener;
@@ -121,6 +124,15 @@
}
}
+ public void onEntryBundlingUpdated(final NotificationData.Entry updated,
+ final String overrideGroupKey) {
+ final StatusBarNotification oldSbn = updated.notification.clone();
+ if (!Objects.equals(oldSbn.getOverrideGroupKey(), overrideGroupKey)) {
+ updated.notification.setOverrideGroupKey(overrideGroupKey);
+ onEntryUpdated(updated, oldSbn);
+ }
+ }
+
private void updateSuppression(NotificationGroup group) {
if (group == null) {
return;
@@ -129,9 +141,12 @@
group.suppressed = group.summary != null && !group.expanded
&& (group.children.size() == 1
|| (group.children.size() == 0
- && !group.summary.notification.getNotification().isGroupChild()
+ && group.summary.notification.getNotification().isGroupSummary()
&& hasIsolatedChildren(group)));
if (prevSuppressed != group.suppressed) {
+ if (group.suppressed) {
+ handleSuppressedSummaryHeadsUpped(group.summary);
+ }
mListener.onGroupsChanged();
}
}
@@ -150,6 +165,15 @@
return count;
}
+ private NotificationData.Entry getIsolatedChild(String groupKey) {
+ for (StatusBarNotification sbn : mIsolatedEntries.values()) {
+ if (sbn.getGroupKey().equals(groupKey) && isIsolated(sbn)) {
+ return mGroupMap.get(sbn.getKey()).summary;
+ }
+ }
+ return null;
+ }
+
public void onEntryUpdated(NotificationData.Entry entry,
StatusBarNotification oldNotification) {
if (mGroupMap.get(getGroupKey(oldNotification)) != null) {
@@ -173,7 +197,7 @@
public boolean isOnlyChildInSuppressedGroup(StatusBarNotification sbn) {
return isGroupSuppressed(sbn.getGroupKey())
- && sbn.getNotification().isGroupChild()
+ && !sbn.getNotification().isGroupSummary()
&& getTotalNumberOfChildren(sbn) == 1;
}
@@ -278,11 +302,12 @@
}
return sbn.getNotification().isGroupSummary();
}
+
private boolean isGroupChild(StatusBarNotification sbn) {
if (isIsolated(sbn)) {
return false;
}
- return sbn.getNotification().isGroupChild();
+ return sbn.isGroup() && !sbn.getNotification().isGroupSummary();
}
private String getGroupKey(StatusBarNotification sbn) {
@@ -321,6 +346,9 @@
// it doesn't lead to an update.
updateSuppression(mGroupMap.get(entry.notification.getGroupKey()));
mListener.onGroupsChanged();
+ } else {
+ handleSuppressedSummaryHeadsUpped(entry);
+
}
} else {
if (mIsolatedEntries.containsKey(sbn.getKey())) {
@@ -333,9 +361,35 @@
}
}
+ private void handleSuppressedSummaryHeadsUpped(NotificationData.Entry entry) {
+ StatusBarNotification sbn = entry.notification;
+ if (!isGroupSuppressed(sbn.getGroupKey())
+ || !sbn.getNotification().isGroupSummary()
+ || !entry.row.isHeadsUp()) {
+ return;
+ }
+ // The parent of a suppressed group got huned, lets hun the child!
+ NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
+ if (notificationGroup != null) {
+ Iterator<NotificationData.Entry> iterator = notificationGroup.children.iterator();
+ NotificationData.Entry child = iterator.hasNext() ? iterator.next() : null;
+ if (child == null) {
+ child = getIsolatedChild(sbn.getGroupKey());
+ }
+ if (child != null) {
+ if (mHeadsUpManager.isHeadsUp(child.key)) {
+ mHeadsUpManager.updateNotification(child, true);
+ } else {
+ mHeadsUpManager.showNotification(child);
+ }
+ }
+ }
+ mHeadsUpManager.releaseImmediately(entry.key);
+ }
+
private boolean shouldIsolate(StatusBarNotification sbn) {
NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
- return sbn.getNotification().isGroupChild()
+ return (sbn.isGroup() && !sbn.getNotification().isGroupSummary())
&& (sbn.getNotification().fullScreenIntent != null
|| notificationGroup == null
|| !notificationGroup.expanded
@@ -349,6 +403,10 @@
|| notificationGroup.summary.row.getTranslationY() < 0;
}
+ public void setHeadsUpManager(HeadsUpManager headsUpManager) {
+ mHeadsUpManager = headsUpManager;
+ }
+
public static class NotificationGroup {
public final HashSet<NotificationData.Entry> children = new HashSet<>();
public NotificationData.Entry summary;
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 45e94f7..62c0fa9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -306,7 +306,7 @@
// Calculate quick setting heights.
int oldMaxHeight = mQsMaxExpansionHeight;
- mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQsContainer.getHeader().getHeight();
+ mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQsContainer.getQsMinExpansionHeight();
mQsMaxExpansionHeight = mQsContainer.getDesiredHeight();
positionClockAndNotifications();
if (mQsExpanded && mQsFullyExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index c9bb15d..c4b7932 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -845,15 +845,19 @@
};
public void cancelPeek() {
+ boolean cancelled = mPeekPending;
if (mPeekAnimator != null) {
+ cancelled = true;
mPeekAnimator.cancel();
}
removeCallbacks(mPeekRunnable);
mPeekPending = false;
- // When peeking, we already tell mBar that we expanded ourselves. Make sure that we also
- // notify mBar that we might have closed ourselves.
- notifyBarPanelExpansionChanged();
+ if (cancelled) {
+ // When peeking, we already tell mBar that we expanded ourselves. Make sure that we also
+ // notify mBar that we might have closed ourselves.
+ notifyBarPanelExpansionChanged();
+ }
}
public void expand(final boolean animate) {
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 bf58592..e52a401 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -21,9 +21,7 @@
import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
-import android.app.ActivityManager.StackId;
import android.app.ActivityManagerNative;
-import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -147,6 +145,7 @@
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
@@ -730,6 +729,7 @@
mHeadsUpManager.addListener(mGroupManager);
mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
mNotificationData.setHeadsUpManager(mHeadsUpManager);
+ mGroupManager.setHeadsUpManager(mHeadsUpManager);
if (MULTIUSER_DEBUG) {
mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
@@ -826,7 +826,7 @@
// Other icons
mLocationController = new LocationControllerImpl(mContext,
mHandlerThread.getLooper()); // will post a notification
- mBatteryController = new BatteryController(mContext);
+ mBatteryController = createBatteryController();
mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
@Override
public void onPowerSaveChanged(boolean isPowerSave) {
@@ -943,6 +943,10 @@
return mStatusBarView;
}
+ protected BatteryController createBatteryController() {
+ return new BatteryControllerImpl(mContext);
+ }
+
@Override
protected void reInflateViews() {
super.reInflateViews();
@@ -1167,7 +1171,9 @@
@Override
public boolean onLongClick(View v) {
- if (mRecents == null || !ActivityManager.supportsMultiWindow()) {
+ if (mRecents == null || !ActivityManager.supportsMultiWindow()
+ || !getComponent(Divider.class).getView().getSnapAlgorithm()
+ .isSplitScreenFeasible()) {
return false;
}
@@ -1525,6 +1531,9 @@
// we are only transfering this notification to its parent, don't generate an animation
mStackScroller.setChildTransferInProgress(true);
}
+ if (remove.isSummaryWithChildren()) {
+ remove.removeAllChildren();
+ }
mStackScroller.removeView(remove);
mStackScroller.setChildTransferInProgress(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 902fd3d..cc3b4bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -41,7 +41,9 @@
private Runnable mHideExpandedRunnable = new Runnable() {
@Override
public void run() {
- mBar.makeExpandedInvisible();
+ if (mPanelFraction == 0.0f) {
+ mBar.makeExpandedInvisible();
+ }
}
};
@@ -135,6 +137,7 @@
super.onTrackingStarted();
mBar.onTrackingStarted();
mScrimController.onTrackingStarted();
+ removePendingHideExpandedRunnables();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index f3aba4f..ea9a5a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -45,7 +45,7 @@
import com.android.systemui.tuner.TunerService;
public class QuickStatusBarHeader extends BaseStatusBarHeader implements
- NextAlarmChangeCallback, OnClickListener {
+ NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener {
private static final String TAG = "QuickStatusBarHeader";
@@ -54,7 +54,7 @@
private ActivityStarter mActivityStarter;
private NextAlarmController mNextAlarmController;
private SettingsButton mSettingsButton;
- private View mSettingsContainer;
+ protected View mSettingsContainer;
private TextView mAlarmStatus;
private TextView mAlarmStatusCollapsed;
@@ -75,19 +75,19 @@
private QuickQSPanel mHeaderQsPanel;
private boolean mShowEmergencyCallsOnly;
- private MultiUserSwitch mMultiUserSwitch;
+ protected MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
private float mDateTimeTranslation;
private float mDateTimeAlarmTranslation;
private float mDateScaleFactor;
- private float mGearTranslation;
+ protected float mGearTranslation;
private TouchAnimator mSecondHalfAnimator;
private TouchAnimator mFirstHalfAnimator;
private TouchAnimator mDateSizeAnimator;
private TouchAnimator mAlarmTranslation;
- private TouchAnimator mSettingsAlpha;
+ protected TouchAnimator mSettingsAlpha;
private float mExpansionAmount;
private QSTileHost mHost;
@@ -172,6 +172,11 @@
.addFloat(mDateTimeGroup, "scaleY", 1, mDateScaleFactor)
.setStartDelay(.36f)
.build();
+
+ updateSettingsAnimator();
+ }
+
+ protected void updateSettingsAnimator() {
mSettingsAlpha = new TouchAnimator.Builder()
.addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
.addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
@@ -241,7 +246,7 @@
@Override
protected void onDetachedFromWindow() {
setListening(false);
- mHost.getUserInfoController().remListener(mUserListener);
+ mHost.getUserInfoController().remListener(this);
mHost.getNetworkController().removeEmergencyListener(this);
super.onDetachedFromWindow();
}
@@ -275,7 +280,7 @@
updateVisibilities();
}
- private void updateVisibilities() {
+ protected void updateVisibilities() {
updateAlarmVisibilities();
mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
? View.VISIBLE : View.INVISIBLE);
@@ -309,7 +314,7 @@
public void setupHost(final QSTileHost host) {
mHost = host;
- host.setHeaderView(this);
+ host.setHeaderView(mExpandIndicator);
mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this);
mHeaderQsPanel.setHost(host, null /* No customization in header */);
setUserInfoController(host.getUserInfoController());
@@ -365,7 +370,7 @@
@Override
public void setUserInfoController(UserInfoController userInfoController) {
- userInfoController.addListener(mUserListener);
+ userInfoController.addListener(this);
}
@Override
@@ -379,10 +384,8 @@
}
}
- private final OnUserInfoChangedListener mUserListener = new OnUserInfoChangedListener() {
- @Override
- public void onUserInfoChanged(String name, Drawable picture) {
- mMultiUserAvatar.setImageDrawable(picture);
- }
- };
+ @Override
+ public void onUserInfoChanged(String name, Drawable picture) {
+ mMultiUserAvatar.setImageDrawable(picture);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
index 093a827..dc1b35d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
@@ -17,69 +17,57 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
+import com.android.settingslib.drawable.UserIconDrawable;
import com.android.systemui.R;
/**
- * A view that displays a user image cropped to a circle with a frame.
+ * A view that displays a user image cropped to a circle with an optional frame.
*/
public class UserAvatarView extends View {
- private int mActiveFrameColor;
- private int mFrameColor;
- private float mFrameWidth;
- private float mFramePadding;
- private Bitmap mBitmap;
- private Drawable mDrawable;
- private boolean mIsDisabled;
-
- private final Paint mFramePaint = new Paint();
- private final Paint mBitmapPaint = new Paint();
- private final Matrix mDrawMatrix = new Matrix();
-
- private float mScale = 1;
+ private final UserIconDrawable mDrawable = new UserIconDrawable();
public UserAvatarView(Context context, AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.UserAvatarView, defStyleAttr, defStyleRes);
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
switch (attr) {
+ case R.styleable.UserAvatarView_avatarPadding:
+ setAvatarPadding(a.getDimension(attr, 0));
+ break;
case R.styleable.UserAvatarView_frameWidth:
setFrameWidth(a.getDimension(attr, 0));
break;
case R.styleable.UserAvatarView_framePadding:
setFramePadding(a.getDimension(attr, 0));
break;
- case R.styleable.UserAvatarView_activeFrameColor:
- setActiveFrameColor(a.getColor(attr, 0));
- break;
case R.styleable.UserAvatarView_frameColor:
- setFrameColor(a.getColor(attr, 0));
+ setFrameColor(a.getColorStateList(attr));
+ break;
+ case R.styleable.UserAvatarView_badgeDiameter:
+ setBadgeDiameter(a.getDimension(attr, 0));
+ break;
+ case R.styleable.UserAvatarView_badgeMargin:
+ setBadgeMargin(a.getDimension(attr, 0));
break;
}
}
a.recycle();
-
- mFramePaint.setAntiAlias(true);
- mFramePaint.setStyle(Paint.Style.STROKE);
- mBitmapPaint.setAntiAlias(true);
+ setBackground(mDrawable);
}
public UserAvatarView(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -94,180 +82,61 @@
this(context, null);
}
+ /**
+ * @deprecated use {@link #setAvatar(Bitmap)} instead.
+ */
+ @Deprecated
public void setBitmap(Bitmap bitmap) {
- setDrawable(null);
- mBitmap = bitmap;
- if (mBitmap != null) {
- mBitmapPaint.setShader(new BitmapShader(
- bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
- } else {
- mBitmapPaint.setShader(null);
- }
- configureBounds();
- invalidate();
+ setAvatar(bitmap);
}
- public void setFrameColor(int frameColor) {
- mFrameColor = frameColor;
- invalidate();
- }
-
- public void setActiveFrameColor(int activeFrameColor) {
- mActiveFrameColor = activeFrameColor;
- invalidate();
+ public void setFrameColor(ColorStateList color) {
+ mDrawable.setFrameColor(color);
}
public void setFrameWidth(float frameWidth) {
- mFrameWidth = frameWidth;
- invalidate();
+ mDrawable.setFrameWidth(frameWidth);
}
public void setFramePadding(float framePadding) {
- mFramePadding = framePadding;
- invalidate();
+ mDrawable.setFramePadding(framePadding);
}
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- configureBounds();
+ public void setAvatarPadding(float avatarPadding) {
+ mDrawable.setPadding(avatarPadding);
}
- public void configureBounds() {
- int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
- int vheight = getHeight() - mPaddingTop - mPaddingBottom;
-
- int dwidth;
- int dheight;
- if (mBitmap != null) {
- dwidth = mBitmap.getWidth();
- dheight = mBitmap.getHeight();
- } else if (mDrawable != null) {
- vwidth -= 2 * (mFrameWidth - 1);
- vheight -= 2 * (mFrameWidth - 1);
- dwidth = vwidth;
- dheight = vheight;
- mDrawable.setBounds(0, 0, dwidth, dheight);
- } else {
- return;
- }
-
- float scale;
- float dx;
- float dy;
-
- scale = Math.min((float) vwidth / (float) dwidth,
- (float) vheight / (float) dheight);
-
- dx = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);
- dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f);
-
- mDrawMatrix.setScale(scale, scale);
- mDrawMatrix.postTranslate(dx, dy);
- mScale = scale;
+ public void setBadgeDiameter(float diameter) {
+ mDrawable.setBadgeRadius(diameter * 0.5f);
}
- @Override
- protected void onDraw(Canvas canvas) {
- int frameColor = isActivated() ? mActiveFrameColor : mFrameColor;
- float halfW = getWidth() / 2f;
- float halfH = getHeight() / 2f;
- float halfSW = Math.min(halfH, halfW);
- updateDrawableIfDisabled();
- if (mBitmap != null && mScale > 0) {
- int saveCount = canvas.getSaveCount();
- canvas.save();
- canvas.translate(mPaddingLeft, mPaddingTop);
- canvas.concat(mDrawMatrix);
- float halfBW = mBitmap.getWidth() / 2f;
- float halfBH = mBitmap.getHeight() / 2f;
- float halfBSW = Math.min(halfBH, halfBW);
- canvas.drawCircle(halfBW, halfBH, halfBSW - mFrameWidth / mScale + 1, mBitmapPaint);
- canvas.restoreToCount(saveCount);
- } else if (mDrawable != null && mScale > 0) {
- int saveCount = canvas.getSaveCount();
- canvas.save();
- canvas.translate(mPaddingLeft, mPaddingTop);
- canvas.translate(mFrameWidth - 1, mFrameWidth - 1);
- canvas.concat(mDrawMatrix);
- mDrawable.draw(canvas);
- canvas.restoreToCount(saveCount);
- }
- if (frameColor != 0) {
- mFramePaint.setColor(frameColor);
- mFramePaint.setStrokeWidth(mFrameWidth);
- canvas.drawCircle(halfW, halfH, halfSW + (mFramePadding - mFrameWidth) / 2f,
- mFramePaint);
- }
+ public void setBadgeMargin(float margin) {
+ mDrawable.setBadgeMargin(margin);
+ }
+
+ public void setAvatar(Bitmap avatar) {
+ mDrawable.setIcon(avatar);
+ mDrawable.setBadge(null);
+ }
+
+ public void setAvatarWithBadge(Bitmap avatar, int userId) {
+ mDrawable.setIcon(avatar);
+ mDrawable.setBadgeIfManagedUser(getContext(), userId);
}
public void setDrawable(Drawable d) {
- if (mDrawable != null) {
- mDrawable.setCallback(null);
- unscheduleDrawable(mDrawable);
+ if (d instanceof UserIconDrawable) {
+ throw new RuntimeException("Recursively adding UserIconDrawable");
}
- mDrawable = d;
- if (d != null) {
- d.setCallback(this);
- if (d.isStateful()) {
- d.setState(getDrawableState());
- }
- d.setLayoutDirection(getLayoutDirection());
- configureBounds();
- }
- if (d != null) {
- mBitmap = null;
- }
- configureBounds();
- invalidate();
+ mDrawable.setIconDrawable(d);
+ mDrawable.setBadge(null);
}
- @Override
- public void invalidateDrawable(Drawable dr) {
- if (dr == mDrawable) {
- invalidate();
- } else {
- super.invalidateDrawable(dr);
+ public void setDrawableWithBadge(Drawable d, int userId) {
+ if (d instanceof UserIconDrawable) {
+ throw new RuntimeException("Recursively adding UserIconDrawable");
}
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return who == mDrawable || super.verifyDrawable(who);
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- if (mDrawable != null && mDrawable.isStateful()) {
- mDrawable.setState(getDrawableState());
- }
- }
-
- public void setDisabled(boolean disabled) {
- if (mIsDisabled == disabled) {
- return;
- }
- mIsDisabled = disabled;
- invalidate();
- }
-
- private void updateDrawableIfDisabled() {
- int disabledColor = getContext().getColor(R.color.qs_tile_disabled_color);
- PorterDuffColorFilter filter = new PorterDuffColorFilter(disabledColor,
- PorterDuff.Mode.SRC_ATOP);
- if (mBitmap != null) {
- if (mIsDisabled) {
- mBitmapPaint.setColorFilter(filter);
- } else {
- mBitmapPaint.setColorFilter(null);
- }
- } else if (mDrawable != null) {
- if (mIsDisabled) {
- mDrawable.setColorFilter(filter);
- } else {
- mDrawable.setColorFilter(null);
- }
- }
+ mDrawable.setIconDrawable(d);
+ mDrawable.setBadgeIfManagedUser(getContext(), userId);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index bb3e116..ea64fd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -16,158 +16,33 @@
package com.android.systemui.statusbar.policy;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.util.Log;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.ArrayList;
-public class BatteryController extends BroadcastReceiver {
- private static final String TAG = "BatteryController";
+public interface BatteryController {
+ /**
+ * Prints the current state of the {@link BatteryController} to the given {@link PrintWriter}.
+ */
+ void dump(FileDescriptor fd, PrintWriter pw, String[] args);
- public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+ /**
+ * Sets if the current device is in power save mode.
+ */
+ void setPowerSaveMode(boolean powerSave);
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ /**
+ * Returns {@code true} if the device is currently in power save mode.
+ */
+ boolean isPowerSave();
- private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
- private final PowerManager mPowerManager;
- private final Handler mHandler;
+ void addStateChangedCallback(BatteryStateChangeCallback cb);
+ void removeStateChangedCallback(BatteryStateChangeCallback cb);
- private int mLevel;
- private boolean mPluggedIn;
- private boolean mCharging;
- private boolean mCharged;
- private boolean mPowerSave;
- private boolean mTestmode = false;
-
- public BatteryController(Context context) {
- mHandler = new Handler();
- mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
- filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
- filter.addAction(ACTION_LEVEL_TEST);
- context.registerReceiver(this, filter);
-
- updatePowerSave();
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("BatteryController state:");
- pw.print(" mLevel="); pw.println(mLevel);
- pw.print(" mPluggedIn="); pw.println(mPluggedIn);
- pw.print(" mCharging="); pw.println(mCharging);
- pw.print(" mCharged="); pw.println(mCharged);
- pw.print(" mPowerSave="); pw.println(mPowerSave);
- }
-
- public void setPowerSaveMode(boolean powerSave) {
- mPowerManager.setPowerSaveMode(powerSave);
- }
-
- public void addStateChangedCallback(BatteryStateChangeCallback cb) {
- mChangeCallbacks.add(cb);
- cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
- cb.onPowerSaveChanged(mPowerSave);
- }
-
- public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
- mChangeCallbacks.remove(cb);
- }
-
- public void onReceive(final Context context, Intent intent) {
- final String action = intent.getAction();
- if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (mTestmode && !intent.getBooleanExtra("testmode", false)) return;
- mLevel = (int)(100f
- * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
- / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
- mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
-
- final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
- mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
- mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
-
- fireBatteryLevelChanged();
- } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
- updatePowerSave();
- } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
- setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
- } else if (action.equals(ACTION_LEVEL_TEST)) {
- mTestmode = true;
- mHandler.post(new Runnable() {
- int curLevel = 0;
- int incr = 1;
- int saveLevel = mLevel;
- boolean savePlugged = mPluggedIn;
- Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
- @Override
- public void run() {
- if (curLevel < 0) {
- mTestmode = false;
- dummy.putExtra("level", saveLevel);
- dummy.putExtra("plugged", savePlugged);
- dummy.putExtra("testmode", false);
- } else {
- dummy.putExtra("level", curLevel);
- dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
- : 0);
- dummy.putExtra("testmode", true);
- }
- context.sendBroadcast(dummy);
-
- if (!mTestmode) return;
-
- curLevel += incr;
- if (curLevel == 100) {
- incr *= -1;
- }
- mHandler.postDelayed(this, 200);
- }
- });
- }
- }
-
- public boolean isPowerSave() {
- return mPowerSave;
- }
-
- private void updatePowerSave() {
- setPowerSave(mPowerManager.isPowerSaveMode());
- }
-
- private void setPowerSave(boolean powerSave) {
- if (powerSave == mPowerSave) return;
- mPowerSave = powerSave;
- if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
- firePowerSaveChanged();
- }
-
- private void fireBatteryLevelChanged() {
- final int N = mChangeCallbacks.size();
- for (int i = 0; i < N; i++) {
- mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
- }
- }
-
- private void firePowerSaveChanged() {
- final int N = mChangeCallbacks.size();
- for (int i = 0; i < N; i++) {
- mChangeCallbacks.get(i).onPowerSaveChanged(mPowerSave);
- }
- }
-
- public interface BatteryStateChangeCallback {
+ /**
+ * A listener that will be notified whenever a change in battery level or power save mode
+ * has occurred.
+ */
+ interface BatteryStateChangeCallback {
void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
void onPowerSaveChanged(boolean isPowerSave);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
new file mode 100644
index 0000000..24207f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -0,0 +1,179 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Default implementation of a {@link BatteryController}. This controller monitors for battery
+ * level change events that are broadcasted by the system.
+ */
+public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController {
+ private static final String TAG = "BatteryController";
+
+ public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+ private final PowerManager mPowerManager;
+ private final Handler mHandler;
+
+ protected int mLevel;
+ protected boolean mPluggedIn;
+ protected boolean mCharging;
+ protected boolean mCharged;
+ protected boolean mPowerSave;
+ private boolean mTestmode = false;
+
+ public BatteryControllerImpl(Context context) {
+ mHandler = new Handler();
+ mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+ filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
+ filter.addAction(ACTION_LEVEL_TEST);
+ context.registerReceiver(this, filter);
+
+ updatePowerSave();
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("BatteryController state:");
+ pw.print(" mLevel="); pw.println(mLevel);
+ pw.print(" mPluggedIn="); pw.println(mPluggedIn);
+ pw.print(" mCharging="); pw.println(mCharging);
+ pw.print(" mCharged="); pw.println(mCharged);
+ pw.print(" mPowerSave="); pw.println(mPowerSave);
+ }
+
+ @Override
+ public void setPowerSaveMode(boolean powerSave) {
+ mPowerManager.setPowerSaveMode(powerSave);
+ }
+
+ @Override
+ public void addStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
+ mChangeCallbacks.add(cb);
+ cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ cb.onPowerSaveChanged(mPowerSave);
+ }
+
+ @Override
+ public void removeStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
+ mChangeCallbacks.remove(cb);
+ }
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ if (mTestmode && !intent.getBooleanExtra("testmode", false)) return;
+ mLevel = (int)(100f
+ * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
+ / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+ mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+
+ final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
+ mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
+
+ fireBatteryLevelChanged();
+ } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
+ updatePowerSave();
+ } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
+ setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
+ } else if (action.equals(ACTION_LEVEL_TEST)) {
+ mTestmode = true;
+ mHandler.post(new Runnable() {
+ int curLevel = 0;
+ int incr = 1;
+ int saveLevel = mLevel;
+ boolean savePlugged = mPluggedIn;
+ Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ @Override
+ public void run() {
+ if (curLevel < 0) {
+ mTestmode = false;
+ dummy.putExtra("level", saveLevel);
+ dummy.putExtra("plugged", savePlugged);
+ dummy.putExtra("testmode", false);
+ } else {
+ dummy.putExtra("level", curLevel);
+ dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
+ : 0);
+ dummy.putExtra("testmode", true);
+ }
+ context.sendBroadcast(dummy);
+
+ if (!mTestmode) return;
+
+ curLevel += incr;
+ if (curLevel == 100) {
+ incr *= -1;
+ }
+ mHandler.postDelayed(this, 200);
+ }
+ });
+ }
+ }
+
+ @Override
+ public boolean isPowerSave() {
+ return mPowerSave;
+ }
+
+ private void updatePowerSave() {
+ setPowerSave(mPowerManager.isPowerSaveMode());
+ }
+
+ private void setPowerSave(boolean powerSave) {
+ if (powerSave == mPowerSave) return;
+ mPowerSave = powerSave;
+ if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
+ firePowerSaveChanged();
+ }
+
+ protected void fireBatteryLevelChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ }
+ }
+
+ private void firePowerSaveChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onPowerSaveChanged(mPowerSave);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index ab81712..ebefdde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -185,6 +185,11 @@
if (alert) {
HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
+ if (headsUpEntry == null) {
+ // the entry was released before this update (i.e by a listener) This can happen
+ // with the groupmanager
+ return;
+ }
headsUpEntry.updateEntry();
setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUp));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index fb310a6..c39d718 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -253,17 +253,13 @@
UserDetailItemView v = (UserDetailItemView) convertView;
String name = getName(mContext, item);
- Drawable drawable;
if (item.picture == null) {
- drawable = getDrawable(mContext, item).mutate();
+ v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
} else {
- drawable = new BitmapDrawable(mContext.getResources(), item.picture);
+ v.bind(name, item.picture, item.info.id);
}
// Disable the icon if switching is disabled
- if (!item.isSwitchToEnabled) {
- drawable.setTint(mContext.getColor(R.color.qs_tile_disabled_color));
- }
- v.bind(name, drawable);
+ v.setAvatarEnabled(item.isSwitchToEnabled);
convertView.setActivated(item.isCurrent);
convertView.setTag(item);
return convertView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
index 85ac755..bae5bda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
@@ -26,7 +26,6 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.RemoteException;
@@ -37,7 +36,7 @@
import android.util.Pair;
import com.android.internal.util.UserIcons;
-import com.android.systemui.BitmapHelper;
+import com.android.settingslib.drawable.UserIconDrawable;
import com.android.systemui.R;
import java.util.ArrayList;
@@ -155,8 +154,8 @@
Drawable avatar = null;
Bitmap rawAvatar = um.getUserIcon(userId);
if (rawAvatar != null) {
- avatar = new BitmapDrawable(mContext.getResources(),
- BitmapHelper.createCircularClip(rawAvatar, avatarSize, avatarSize));
+ avatar = new UserIconDrawable(avatarSize)
+ .setIcon(rawAvatar).setBadgeIfManagedUser(mContext, userId).bake();
} else {
avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId,
/* light= */ true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index ea0bdf2..c82ba3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -50,7 +50,6 @@
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.util.UserIcons;
import com.android.settingslib.RestrictedLockUtils;
-import com.android.systemui.BitmapHelper;
import com.android.systemui.GuestResumeSessionReceiver;
import com.android.systemui.R;
import com.android.systemui.SystemUISecondaryUserService;
@@ -197,8 +196,6 @@
boolean canSwitchUsers = mUserManager.canSwitchUsers();
UserInfo currentUserInfo = null;
UserRecord guestRecord = null;
- int avatarSize = mContext.getResources()
- .getDimensionPixelSize(R.dimen.max_avatar_size);
for (UserInfo info : infos) {
boolean isCurrent = currentId == info.id;
@@ -219,8 +216,10 @@
picture = mUserManager.getUserIcon(info.id);
if (picture != null) {
- picture = BitmapHelper.createCircularClip(
- picture, avatarSize, avatarSize);
+ int avatarSize = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.max_avatar_size);
+ picture = Bitmap.createScaledBitmap(
+ picture, avatarSize, avatarSize, true);
}
}
int index = isCurrent ? 0 : records.size();
@@ -664,8 +663,7 @@
if (item.isAddUser) {
return context.getDrawable(R.drawable.ic_add_circle_qs);
}
- return UserIcons.getDefaultUserIcon(item.isGuest ? UserHandle.USER_NULL : item.info.id,
- /* light= */ true);
+ return UserIcons.getDefaultUserIcon(item.resolveId(), /* light= */ true);
}
public void refresh() {
@@ -718,6 +716,13 @@
isSwitchToEnabled);
}
+ public int resolveId() {
+ if (isGuest || info == null) {
+ return UserHandle.USER_NULL;
+ }
+ return info.id;
+ }
+
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("UserRecord(");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index fa37e22..7c5cdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -299,7 +299,7 @@
setDimAmount((Float) animation.getAnimatedValue());
}
};
- private ViewGroup mQsContainer;
+ protected ViewGroup mQsContainer;
private boolean mContinuousShadowUpdate;
private ViewTreeObserver.OnPreDrawListener mShadowUpdater
= new ViewTreeObserver.OnPreDrawListener() {
@@ -3639,16 +3639,18 @@
if (mTranslatingParentView == null) {
return false;
}
- final float snapBackThreshold = getSpaceForGear(animView);
+ // If the notification can't be dismissed then how far it can move is
+ // restricted -- reduce the distance it needs to move in this case.
+ final float multiplier = canChildBeDismissed(animView) ? 0.4f : 0.2f;
+ final float snapBackThreshold = getSpaceForGear(animView) * multiplier;
final float translation = getTranslation(animView);
final boolean fromLeft = translation > 0;
final float absTrans = Math.abs(translation);
final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
- // If the notification can't be dismissed then how far it can move is
- // restricted -- reduce the distance it needs to move in this case.
- final float multiplier = canChildBeDismissed(animView) ? 0.4f : 0.2f;
- return absTrans >= snapBackThreshold * 0.4f && absTrans <= notiThreshold;
+ return mCurrIconRow.isVisible() && (mCurrIconRow.isIconOnLeft()
+ ? (translation > snapBackThreshold && translation <= notiThreshold)
+ : (translation < -snapBackThreshold && translation >= -notiThreshold));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index f9bb5e3..450001f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.RemoteException;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.view.View;
@@ -29,12 +30,22 @@
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.tv.pip.PipManager;
-/*
+/**
* Status bar implementation for "large screen" products that mostly present no on-screen nav
*/
public class TvStatusBar extends BaseStatusBar {
+ /**
+ * Tracking calls to View.setSystemUiVisibility().
+ */
+ int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+
+ /**
+ * Last value sent to window manager.
+ */
+ private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
+
@Override
public void setIcon(String slot, StatusBarIcon icon) {
}
@@ -207,4 +218,30 @@
@Override
public void clickTile(ComponentName tile) {
}
+
+ @Override
+ public void start() {
+ super.start();
+ putComponent(TvStatusBar.class, this);
+ }
+
+ public void updateRecentsVisibility(boolean visible) {
+ // Update the recents visibility flag
+ if (visible) {
+ mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
+ } else {
+ mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
+ }
+ notifyUiVisibilityChanged(mSystemUiVisibility);
+ }
+
+ private void notifyUiVisibilityChanged(int vis) {
+ try {
+ if (mLastDispatchedSystemUiVisibility != vis) {
+ mWindowManagerService.statusBarVisibilityChanged(vis);
+ mLastDispatchedSystemUiVisibility = vis;
+ }
+ } catch (RemoteException ex) {
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index fe54090..a445e77 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -36,6 +36,7 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;
+import android.util.Pair;
import com.android.systemui.Prefs;
import com.android.systemui.R;
@@ -63,6 +64,20 @@
private static final int MAX_RUNNING_TASKS_COUNT = 10;
/**
+ * List of package and class name which are considered as Settings,
+ * so PIP location should be adjusted to the left of the side panel.
+ */
+ private static final List<Pair<String, String>> sSettingsPackageAndClassNamePairList;
+ static {
+ sSettingsPackageAndClassNamePairList = new ArrayList<>();
+ sSettingsPackageAndClassNamePairList.add(new Pair<String, String>(
+ "com.android.tv.settings", null));
+ sSettingsPackageAndClassNamePairList.add(new Pair<String, String>(
+ "com.google.android.leanbacklauncher",
+ "com.google.android.leanbacklauncher.settings.HomeScreenSettingsActivity"));
+ }
+
+ /**
* State when there's no PIP.
*/
public static final int STATE_NO_PIP = 0;
@@ -108,6 +123,7 @@
private int mSuspendPipResizingReason;
private Context mContext;
+ private SystemServicesProxy mSystemServiceProxy;
private PipRecentsOverlayManager mPipRecentsOverlayManager;
private IActivityManager mActivityManager;
private MediaSessionManager mMediaSessionManager;
@@ -117,6 +133,8 @@
private List<MediaListener> mMediaListeners = new ArrayList<>();
private Rect mCurrentPipBounds;
private Rect mPipBounds;
+ private Rect mDefaultPipBounds;
+ private Rect mSettingsPipBounds;
private Rect mMenuModePipBounds;
private Rect mRecentsPipBounds;
private Rect mRecentsFocusedPipBounds;
@@ -176,8 +194,10 @@
mInitialized = true;
mContext = context;
Resources res = context.getResources();
- mPipBounds = Rect.unflattenFromString(res.getString(
+ mDefaultPipBounds = Rect.unflattenFromString(res.getString(
com.android.internal.R.string.config_defaultPictureInPictureBounds));
+ mSettingsPipBounds = Rect.unflattenFromString(res.getString(
+ R.string.pip_settings_bounds));
mMenuModePipBounds = Rect.unflattenFromString(res.getString(
R.string.pip_menu_bounds));
mRecentsPipBounds = Rect.unflattenFromString(res.getString(
@@ -186,9 +206,11 @@
R.string.pip_recents_focused_bounds));
mRecentsFocusChangedAnimationDurationMs = res.getInteger(
R.integer.recents_tv_pip_focus_anim_duration);
+ mPipBounds = mDefaultPipBounds;
mActivityManager = ActivityManagerNative.getDefault();
- SystemServicesProxy.getInstance(context).registerTaskStackListener(mTaskStackListener);
+ mSystemServiceProxy = SystemServicesProxy.getInstance(context);
+ mSystemServiceProxy.registerTaskStackListener(mTaskStackListener);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter);
@@ -522,10 +544,25 @@
return PLAYBACK_STATE_UNAVAILABLE;
}
+ private static boolean isSettingsShown(ComponentName topActivity) {
+ for (Pair<String, String> componentName : sSettingsPackageAndClassNamePairList) {
+ String packageName = componentName.first;
+ if (topActivity.getPackageName().equals(componentName.first)) {
+ String className = componentName.second;
+ if (className == null || topActivity.getClassName().equals(className)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private TaskStackListener mTaskStackListener = new TaskStackListener() {
@Override
public void onTaskStackChanged() {
if (mState != STATE_NO_PIP) {
+ boolean hasPip = false;
+
StackInfo stackInfo = null;
try {
stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -541,11 +578,32 @@
for (int i = stackInfo.taskIds.length - 1; i >= 0; --i) {
if (stackInfo.taskIds[i] == mPipTaskId) {
// PIP task is still alive.
- return;
+ hasPip = true;
+ break;
}
}
- // PIP task doesn't exist anymore in PINNED_STACK.
- closePipInternal(true);
+ if (!hasPip) {
+ // PIP task doesn't exist anymore in PINNED_STACK.
+ closePipInternal(true);
+ return;
+ }
+ }
+ if (mState == STATE_PIP_OVERLAY) {
+ try {
+ List<RunningTaskInfo> runningTasks = mActivityManager.getTasks(1, 0);
+ if (runningTasks == null || runningTasks.size() == 0) {
+ return;
+ }
+ RunningTaskInfo topTask = runningTasks.get(0);
+ Rect bounds = isSettingsShown(topTask.topActivity)
+ ? mSettingsPipBounds : mDefaultPipBounds;
+ if (mPipBounds != bounds) {
+ mPipBounds = bounds;
+ resizePinnedStack(STATE_PIP_OVERLAY);
+ }
+ } catch (RemoteException e) {
+ Log.d(TAG, "Failed to detect top activity", e);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 1d5ca04..91a8493 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -761,7 +761,37 @@
: (iconRes == R.drawable.ic_volume_media_bt || iconRes == row.iconRes)
? Events.ICON_STATE_UNMUTE
: Events.ICON_STATE_UNKNOWN;
- row.icon.setContentDescription(ss.name);
+ if (iconEnabled) {
+ if (isRingStream) {
+ if (isRingVibrate) {
+ row.icon.setContentDescription(mContext.getString(
+ R.string.volume_stream_content_description_unmute,
+ ss.name));
+ } else {
+ if (mController.hasVibrator()) {
+ row.icon.setContentDescription(mContext.getString(
+ R.string.volume_stream_content_description_vibrate,
+ ss.name));
+ } else {
+ row.icon.setContentDescription(mContext.getString(
+ R.string.volume_stream_content_description_mute,
+ ss.name));
+ }
+ }
+ } else {
+ if (ss.muted || mAutomute && ss.level == 0) {
+ row.icon.setContentDescription(mContext.getString(
+ R.string.volume_stream_content_description_unmute,
+ ss.name));
+ } else {
+ row.icon.setContentDescription(mContext.getString(
+ R.string.volume_stream_content_description_mute,
+ ss.name));
+ }
+ }
+ } else {
+ row.icon.setContentDescription(ss.name);
+ }
// update slider
final boolean enableSlider = !zenMuted;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
index f24b541..1e27603 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.os.Handler;
import android.os.HandlerThread;
-import android.service.quicksettings.TileService;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.systemui.SysuiTestCase;
import org.mockito.ArgumentCaptor;
@@ -42,11 +41,10 @@
mTileServices = Mockito.mock(TileServices.class);
Mockito.when(mTileServices.getContext()).thenReturn(mContext);
mTileLifecycle = Mockito.mock(TileLifecycleManager.class);
+ Mockito.when(mTileLifecycle.isActiveTile()).thenReturn(false);
ComponentName componentName = new ComponentName(mContext,
TileServiceManagerTests.class);
Mockito.when(mTileLifecycle.getComponent()).thenReturn(componentName);
- mContext.getSharedPreferences(TileServiceManager.PREFS_FILE, 0).edit()
- .putInt(componentName.flattenToString(), TileService.TILE_MODE_PASSIVE).commit();
mTileServiceManager = new TileServiceManager(mTileServices, mHandler, mTileLifecycle);
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index b3613df..ea3cffe 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2135,6 +2135,9 @@
// Suggestion -> Overflow -> Remove.
ACTION_SETTINGS_DISMISS_SUGGESTION = 387;
+ // Settings > Apps > Gear > Special Access > Premium SMS access
+ PREMIUM_SMS_ACCESS = 388;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 3e7466f..613f890 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -363,12 +363,6 @@
private void enableFeatures() {
resetStreamState();
- if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
- mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
- addFirstEventHandler(mMotionEventInjector);
- mAms.setMotionEventInjector(mMotionEventInjector);
- }
-
if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) {
mAutoclickController = new AutoclickController(mContext, mUserId);
addFirstEventHandler(mAutoclickController);
@@ -384,6 +378,12 @@
addFirstEventHandler(mMagnificationGestureHandler);
}
+ if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
+ mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
+ addFirstEventHandler(mMotionEventInjector);
+ mAms.setMotionEventInjector(mMotionEventInjector);
+ }
+
if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
mKeyboardInterceptor = new KeyboardInterceptor(mAms);
addFirstEventHandler(mKeyboardInterceptor);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 2741733..ca17c43 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -439,7 +439,7 @@
}
if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
mSecurityPolicy.updateActiveAndAccessibilityFocusedWindowLocked(event.getWindowId(),
- event.getSourceNodeId(), event.getEventType());
+ event.getSourceNodeId(), event.getEventType(), event.getAction());
mSecurityPolicy.updateEventSourceLocked(event);
notifyAccessibilityServicesDelayedLocked(event, false);
notifyAccessibilityServicesDelayedLocked(event, true);
@@ -1795,9 +1795,8 @@
}
userState.mSoftKeyboardShowMode = 0;
userState.mServiceChangingSoftKeyboardMode = null;
+ notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
}
-
- notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
}
}
@@ -3829,7 +3828,7 @@
}
public void updateActiveAndAccessibilityFocusedWindowLocked(int windowId, long nodeId,
- int eventType) {
+ int eventType, int eventAction) {
// The active window is either the window that has input focus or
// the window that the user is currently touching. If the user is
// touching a window that does not have input focus as soon as the
@@ -3882,8 +3881,12 @@
if (mAccessibilityFocusNodeId == nodeId) {
mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
}
- if (mAccessibilityFocusNodeId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID
- && mAccessibilityFocusedWindowId == windowId) {
+ // Clear the window with focus if it no longer has focus and we aren't
+ // just moving focus from one view to the other in the same window
+ if ((mAccessibilityFocusNodeId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
+ && (mAccessibilityFocusedWindowId == windowId)
+ && (eventAction != AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS)
+ ) {
mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
}
}
@@ -4355,6 +4358,7 @@
}
} else if (mAccessibilitySoftKeyboardModeUri.equals(uri)) {
if (readSoftKeyboardShowModeChangedLocked(userState)) {
+ notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
onUserStateChangedLocked(userState);
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b2196bf..fb1ef37 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -156,10 +156,10 @@
final float offsetY = sentSpec.offsetY;
// Compute the new center and update spec as needed.
- final float centerX = (mMagnifiedBounds.width() / 2.0f
- + mMagnifiedBounds.left - offsetX) / scale;
- final float centerY = (mMagnifiedBounds.height() / 2.0f
- + mMagnifiedBounds.top - offsetY) / scale;
+ final float centerX = (mMagnifiedBounds.width() / 2.0f - offsetX) / scale
+ + mMagnifiedBounds.left;
+ final float centerY = (mMagnifiedBounds.height() / 2.0f - offsetY) / scale
+ + mMagnifiedBounds.top;
if (updateSpec) {
setScaleAndCenter(scale, centerX, centerY, false);
} else {
@@ -256,7 +256,7 @@
public float getCenterX() {
synchronized (mLock) {
return (mMagnifiedBounds.width() / 2.0f
- + mMagnifiedBounds.left - getOffsetX()) / getScale();
+ - getOffsetX()) / getScale() + mMagnifiedBounds.left;
}
}
@@ -279,7 +279,7 @@
public float getCenterY() {
synchronized (mLock) {
return (mMagnifiedBounds.height() / 2.0f
- + mMagnifiedBounds.top - getOffsetY()) / getScale();
+ - getOffsetY()) / getScale() + mMagnifiedBounds.top;
}
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 48e96aa..8753992 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -124,6 +124,7 @@
private boolean mLastBatteryLevelCritical;
private int mLastMaxChargingCurrent;
private int mLastMaxChargingVoltage;
+ private int mLastChargeCounter;
private int mInvalidCharger;
private int mLastInvalidCharger;
@@ -341,6 +342,7 @@
+ ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
+ ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
+ ", maxChargingVoltage" + mBatteryProps.maxChargingVoltage
+ + ", chargeCounter" + mBatteryProps.batteryChargeCounter
+ ", batteryStatus=" + mBatteryProps.batteryStatus
+ ", batteryHealth=" + mBatteryProps.batteryHealth
+ ", batteryPresent=" + mBatteryProps.batteryPresent
@@ -373,6 +375,7 @@
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage ||
+ mBatteryProps.batteryChargeCounter != mLastChargeCounter ||
mInvalidCharger != mLastInvalidCharger)) {
if (mPlugType != mLastPlugType) {
@@ -501,6 +504,7 @@
mLastBatteryTemperature = mBatteryProps.batteryTemperature;
mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage;
+ mLastChargeCounter = mBatteryProps.batteryChargeCounter;
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
}
@@ -527,6 +531,7 @@
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
+ intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
if (DEBUG) {
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel +
", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
@@ -540,7 +545,8 @@
", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
", icon:" + icon + ", invalid charger:" + mInvalidCharger +
", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent +
- ", maxChargingVoltage:" + mBatteryProps.maxChargingVoltage);
+ ", maxChargingVoltage:" + mBatteryProps.maxChargingVoltage +
+ ", chargeCounter:" + mBatteryProps.batteryChargeCounter);
}
mHandler.post(new Runnable() {
@@ -772,6 +778,7 @@
pw.println(" Wireless powered: " + mBatteryProps.chargerWirelessOnline);
pw.println(" Max charging current: " + mBatteryProps.maxChargingCurrent);
pw.println(" Max charging voltage: " + mBatteryProps.maxChargingVoltage);
+ pw.println(" Charge counter: " + mBatteryProps.batteryChargeCounter);
pw.println(" status: " + mBatteryProps.batteryStatus);
pw.println(" health: " + mBatteryProps.batteryHealth);
pw.println(" present: " + mBatteryProps.batteryPresent);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 82a36b4..966deb6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -991,7 +991,16 @@
@Override
public Network getActiveNetwork() {
enforceAccessPermission();
- final int uid = Binder.getCallingUid();
+ return getActiveNetworkForUidInternal(Binder.getCallingUid());
+ }
+
+ @Override
+ public Network getActiveNetworkForUid(int uid) {
+ enforceConnectivityInternalPermission();
+ return getActiveNetworkForUidInternal(uid);
+ }
+
+ private Network getActiveNetworkForUidInternal(final int uid) {
final int user = UserHandle.getUserId(uid);
int vpnNetId = NETID_UNSET;
synchronized (mVpns) {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index ccb4647..6a08191 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -39,7 +39,9 @@
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
+import android.net.ConnectivityManager;
import android.net.INetworkPolicyManager;
+import android.net.NetworkInfo;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
@@ -114,6 +116,7 @@
private IBatteryStats mBatteryStats;
private PowerManagerInternal mLocalPowerManager;
private PowerManager mPowerManager;
+ private ConnectivityService mConnectivityService;
private AlarmManagerService.LocalService mLocalAlarmManager;
private INetworkPolicyManager mNetworkPolicyManager;
private DisplayManager mDisplayManager;
@@ -128,6 +131,7 @@
private boolean mLightEnabled;
private boolean mDeepEnabled;
private boolean mForceIdle;
+ private boolean mNetworkConnected;
private boolean mScreenOn;
private boolean mCharging;
private boolean mNotMoving;
@@ -173,16 +177,20 @@
private static final int LIGHT_STATE_PRE_IDLE = 3;
/** Device is in the light idle state, trying to stay asleep as much as possible. */
private static final int LIGHT_STATE_IDLE = 4;
+ /** Device is in the light idle state, we want to go in to idle maintenance but are
+ * waiting for network connectivity before doing so. */
+ private static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
/** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
- private static final int LIGHT_STATE_IDLE_MAINTENANCE = 5;
+ private static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
/** Device light idle state is overriden, now applying deep doze state. */
- private static final int LIGHT_STATE_OVERRIDE = 6;
+ private static final int LIGHT_STATE_OVERRIDE = 7;
private static String lightStateToString(int state) {
switch (state) {
case LIGHT_STATE_ACTIVE: return "ACTIVE";
case LIGHT_STATE_INACTIVE: return "INACTIVE";
case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
case LIGHT_STATE_IDLE: return "IDLE";
+ case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
default: return Integer.toString(state);
@@ -315,17 +323,27 @@
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
- int plugged = intent.getIntExtra("plugged", 0);
- updateChargingLocked(plugged != 0);
- } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
- if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
- Uri data = intent.getData();
- String ssp;
- if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
- removePowerSaveWhitelistAppInternal(ssp);
+ switch (intent.getAction()) {
+ case ConnectivityManager.CONNECTIVITY_ACTION: {
+ synchronized (DeviceIdleController.this) {
+ updateConnectivityStateLocked(intent);
}
- }
+ } break;
+ case Intent.ACTION_BATTERY_CHANGED: {
+ synchronized (DeviceIdleController.this) {
+ int plugged = intent.getIntExtra("plugged", 0);
+ updateChargingLocked(plugged != 0);
+ }
+ } break;
+ case Intent.ACTION_PACKAGE_REMOVED: {
+ if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ Uri data = intent.getData();
+ String ssp;
+ if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
+ removePowerSaveWhitelistAppInternal(ssp);
+ }
+ }
+ } break;
}
}
};
@@ -1318,6 +1336,7 @@
readConfigFileLocked();
updateWhitelistAppIdsLocked();
+ mNetworkConnected = true;
mScreenOn = true;
// Start out assuming we are charging. If we aren't, we will at least get
// a battery update the next time the level drops.
@@ -1343,6 +1362,8 @@
mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"deviceidle_maint");
mActiveIdleWakeLock.setReferenceCounted(false);
+ mConnectivityService = (ConnectivityService)ServiceManager.getService(
+ Context.CONNECTIVITY_SERVICE);
mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class);
mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
@@ -1395,11 +1416,14 @@
filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
+ filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getContext().registerReceiver(mReceiver, filter);
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
mDisplayManager.registerDisplayListener(mDisplayListener, null);
+ updateConnectivityStateLocked(null);
updateDisplayLocked();
}
}
@@ -1680,6 +1704,35 @@
}
}
+ void updateConnectivityStateLocked(Intent connIntent) {
+ if (mConnectivityService != null) {
+ NetworkInfo ni = mConnectivityService.getActiveNetworkInfo();
+ boolean conn;
+ if (ni == null) {
+ conn = false;
+ } else {
+ if (connIntent == null) {
+ conn = ni.isConnected();
+ } else {
+ final int networkType =
+ connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
+ ConnectivityManager.TYPE_NONE);
+ if (ni.getType() != networkType) {
+ return;
+ }
+ conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
+ false);
+ }
+ }
+ if (conn != mNetworkConnected) {
+ mNetworkConnected = conn;
+ if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
+ stepLightIdleStateLocked("network");
+ }
+ }
+ }
+ }
+
void updateDisplayLocked() {
mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
// We consider any situation where the display is showing something to be it on,
@@ -1778,7 +1831,7 @@
if (mForceIdle) {
mForceIdle = false;
if (mScreenOn || mCharging) {
- becomeActiveLocked("exit-force-idle", Process.myUid());
+ becomeActiveLocked("exit-force", Process.myUid());
}
}
}
@@ -1834,22 +1887,33 @@
mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
break;
case LIGHT_STATE_IDLE:
- // We have been idling long enough, now it is time to do some work.
- mActiveIdleOpCount = 1;
- mActiveIdleWakeLock.acquire();
- mMaintenanceStartTime = SystemClock.elapsedRealtime();
- if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
- mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
- } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
- mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
+ case LIGHT_STATE_WAITING_FOR_NETWORK:
+ if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
+ // We have been idling long enough, now it is time to do some work.
+ mActiveIdleOpCount = 1;
+ mActiveIdleWakeLock.acquire();
+ mMaintenanceStartTime = SystemClock.elapsedRealtime();
+ if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
+ mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
+ } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
+ mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
+ }
+ scheduleLightAlarmLocked(mCurIdleBudget);
+ if (DEBUG) Slog.d(TAG,
+ "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
+ mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
+ EventLogTags.writeDeviceIdleLight(mLightState, reason);
+ addEvent(EVENT_LIGHT_MAINTENANCE);
+ mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
+ } else {
+ // We'd like to do maintenance, but currently don't have network
+ // connectivity... let's try to wait until the network comes back.
+ // We'll only wait for another full idle period, however, and then give up.
+ scheduleLightAlarmLocked(mNextLightIdleDelay);
+ if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
+ mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
+ EventLogTags.writeDeviceIdleLight(mLightState, reason);
}
- scheduleLightAlarmLocked(mCurIdleBudget);
- if (DEBUG) Slog.d(TAG,
- "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
- mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
- EventLogTags.writeDeviceIdleLight(mLightState, reason);
- addEvent(EVENT_LIGHT_MAINTENANCE);
- mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
break;
}
}
@@ -2209,13 +2273,6 @@
void scheduleLightAlarmLocked(long delay) {
if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
- if (mMotionSensor == null) {
- // If there is no motion sensor on this device, then we won't schedule
- // alarms, because we can't determine if the device is not moving. This effectively
- // turns off normal execution of device idling, although it is still possible to
- // manually poke it by pretending like the alarm is going off.
- return;
- }
mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
@@ -2430,9 +2487,14 @@
pw.println(" Print this help text.");
pw.println(" step [light|deep]");
pw.println(" Immediately step to next state, without waiting for alarm.");
- pw.println(" force-idle");
+ pw.println(" force-idle [light|deep]");
pw.println(" Force directly into idle mode, regardless of other device state.");
- pw.println(" Use \"step\" to get out.");
+ pw.println(" force-inactive");
+ pw.println(" Force to be inactive, ready to freely step idle states.");
+ pw.println(" unforce");
+ pw.println(" Resume normal functioning after force-idle or force-inactive.");
+ pw.println(" get [light|deep|force|screen|charging|network]");
+ pw.println(" Retrieve the current given state.");
pw.println(" disable [light|deep|all]");
pw.println(" Completely disable device idle mode.");
pw.println(" enable [light|deep|all]");
@@ -2472,12 +2534,10 @@
String arg = shell.getNextArg();
try {
if (arg == null || "deep".equals(arg)) {
- exitForceIdleLocked();
stepIdleStateLocked("s:shell");
pw.print("Stepped to deep: ");
pw.println(stateToString(mState));
} else if ("light".equals(arg)) {
- exitForceIdleLocked();
stepLightIdleStateLocked("s:shell");
pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
} else {
@@ -2492,29 +2552,104 @@
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
+ String arg = shell.getNextArg();
try {
- if (!mDeepEnabled) {
- pw.println("Unable to go idle; not enabled");
- return -1;
- }
- mForceIdle = true;
- becomeInactiveIfAppropriateLocked();
- int curState = mState;
- while (curState != STATE_IDLE) {
- stepIdleStateLocked("s:shell");
- if (curState == mState) {
- pw.print("Unable to go idle; stopped at ");
- pw.println(stateToString(mState));
- exitForceIdleLocked();
+ if (arg == null || "deep".equals(arg)) {
+ if (!mDeepEnabled) {
+ pw.println("Unable to go deep idle; not enabled");
return -1;
}
- curState = mState;
+ mForceIdle = true;
+ becomeInactiveIfAppropriateLocked();
+ int curState = mState;
+ while (curState != STATE_IDLE) {
+ stepIdleStateLocked("s:shell");
+ if (curState == mState) {
+ pw.print("Unable to go deep idle; stopped at ");
+ pw.println(stateToString(mState));
+ exitForceIdleLocked();
+ return -1;
+ }
+ curState = mState;
+ }
+ pw.println("Now forced in to deep idle mode");
+ } else if ("light".equals(arg)) {
+ mForceIdle = true;
+ becomeInactiveIfAppropriateLocked();
+ int curLightState = mLightState;
+ while (curLightState != LIGHT_STATE_IDLE) {
+ stepIdleStateLocked("s:shell");
+ if (curLightState == mLightState) {
+ pw.print("Unable to go light idle; stopped at ");
+ pw.println(lightStateToString(mLightState));
+ exitForceIdleLocked();
+ return -1;
+ }
+ curLightState = mLightState;
+ }
+ pw.println("Now forced in to light idle mode");
+ } else {
+ pw.println("Unknown idle mode: " + arg);
}
- pw.println("Now forced in to idle mode");
} finally {
Binder.restoreCallingIdentity(token);
}
}
+ } else if ("force-inactive".equals(cmd)) {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ synchronized (this) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mForceIdle = true;
+ becomeInactiveIfAppropriateLocked();
+ pw.print("Light state: ");
+ pw.print(lightStateToString(mLightState));
+ pw.print(", deep state: ");
+ pw.println(stateToString(mState));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } else if ("unforce".equals(cmd)) {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ synchronized (this) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ exitForceIdleLocked();
+ pw.print("Light state: ");
+ pw.print(lightStateToString(mLightState));
+ pw.print(", deep state: ");
+ pw.println(stateToString(mState));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } else if ("get".equals(cmd)) {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ synchronized (this) {
+ String arg = shell.getNextArg();
+ if (arg != null) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ switch (arg) {
+ case "light": pw.println(lightStateToString(mLightState)); break;
+ case "deep": pw.println(stateToString(mState)); break;
+ case "force": pw.println(mForceIdle); break;
+ case "screen": pw.println(mScreenOn); break;
+ case "charging": pw.println(mCharging); break;
+ case "network": pw.println(mNetworkConnected); break;
+ default: pw.println("Unknown get option: " + arg); break;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } else {
+ pw.println("Argument required");
+ }
+ }
} else if ("disable".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
@@ -2829,6 +2964,7 @@
pw.print(" mMotionSensor="); pw.println(mMotionSensor);
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
pw.print(" mScreenOn="); pw.println(mScreenOn);
+ pw.print(" mNetworkConnected="); pw.println(mNetworkConnected);
pw.print(" mCharging="); pw.println(mCharging);
pw.print(" mMotionActive="); pw.println(mMotionListener.active);
pw.print(" mNotMoving="); pw.println(mNotMoving);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index ac7872a..58e3674 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2546,7 +2546,8 @@
return false;
}
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
- onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype);
+ onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype,
+ true /* forward */);
if (nextSubtype == null) {
return false;
}
@@ -2569,7 +2570,8 @@
return false;
}
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
- false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
+ false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype,
+ true /* forward */);
if (nextSubtype == null) {
return false;
}
@@ -2963,9 +2965,8 @@
private void handleSwitchInputMethod(final boolean forwardDirection) {
synchronized (mMethodMap) {
- // TODO: Support forwardDirection.
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
- false, mMethodMap.get(mCurMethodId), mCurrentSubtype);
+ false, mMethodMap.get(mCurMethodId), mCurrentSubtype, forwardDirection);
if (nextSubtype == null) {
return;
}
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ab0f55e..4ac75ca 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -56,6 +56,9 @@
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
import android.security.KeyStore;
+import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
import android.text.TextUtils;
@@ -68,15 +71,33 @@
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.LockSettingsStorage.CredentialHash;
+import libcore.util.HexEncoding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
/**
* Keeps the lock pattern/password data and related settings for each user.
* Used by LockPatternUtils. Needs to be a service because Settings app also needs
@@ -90,6 +111,12 @@
private static final int FBE_ENCRYPTED_NOTIFICATION = 0;
private static final boolean DEBUG = false;
+ private static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_";
+ private static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_";
+ private static final int PROFILE_KEY_IV_SIZE = 12;
+ private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+ private final Object mSeparateChallengeLock = new Object();
+
private final Context mContext;
private final LockSettingsStorage mStorage;
private final LockSettingsStrongAuth mStrongAuth;
@@ -125,6 +152,7 @@
@Override
public void onStart() {
+ AndroidKeyStoreProvider.install();
mLockSettingsService = new LockSettingsService(getContext());
publishBinderService("lock_settings", mLockSettingsService);
}
@@ -149,6 +177,46 @@
}
}
+ /**
+ * Tie managed profile to primary profile if it is in unified mode and not tied before.
+ *
+ * @param managedUserId Managed profile user Id
+ * @param managedUserPassword Managed profile original password (when it has separated lock).
+ * NULL when it does not have a separated lock before.
+ */
+ public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
+ if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
+ // Only for managed profile
+ if (!UserManager.get(mContext).getUserInfo(managedUserId).isManagedProfile()) {
+ return;
+ }
+ // Do not tie managed profile when work challenge is enabled
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+ return;
+ }
+ // Do not tie managed profile to parent when it's done already
+ if (mStorage.hasChildProfileLock(managedUserId)) {
+ return;
+ }
+ // Do not tie it to parent when parent does not have a screen lock
+ final int parentId = mUserManager.getProfileParent(managedUserId).id;
+ if (!mStorage.hasPassword(parentId) && !mStorage.hasPattern(parentId)) {
+ if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
+ return;
+ }
+ if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
+ byte[] randomLockSeed = new byte[] {};
+ try {
+ randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
+ String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
+ setLockPasswordInternal(newPassword, managedUserPassword, managedUserId);
+ tieProfileLockToParent(managedUserId, newPassword);
+ } catch (NoSuchAlgorithmException | RemoteException e) {
+ Slog.e(TAG, "Fail to tie managed profile", e);
+ // Nothing client can do to fix this issue, so we do not throw exception out
+ }
+ }
+
public LockSettingsService(Context context) {
mContext = context;
mStrongAuth = new LockSettingsStrongAuth(context);
@@ -271,6 +339,7 @@
}
public void onUnlockUser(int userId) {
+ tieManagedProfileLockIfNecessary(userId, null);
hideEncryptionNotification(new UserHandle(userId));
// Now we have unlocked the parent user we should show notifications
@@ -294,8 +363,7 @@
// Notify keystore that a new user was added.
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
final KeyStore ks = KeyStore.getInstance();
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- final UserInfo parentInfo = um.getProfileParent(userHandle);
+ final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
final int parentHandle = parentInfo != null ? parentInfo.id : -1;
ks.onUserAdded(userHandle, parentHandle);
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
@@ -343,9 +411,8 @@
// These Settings changed after multi-user was enabled, hence need to be moved per user.
if (getString("migrated_user_specific", null, 0) == null) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final ContentResolver cr = mContext.getContentResolver();
- List<UserInfo> users = um.getUsers();
+ List<UserInfo> users = mUserManager.getUsers();
for (int user = 0; user < users.size(); user++) {
// Migrate owner info
final int userId = users.get(user).id;
@@ -380,8 +447,7 @@
// Migrates biometric weak such that the fallback mechanism becomes the primary.
if (getString("migrated_biometric_weak", null, 0) == null) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- List<UserInfo> users = um.getUsers();
+ List<UserInfo> users = mUserManager.getUsers();
for (int i = 0; i < users.size(); i++) {
int userId = users.get(i).id;
long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
@@ -407,9 +473,7 @@
// user was present on the system, so if we're upgrading to M and there is more than one
// user we disable the flag to remain consistent.
if (getString("migrated_lockscreen_disabled", null, 0) == null) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-
- final List<UserInfo> users = um.getUsers();
+ final List<UserInfo> users = mUserManager.getUsers();
final int userCount = users.size();
int switchableUsers = 0;
for (int i = 0; i < userCount; i++) {
@@ -469,6 +533,27 @@
}
@Override
+ public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
+ synchronized (mSeparateChallengeLock) {
+ return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
+ }
+ }
+
+ @Override
+ public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
+ String managedUserPassword) throws RemoteException {
+ synchronized (mSeparateChallengeLock) {
+ setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
+ if (enabled) {
+ mStorage.removeChildProfileLock(userId);
+ removeKeystoreProfileKey(userId);
+ } else {
+ tieManagedProfileLockIfNecessary(userId, managedUserPassword);
+ }
+ }
+ }
+
+ @Override
public void setBoolean(String key, boolean value, int userId) throws RemoteException {
checkWritePermission(userId);
setStringUnchecked(key, userId, value ? "1" : "0");
@@ -536,61 +621,65 @@
@Override
public boolean havePassword(int userId) throws RemoteException {
// Do we need a permissions check here?
-
return mStorage.hasPassword(userId);
}
@Override
public boolean havePattern(int userId) throws RemoteException {
// Do we need a permissions check here?
-
return mStorage.hasPattern(userId);
}
private void setKeystorePassword(String password, int userHandle) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final KeyStore ks = KeyStore.getInstance();
-
- if (um.getUserInfo(userHandle).isManagedProfile()) {
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
- ks.onUserPasswordChanged(userHandle, password);
- } else {
- throw new RuntimeException("Can't set keystore password on a profile that "
- + "doesn't have a profile challenge.");
- }
- } else {
- final List<UserInfo> profiles = um.getProfiles(userHandle);
- for (UserInfo pi : profiles) {
- // Change password on the given user and all its profiles that don't have
- // their own profile challenge enabled.
- if (pi.id == userHandle || (pi.isManagedProfile()
- && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id))) {
- ks.onUserPasswordChanged(pi.id, password);
- }
- }
- }
+ ks.onUserPasswordChanged(userHandle, password);
}
private void unlockKeystore(String password, int userHandle) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+ if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
final KeyStore ks = KeyStore.getInstance();
+ ks.unlock(userHandle, password);
+ }
- if (um.getUserInfo(userHandle).isManagedProfile()) {
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
- ks.unlock(userHandle, password);
+ private String getDecryptedPasswordForTiedProfile(int userId)
+ throws KeyStoreException, UnrecoverableKeyException,
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
+ CertificateException, IOException {
+ if (DEBUG) Slog.v(TAG, "Unlock keystore for child profile");
+ byte[] storedData = mStorage.readChildProfileLock(userId);
+ if (storedData == null) {
+ throw new FileNotFoundException("Child profile lock file not found");
+ }
+ byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
+ byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
+ storedData.length);
+ byte[] decryptionResult;
+ java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+ SecretKey decryptionKey = (SecretKey) keyStore.getKey(
+ PROFILE_KEY_NAME_DECRYPT + userId, null);
+
+ Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+
+ cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
+ decryptionResult = cipher.doFinal(encryptedPassword);
+ return new String(decryptionResult, StandardCharsets.UTF_8);
+ }
+
+ private void unlockChildProfile(int profileHandle) throws RemoteException {
+ try {
+ doVerifyPassword(getDecryptedPasswordForTiedProfile(profileHandle), false,
+ 0 /* no challenge */, profileHandle);
+ } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+ | NoSuchAlgorithmException | NoSuchPaddingException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | CertificateException | IOException e) {
+ if (e instanceof FileNotFoundException) {
+ Slog.i(TAG, "Child profile key not found");
} else {
- throw new RuntimeException("Can't unlock a profile explicitly if it "
- + "doesn't have a profile challenge.");
- }
- } else {
- final List<UserInfo> profiles = um.getProfiles(userHandle);
- for (UserInfo pi : profiles) {
- // Unlock the given user and all its profiles that don't have
- // their own profile challenge enabled.
- if (pi.id == userHandle || (pi.isManagedProfile()
- && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id))) {
- ks.unlock(pi.id, password);
- }
+ Slog.e(TAG, "Failed to decrypt child profile key", e);
}
}
}
@@ -627,6 +716,21 @@
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
+ try {
+ if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
+ final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+ for (UserInfo pi : profiles) {
+ // Unlock managed profile with unified lock
+ if (pi.isManagedProfile()
+ && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+ && mStorage.hasChildProfileLock(pi.id)) {
+ unlockChildProfile(pi.id);
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ Log.d(TAG, "Failed to unlock child profile", e);
+ }
}
private byte[] getCurrentHandle(int userId) {
@@ -661,10 +765,57 @@
return currentHandle;
}
+ private void onUserLockChanged(int userId) throws RemoteException {
+ if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+ return;
+ }
+ final boolean isSecure = mStorage.hasPassword(userId) || mStorage.hasPattern(userId);
+ final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+ final int size = profiles.size();
+ for (int i = 0; i < size; i++) {
+ final UserInfo profile = profiles.get(i);
+ if (profile.isManagedProfile()) {
+ final int managedUserId = profile.id;
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+ continue;
+ }
+ if (isSecure) {
+ tieManagedProfileLockIfNecessary(managedUserId, null);
+ } else {
+ getGateKeeperService().clearSecureUserId(managedUserId);
+ mStorage.writePatternHash(null, managedUserId);
+ setKeystorePassword(null, managedUserId);
+ clearUserKeyProtection(managedUserId);
+ mStorage.removeChildProfileLock(managedUserId);
+ removeKeystoreProfileKey(managedUserId);
+ }
+ }
+ }
+ }
+ private boolean isManagedProfileWithUnifiedLock(int userId) {
+ return mUserManager.getUserInfo(userId).isManagedProfile()
+ && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+ }
+
+ private boolean isManagedProfileWithSeparatedLock(int userId) {
+ return mUserManager.getUserInfo(userId).isManagedProfile()
+ && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+ }
+
+ // This method should be called by LockPatternUtil only, all internal methods in this class
+ // should call setLockPatternInternal.
@Override
public void setLockPattern(String pattern, String savedCredential, int userId)
throws RemoteException {
+ synchronized (mSeparateChallengeLock) {
+ setLockPatternInternal(pattern, savedCredential, userId);
+ setSeparateProfileChallengeEnabled(userId, true, null);
+ }
+ }
+
+ public void setLockPatternInternal(String pattern, String savedCredential, int userId)
+ throws RemoteException {
byte[] currentHandle = getCurrentHandle(userId);
if (pattern == null) {
@@ -672,55 +823,157 @@
mStorage.writePatternHash(null, userId);
setKeystorePassword(null, userId);
clearUserKeyProtection(userId);
+ onUserLockChanged(userId);
return;
}
- if (currentHandle == null) {
- if (savedCredential != null) {
- Slog.w(TAG, "Saved credential provided, but none stored");
+ if (isManagedProfileWithUnifiedLock(userId)) {
+ // get credential from keystore when managed profile has unified lock
+ try {
+ savedCredential = getDecryptedPasswordForTiedProfile(userId);
+ } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+ | NoSuchAlgorithmException | NoSuchPaddingException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | CertificateException | IOException e) {
+ if (e instanceof FileNotFoundException) {
+ Slog.i(TAG, "Child profile key not found");
+ } else {
+ Slog.e(TAG, "Failed to decrypt child profile key", e);
+ }
}
- savedCredential = null;
+ } else {
+ if (currentHandle == null) {
+ if (savedCredential != null) {
+ Slog.w(TAG, "Saved credential provided, but none stored");
+ }
+ savedCredential = null;
+ }
}
byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, pattern, userId);
if (enrolledHandle != null) {
mStorage.writePatternHash(enrolledHandle, userId);
setUserKeyProtection(userId, pattern, verifyPattern(pattern, 0, userId));
+ onUserLockChanged(userId);
} else {
throw new RemoteException("Failed to enroll pattern");
}
}
-
+ // This method should be called by LockPatternUtil only, all internal methods in this class
+ // should call setLockPasswordInternal.
@Override
public void setLockPassword(String password, String savedCredential, int userId)
throws RemoteException {
- byte[] currentHandle = getCurrentHandle(userId);
+ synchronized (mSeparateChallengeLock) {
+ setLockPasswordInternal(password, savedCredential, userId);
+ setSeparateProfileChallengeEnabled(userId, true, null);
+ }
+ }
+ public void setLockPasswordInternal(String password, String savedCredential, int userId)
+ throws RemoteException {
+ byte[] currentHandle = getCurrentHandle(userId);
if (password == null) {
getGateKeeperService().clearSecureUserId(userId);
mStorage.writePasswordHash(null, userId);
setKeystorePassword(null, userId);
clearUserKeyProtection(userId);
+ onUserLockChanged(userId);
return;
}
- if (currentHandle == null) {
- if (savedCredential != null) {
- Slog.w(TAG, "Saved credential provided, but none stored");
+ if (isManagedProfileWithUnifiedLock(userId)) {
+ // get credential from keystore when managed profile has unified lock
+ try {
+ savedCredential = getDecryptedPasswordForTiedProfile(userId);
+ } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+ | NoSuchAlgorithmException | NoSuchPaddingException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | CertificateException | IOException e) {
+ if (e instanceof FileNotFoundException) {
+ Slog.i(TAG, "Child profile key not found");
+ } else {
+ Slog.e(TAG, "Failed to decrypt child profile key", e);
+ }
}
- savedCredential = null;
+ } else {
+ if (currentHandle == null) {
+ if (savedCredential != null) {
+ Slog.w(TAG, "Saved credential provided, but none stored");
+ }
+ savedCredential = null;
+ }
}
byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, password, userId);
if (enrolledHandle != null) {
mStorage.writePasswordHash(enrolledHandle, userId);
setUserKeyProtection(userId, password, verifyPassword(password, 0, userId));
+ onUserLockChanged(userId);
} else {
throw new RemoteException("Failed to enroll password");
}
}
+ private void tieProfileLockToParent(int userId, String password) {
+ if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
+ byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
+ byte[] encryptionResult;
+ byte[] iv;
+ try {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+ keyGenerator.init(new SecureRandom());
+ SecretKey secretKey = keyGenerator.generateKey();
+
+ java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+ keyStore.setEntry(
+ PROFILE_KEY_NAME_ENCRYPT + userId,
+ new java.security.KeyStore.SecretKeyEntry(secretKey),
+ new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .build());
+ keyStore.setEntry(
+ PROFILE_KEY_NAME_DECRYPT + userId,
+ new java.security.KeyStore.SecretKeyEntry(secretKey),
+ new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setUserAuthenticationRequired(true)
+ .setUserAuthenticationValidityDurationSeconds(30)
+ .build());
+
+ // Key imported, obtain a reference to it.
+ SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
+ PROFILE_KEY_NAME_ENCRYPT + userId, null);
+ // The original key can now be discarded.
+
+ Cipher cipher = Cipher.getInstance(
+ KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+ + KeyProperties.ENCRYPTION_PADDING_NONE);
+ cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
+ encryptionResult = cipher.doFinal(randomLockSeed);
+ iv = cipher.getIV();
+ } catch (CertificateException | UnrecoverableKeyException
+ | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+ | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+ throw new RuntimeException("Failed to encrypt key", e);
+ }
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ try {
+ if (iv.length != PROFILE_KEY_IV_SIZE) {
+ throw new RuntimeException("Invalid iv length: " + iv.length);
+ }
+ outputStream.write(iv);
+ outputStream.write(encryptionResult);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to concatenate byte arrays", e);
+ }
+ mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
+ }
+
private byte[] enrollCredential(byte[] enrolledHandle,
String enrolledCredential, String toEnroll, int userId)
throws RemoteException {
@@ -820,7 +1073,7 @@
@Override
public void setCredential(String pattern, String oldPattern, int userId)
throws RemoteException {
- setLockPattern(pattern, oldPattern, userId);
+ setLockPatternInternal(pattern, oldPattern, userId);
}
@Override
@@ -838,7 +1091,7 @@
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK
&& shouldReEnrollBaseZero) {
- setLockPattern(pattern, patternToVerify, userId);
+ setLockPatternInternal(pattern, patternToVerify, userId);
}
return response;
@@ -857,6 +1110,37 @@
return doVerifyPassword(password, true, challenge, userId);
}
+ @Override
+ public VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern,
+ long challenge, int userId) throws RemoteException {
+ checkPasswordReadPermission(userId);
+ if (!isManagedProfileWithUnifiedLock(userId)) {
+ throw new RemoteException("User id must be managed profile with unified lock");
+ }
+ final int parentProfileId = mUserManager.getProfileParent(userId).id;
+ // Unlock parent by using parent's challenge
+ final VerifyCredentialResponse parentResponse = isPattern
+ ? doVerifyPattern(password, true, challenge, parentProfileId)
+ : doVerifyPassword(password, true, challenge, parentProfileId);
+ if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+ // Failed, just return parent's response
+ return parentResponse;
+ }
+
+ try {
+ // Unlock work profile, and work profile with unified lock must use password only
+ return doVerifyPassword(getDecryptedPasswordForTiedProfile(userId), true,
+ challenge,
+ userId);
+ } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+ | NoSuchAlgorithmException | NoSuchPaddingException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | CertificateException | IOException e) {
+ Slog.e(TAG, "Failed to decrypt child profile key", e);
+ throw new RemoteException("Unable to get tied profile token");
+ }
+ }
+
private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
@@ -866,7 +1150,7 @@
@Override
public void setCredential(String password, String oldPassword, int userId)
throws RemoteException {
- setLockPassword(password, oldPassword, userId);
+ setLockPasswordInternal(password, oldPassword, userId);
}
@Override
@@ -947,8 +1231,7 @@
" with token length " + response.getPayload().length);
unlockUser(userId, response.getPayload(), secretFromCredential(credential));
- UserInfo info = UserManager.get(mContext).getUserInfo(userId);
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+ if (isManagedProfileWithSeparatedLock(userId)) {
TrustManager trustManager =
(TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
trustManager.setDeviceLockedForUser(userId, false);
@@ -1027,6 +1310,23 @@
} catch (RemoteException ex) {
Slog.w(TAG, "unable to clear GK secure user id");
}
+ if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+ removeKeystoreProfileKey(userId);
+ }
+ }
+
+ private void removeKeystoreProfileKey(int targetUserId) {
+ if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
+ try {
+ java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+ keyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + targetUserId);
+ keyStore.deleteEntry(PROFILE_KEY_NAME_DECRYPT + targetUserId);
+ } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+ | IOException e) {
+ // We have tried our best to remove all keys
+ Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index 816c791..d136f1a 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -17,7 +17,6 @@
package com.android.server;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.widget.LockPatternUtils;
import android.content.ContentValues;
import android.content.Context;
@@ -30,6 +29,7 @@
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import java.io.File;
import java.io.IOException;
@@ -44,6 +44,7 @@
private static final String TAG = "LockSettingsStorage";
private static final String TABLE = "locksettings";
+ private static final boolean DEBUG = false;
private static final String COLUMN_KEY = "name";
private static final String COLUMN_USERID = "user";
@@ -62,6 +63,7 @@
private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
+ private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
private static final Object DEFAULT = new Object();
@@ -70,8 +72,7 @@
private final Cache mCache = new Cache();
private final Object mFileWriteLock = new Object();
- private int mStoredCredentialType;
- private LockPatternUtils mLockPatternUtils;
+ private SparseArray<Integer> mStoredCredentialType;
class CredentialHash {
static final int TYPE_NONE = -1;
@@ -101,7 +102,7 @@
public LockSettingsStorage(Context context, Callback callback) {
mContext = context;
mOpenHelper = new DatabaseHelper(context, callback);
- mLockPatternUtils = new LockPatternUtils(context);
+ mStoredCredentialType = new SparseArray<Integer>();
}
public void writeKeyValue(String key, String value, int userId) {
@@ -182,32 +183,34 @@
}
public int getStoredCredentialType(int userId) {
- if (mStoredCredentialType != 0) {
- return mStoredCredentialType;
+ final Integer cachedStoredCredentialType = mStoredCredentialType.get(userId);
+ if (cachedStoredCredentialType != null) {
+ return cachedStoredCredentialType.intValue();
}
+ int storedCredentialType;
CredentialHash pattern = readPatternHash(userId);
if (pattern == null) {
if (readPasswordHash(userId) != null) {
- mStoredCredentialType = CredentialHash.TYPE_PASSWORD;
+ storedCredentialType = CredentialHash.TYPE_PASSWORD;
} else {
- mStoredCredentialType = CredentialHash.TYPE_NONE;
+ storedCredentialType = CredentialHash.TYPE_NONE;
}
} else {
CredentialHash password = readPasswordHash(userId);
if (password != null) {
// Both will never be GateKeeper
if (password.version == CredentialHash.VERSION_GATEKEEPER) {
- mStoredCredentialType = CredentialHash.TYPE_PASSWORD;
+ storedCredentialType = CredentialHash.TYPE_PASSWORD;
} else {
- mStoredCredentialType = CredentialHash.TYPE_PATTERN;
+ storedCredentialType = CredentialHash.TYPE_PATTERN;
}
} else {
- mStoredCredentialType = CredentialHash.TYPE_PATTERN;
+ storedCredentialType = CredentialHash.TYPE_PATTERN;
}
}
-
- return mStoredCredentialType;
+ mStoredCredentialType.put(userId, storedCredentialType);
+ return storedCredentialType;
}
@@ -244,6 +247,27 @@
return null;
}
+ public void removeChildProfileLock(int userId) {
+ if (DEBUG)
+ Slog.e(TAG, "Remove child profile lock for user: " + userId);
+ try {
+ deleteFile(getChildProfileLockFile(userId));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeChildProfileLock(int userId, byte[] lock) {
+ writeFile(getChildProfileLockFile(userId), lock);
+ }
+
+ public byte[] readChildProfileLock(int userId) {
+ return readFile(getChildProfileLockFile(userId));
+ }
+
+ public boolean hasChildProfileLock(int userId) {
+ return hasFile(getChildProfileLockFile(userId));
+ }
public boolean hasPassword(int userId) {
return hasFile(getLockPasswordFilename(userId)) ||
@@ -321,16 +345,19 @@
}
private void deleteFile(String name) {
- File f = new File(name);
- if (f != null) {
- f.delete();
+ if (DEBUG) Slog.e(TAG, "Delete file " + name);
+ synchronized (mFileWriteLock) {
+ File file = new File(name);
+ if (file.exists()) {
+ file.delete();
+ mCache.putFile(name, null);
+ }
}
}
public void writePatternHash(byte[] hash, int userId) {
- mStoredCredentialType = hash == null
- ? CredentialHash.TYPE_NONE
- : CredentialHash.TYPE_PATTERN;
+ mStoredCredentialType.put(userId, hash == null ? CredentialHash.TYPE_NONE
+ : CredentialHash.TYPE_PATTERN);
writeFile(getLockPatternFilename(userId), hash);
clearPasswordHash(userId);
}
@@ -340,9 +367,8 @@
}
public void writePasswordHash(byte[] hash, int userId) {
- mStoredCredentialType = hash == null
- ? CredentialHash.TYPE_NONE
- : CredentialHash.TYPE_PASSWORD;
+ mStoredCredentialType.put(userId, hash == null ? CredentialHash.TYPE_NONE
+ : CredentialHash.TYPE_PASSWORD);
writeFile(getLockPasswordFilename(userId), hash);
clearPatternHash(userId);
}
@@ -375,8 +401,11 @@
return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
}
+ private String getChildProfileLockFile(int userId) {
+ return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+ }
+
private String getLockCredentialFilePathForUser(int userId, String basename) {
- userId = getUserParentOrSelfId(userId);
String dataSystemDirectory =
android.os.Environment.getDataDirectory().getAbsolutePath() +
SYSTEM_DIRECTORY;
@@ -388,23 +417,6 @@
}
}
- private int getUserParentOrSelfId(int userId) {
- // Device supports per user encryption, so lock is applied to the given user.
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
- return userId;
- }
- // Device uses Block Based Encryption, and the parent user's lock is used for the whole
- // device.
- if (userId != 0) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- final UserInfo pi = um.getProfileParent(userId);
- if (pi != null) {
- return pi.id;
- }
- }
- return userId;
- }
-
public void removeUser(int userId) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
@@ -427,6 +439,9 @@
mCache.putFile(name, null);
}
}
+ } else {
+ // Manged profile
+ removeChildProfileLock(userId);
}
try {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 440d8b7..fd9a94d 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -1984,6 +1984,28 @@
mHandler.obtainMessage(H_RESET).sendToTarget();
}
}
+
+ if ((mask & (StorageManager.DEBUG_SDCARDFS_FORCE_ON
+ | StorageManager.DEBUG_SDCARDFS_FORCE_OFF)) != 0) {
+ final String value;
+ if ((flags & StorageManager.DEBUG_SDCARDFS_FORCE_ON) != 0) {
+ value = "force_on";
+ } else if ((flags & StorageManager.DEBUG_SDCARDFS_FORCE_OFF) != 0) {
+ value = "force_off";
+ } else {
+ value = "";
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ SystemProperties.set(StorageManager.PROP_SDCARDFS, value);
+
+ // Reset storage to kick new setting into place
+ mHandler.obtainMessage(H_RESET).sendToTarget();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8a0a62a..810270d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2884,7 +2884,6 @@
}
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
- if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1587516..0f48d21 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1467,6 +1467,7 @@
static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
+ static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2056,6 +2057,21 @@
}
break;
}
+ case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
+ synchronized (ActivityManagerService.this) {
+ for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+ try {
+ // Make a one-way callback to the listener
+ mTaskStackListeners.getBroadcastItem(i)
+ .onActivityDismissingDockedStack();
+ } catch (RemoteException e){
+ // Handled by the RemoteCallbackList
+ }
+ }
+ mTaskStackListeners.finishBroadcast();
+ }
+ break;
+ }
case NOTIFY_CLEARTEXT_NETWORK_MSG: {
final int uid = msg.arg1;
final byte[] firstPacket = (byte[]) msg.obj;
@@ -10590,14 +10606,14 @@
private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
ProcessRecord r, final int userId) {
if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
- cpi.packageName, r.userId)) {
+ cpi.packageName, userId)) {
- final boolean callerForeground = r != null ? r.setSchedGroup
- != ProcessList.SCHED_GROUP_BACKGROUND : true;
+ final boolean callerForeground = r == null || r.setSchedGroup
+ != ProcessList.SCHED_GROUP_BACKGROUND;
// Show a permission review UI only for starting from a foreground app
if (!callerForeground) {
- Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
+ Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
+ cpi.packageName + " requires a permissions review");
return false;
}
@@ -10608,7 +10624,7 @@
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
if (DEBUG_PERMISSIONS_REVIEW) {
- Slog.i(TAG, "u" + r.userId + " Launching permission review "
+ Slog.i(TAG, "u" + userId + " Launching permission review "
+ "for package " + cpi.packageName);
}
@@ -15641,8 +15657,8 @@
pw.println(totalPss - cachedPss);
}
}
- long lostRAM = memInfo.getTotalSizeKb()
- - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
+ - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
if (!isCompact) {
pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 4ec1f61..2e9947a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -28,47 +28,78 @@
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-
import static android.content.res.Configuration.SCREENLAYOUT_UNDEFINED;
-import static com.android.server.am.ActivityManagerDebugConfig.*;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SCREENSHOTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TRANSITION;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_APP;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SCREENSHOTS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TRANSITION;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-
+import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_REMOVED;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.MOVING;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.ArraySet;
-
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.content.ReferrerIntent;
-import com.android.internal.os.BatteryStatsImpl;
-import com.android.server.Watchdog;
-import com.android.server.am.ActivityManagerService.ItemMatcher;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
-import com.android.server.wm.AppTransition;
-import com.android.server.wm.TaskGroup;
-import com.android.server.wm.WindowManagerService;
+import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
+import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_NONE;
+import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
+import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN_BEHIND;
+import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_BACK;
+import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackId;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
import android.app.ResultInfo;
-import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -83,10 +114,20 @@
import android.os.Trace;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
+import android.util.ArraySet;
import android.util.EventLog;
import android.util.Slog;
import android.view.Display;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
+import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.Watchdog;
+import com.android.server.am.ActivityManagerService.ItemMatcher;
+import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
+import com.android.server.wm.TaskGroup;
+import com.android.server.wm.WindowManagerService;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -1650,6 +1691,13 @@
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.finishing) {
+ // Normally the screenshot will be taken in makeInvisible(). When an activity
+ // is finishing, we no longer change its visibility, but we still need to take
+ // the screenshots if startPausingLocked decided it should be taken.
+ if (r.mUpdateTaskThumbnailWhenHidden) {
+ r.updateThumbnailLocked(screenshotActivitiesLocked(r), null);
+ r.mUpdateTaskThumbnailWhenHidden = false;
+ }
continue;
}
final boolean isTop = r == top;
@@ -2225,11 +2273,11 @@
"Prepare close transition: prev=" + prev);
if (mNoAnimActivities.contains(prev)) {
anim = false;
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
- ? AppTransition.TRANSIT_ACTIVITY_CLOSE
- : AppTransition.TRANSIT_TASK_CLOSE, false);
+ ? TRANSIT_ACTIVITY_CLOSE
+ : TRANSIT_TASK_CLOSE, false);
}
mWindowManager.setAppVisibility(prev.appToken, false);
} else {
@@ -2237,22 +2285,22 @@
"Prepare open transition: prev=" + prev);
if (mNoAnimActivities.contains(next)) {
anim = false;
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
- ? AppTransition.TRANSIT_ACTIVITY_OPEN
+ ? TRANSIT_ACTIVITY_OPEN
: next.mLaunchTaskBehind
- ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
- : AppTransition.TRANSIT_TASK_OPEN, false);
+ ? TRANSIT_TASK_OPEN_BEHIND
+ : TRANSIT_TASK_OPEN, false);
}
}
} else {
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
if (mNoAnimActivities.contains(next)) {
anim = false;
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
} else {
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
+ mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
}
}
@@ -2595,14 +2643,14 @@
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare open transition: starting " + r);
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
mNoAnimActivities.add(r);
} else {
mWindowManager.prepareAppTransition(newTask
? r.mLaunchTaskBehind
- ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
- : AppTransition.TRANSIT_TASK_OPEN
- : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
+ ? TRANSIT_TASK_OPEN_BEHIND
+ : TRANSIT_TASK_OPEN
+ : TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
addConfigOverride(r, task);
@@ -3354,13 +3402,13 @@
finishActivityResultsLocked(r, resultCode, resultData);
+ final boolean endTask = index <= 0;
+ final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
if (mResumedActivity == r) {
- boolean endTask = index <= 0;
+
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: finishing " + r);
- mWindowManager.prepareAppTransition(endTask
- ? AppTransition.TRANSIT_TASK_CLOSE
- : AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
+ mWindowManager.prepareAppTransition(transit, false);
// Tell window manager to prepare for this one to be removed.
mWindowManager.setAppVisibility(r.appToken, false);
@@ -3380,7 +3428,9 @@
// it is done pausing; else we can just directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
if (r.visible) {
+ mWindowManager.prepareAppTransition(transit, false);
mWindowManager.setAppVisibility(r.appToken, false);
+ mWindowManager.executeAppTransition();
}
return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
} else {
@@ -4122,7 +4172,7 @@
if (noAnimation) {
ActivityOptions.abort(options);
} else {
- updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
+ updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
}
return;
}
@@ -4152,13 +4202,13 @@
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
if (noAnimation) {
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
if (r != null) {
mNoAnimActivities.add(r);
}
ActivityOptions.abort(options);
} else {
- updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
+ updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
@@ -4261,7 +4311,7 @@
}
}
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
+ mWindowManager.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
mWindowManager.moveTaskToBottom(taskId);
if (VALIDATE_TOKENS) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7b2a370..d34e8fc 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -152,6 +152,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityManagerService.ANIMATE;
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG;
import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
@@ -1810,7 +1811,7 @@
if (DEBUG_STACK) Slog.d(TAG_STACK,
"findTaskToMoveToFront: moved to front of stack=" + task.stack);
- showNonResizeableDockToastIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId);
+ handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId);
}
boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
@@ -2392,7 +2393,7 @@
resumeFocusedStackTopActivityLocked();
}
- showNonResizeableDockToastIfNeeded(task, preferredLaunchStackId, stackId);
+ handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);
return (preferredLaunchStackId == stackId);
}
@@ -3248,13 +3249,9 @@
}
private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
- if (display.mDisplayId != Display.DEFAULT_DISPLAY) {
- return;
- }
- final float fraction = mService.mContext.getResources().getFraction(com.android.internal.R.
- fraction.config_displayFractionForDefaultMinimalSizeOfResizeableTask, 1, 1);
- mDefaultMinimalSizeOfResizeableTask = (int) (fraction * Math.min(
- display.mDisplayInfo.logicalWidth, display.mDisplayInfo.logicalHeight));
+ mDefaultMinimalSizeOfResizeableTask =
+ mService.mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.default_minimal_size_resizable_task);
}
private void handleDisplayRemoved(int displayId) {
@@ -3363,15 +3360,19 @@
}
}
- void showNonResizeableDockToastIfNeeded(
+ void handleNonResizableTaskIfNeeded(
TaskRecord task, int preferredStackId, int actualStackId) {
- if (!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) {
+ if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
+ || task.isHomeTask()) {
return;
}
if (!task.canGoInDockedStack()) {
// Display a warning toast that we tried to put a non-dockable task in the docked stack.
- mWindowManager.scheduleShowNonResizeableDockToast(task.taskId);
+ mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
+
+ // Dismiss docked stack.
+ mService.moveTasksToFullscreenStack(DOCKED_STACK_ID, false);
} else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
String packageName = task.getTopActivity() != null
? task.getTopActivity().appInfo.packageName : null;
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 76dfd01..785dd47 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -119,7 +119,13 @@
if (!mUserManager.isQuietModeEnabled(UserHandle.of(mUserId))) {
return false;
}
- mIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(mUserId);
+ IIntentSender target = mService.getIntentSenderLocked(
+ INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingUid, mUserId, null, null, 0,
+ new Intent[] {mIntent}, new String[] {mResolvedType},
+ FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT, null);
+
+ mIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(mUserId,
+ new IntentSender(target));
mCallingPid = mRealCallingPid;
mCallingUid = mRealCallingUid;
mResolvedType = null;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 3bbc4521..6fba8c8 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -986,8 +986,12 @@
}
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
- mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
- preferredLaunchStackId, topStack.mStackId);
+
+ // Don't use mStartActivity.task to show the toast. We're not starting a new activity
+ // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
+ mSupervisor.handleNonResizableTaskIfNeeded(
+ top.task, preferredLaunchStackId, topStack.mStackId);
+
return START_DELIVERED_TO_TOP;
}
@@ -1074,7 +1078,7 @@
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
- mSupervisor.showNonResizeableDockToastIfNeeded(
+ mSupervisor.handleNonResizableTaskIfNeeded(
mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
return START_SUCCESS;
@@ -1382,6 +1386,9 @@
mTargetStack.moveToFront("intentActivityFound");
}
+ mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task, INVALID_STACK_ID,
+ mTargetStack.mStackId);
+
// If the caller has requested that the target task be reset, then do so.
if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index e32d1d1..e69c662 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1447,7 +1447,8 @@
if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
mLastNonFullscreenBounds = mBounds;
}
- mOverrideConfig = calculateOverrideConfig(mTmpRect, insetBounds);
+ mOverrideConfig = calculateOverrideConfig(mTmpRect, insetBounds,
+ mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
}
if (mFullscreen != oldFullscreen) {
@@ -1457,33 +1458,38 @@
return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
}
- private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds) {
+ private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds,
+ boolean overrideWidth, boolean overrideHeight) {
mTmpRect2.set(inInsetBounds);
mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
int leftInset = mTmpRect2.left - inInsetBounds.left;
int topInset = mTmpRect2.top - inInsetBounds.top;
- int rightInset = inInsetBounds.right - mTmpRect2.right;
- int bottomInset = inInsetBounds.bottom - mTmpRect2.bottom;
+ int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
+ int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
}
- private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds) {
+ private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds,
+ boolean overrideWidth, boolean overrideHeight) {
mTmpRect2.set(inInsetBounds);
mService.mWindowManager.subtractStableInsets(mTmpRect2);
int leftInset = mTmpRect2.left - inInsetBounds.left;
int topInset = mTmpRect2.top - inInsetBounds.top;
- int rightInset = inInsetBounds.right - mTmpRect2.right;
- int bottomInset = inInsetBounds.bottom - mTmpRect2.bottom;
+ int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
+ int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
}
- private Configuration calculateOverrideConfig(Rect bounds, Rect insetBounds) {
+ private Configuration calculateOverrideConfig(Rect bounds, Rect insetBounds,
+ boolean overrideWidth, boolean overrideHeight) {
mTmpNonDecorBounds.set(bounds);
mTmpStableBounds.set(bounds);
subtractNonDecorInsets(
- mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds);
+ mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds,
+ overrideWidth, overrideHeight);
subtractStableInsets(
- mTmpStableBounds, insetBounds != null ? insetBounds : bounds);
+ mTmpStableBounds, insetBounds != null ? insetBounds : bounds,
+ overrideWidth, overrideHeight);
// For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
// i.e. the screen area without the system bars.
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 6e890d5..bea26c7 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -237,7 +237,22 @@
AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
}
- maybeUnlockUser(userId);
+ // We need to delay unlocking managed profiles until the parent user
+ // is also unlocked.
+ if (getUserManager().isManagedProfile(userId)) {
+ final UserInfo parent = getUserManager().getProfileParent(userId);
+ if (parent != null
+ && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
+ Slog.d(TAG, "User " + userId + " (parent " + parent.id
+ + "): attempting unlock because parent is unlocked");
+ maybeUnlockUser(userId);
+ } else {
+ Slog.d(TAG, "User " + userId + " (parent " + parent.id
+ + "): delaying unlock because parent is locked");
+ }
+ } else {
+ maybeUnlockUser(userId);
+ }
}
}
@@ -903,6 +918,18 @@
synchronized (mService) {
final UserState uss = mStartedUsers.get(userId);
finishUserUnlocking(uss, progress);
+
+ // We just unlocked a user, so let's now attempt to unlock any
+ // managed profiles under that user.
+ for (int i = 0; i < mStartedUsers.size(); i++) {
+ final int testUserId = mStartedUsers.keyAt(i);
+ final UserInfo parent = getUserManager().getProfileParent(testUserId);
+ if (parent != null && parent.id == userId && testUserId != userId) {
+ Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
+ + "): attempting unlock because parent was just unlocked");
+ maybeUnlockUser(testUserId);
+ }
+ }
}
return true;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f471af6..58db985 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3954,25 +3954,16 @@
public void applyAllVolumes() {
synchronized (VolumeStreamState.class) {
- // apply default volume first: by convention this will reset all
- // devices volumes in audio policy manager to the supplied value
+ // apply device specific volumes first
int index;
- if (mIsMuted) {
- index = 0;
- } else {
- index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
- }
- AudioSystem.setStreamVolumeIndex(mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT);
- // then apply device specific volumes
for (int i = 0; i < mIndexMap.size(); i++) {
- int device = mIndexMap.keyAt(i);
+ final int device = mIndexMap.keyAt(i);
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
if (mIsMuted) {
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
mAvrcpAbsVolSupported)
- || ((device & mFullVolumeDevices) != 0))
- {
+ || ((device & mFullVolumeDevices) != 0)) {
index = (mIndexMax + 5)/10;
} else {
index = (mIndexMap.valueAt(i) + 5)/10;
@@ -3980,6 +3971,15 @@
AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
}
}
+ // apply default volume last: by convention , default device volume will be used
+ // by audio policy manager if no explicit volume is present for a given device type
+ if (mIsMuted) {
+ index = 0;
+ } else {
+ index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
+ }
+ AudioSystem.setStreamVolumeIndex(
+ mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT);
}
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index e5342ce..db41a54 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1402,12 +1402,24 @@
}
}
+ private void restoreLostPeriodicSyncsIfNeeded(int userId) {
+ List<SyncOperation> periodicSyncs = new ArrayList<SyncOperation>();
+ for (SyncOperation sync : getAllPendingSyncs()) {
+ if (sync.isPeriodic && sync.target.userId == userId) {
+ periodicSyncs.add(sync);
+ }
+ }
+ mSyncStorageEngine.restorePeriodicSyncsIfNeededForUser(userId, periodicSyncs);
+ }
+
private void onUserUnlocked(int userId) {
// Make sure that accounts we're about to use are valid.
AccountManagerService.getSingleton().validateAccounts(userId);
mSyncAdapters.invalidateCache(userId);
+ restoreLostPeriodicSyncsIfNeeded(userId);
+
EndPoint target = new EndPoint(null, null, userId);
updateRunningAccounts(target);
@@ -2578,9 +2590,11 @@
}
}
+ // Cancel all jobs from non-existent accounts.
+ AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts();
List<SyncOperation> ops = getAllPendingSyncs();
for (SyncOperation op: ops) {
- if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) {
+ if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) {
getJobScheduler().cancel(op.jobId);
}
}
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index bc3fc6a..fb23265 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -826,6 +826,35 @@
return true;
}
+ /**
+ * STOPSHIP This is a temporary workaround and should be removed before shipping: b/28052438
+ */
+ void restorePeriodicSyncsIfNeededForUser(int userHandle, List<SyncOperation> periodicSyncs) {
+ if (mPeriodicSyncAddedListener == null) {
+ return;
+ }
+ synchronized (mAuthorities) {
+ for (int i = 0; i < mAuthorities.size(); i++) {
+ AuthorityInfo authority = mAuthorities.valueAt(i);
+ if (authority.target.userId == userHandle && authority.enabled) {
+ boolean periodicSyncAlreadyExists = false;
+ for (SyncOperation sync : periodicSyncs) {
+ if (authority.target.matchesSpec(sync.target)) {
+ periodicSyncAlreadyExists = true;
+ break;
+ }
+ }
+ // The periodic sync must have been lost due to previous bug.
+ if (!periodicSyncAlreadyExists) {
+ mPeriodicSyncAddedListener.onPeriodicSyncAdded(authority.target,
+ new Bundle(), DEFAULT_POLL_FREQUENCY_SECONDS,
+ calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS));
+ }
+ }
+ }
+ }
+ }
+
public void setMasterSyncAutomatically(boolean flag, int userId) {
synchronized (mAuthorities) {
Boolean auto = mMasterSyncAutomatically.get(userId);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 7ba030f..3d8bf51 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -947,10 +947,6 @@
if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
-
- // Group ID is arbitrarily set to parent profile user ID. It just represents
- // the default fingerprints for the user.
- final int effectiveGroupId = getEffectiveUserId(groupId);
final int realUserId = Binder.getCallingUid();
final boolean restricted = isRestricted();
@@ -958,7 +954,7 @@
@Override
public void run() {
MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
- startAuthentication(token, opId, realUserId, effectiveGroupId, receiver,
+ startAuthentication(token, opId, realUserId, groupId, receiver,
flags, restricted, opPackageName);
}
});
@@ -993,14 +989,10 @@
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
final boolean restricted = isRestricted();
-
- // Group ID is arbitrarily set to parent profile user ID. It just represents
- // the default fingerprints for the user.
- final int effectiveGroupId = getEffectiveUserId(groupId);
mHandler.post(new Runnable() {
@Override
public void run() {
- startRemove(token, fingerId, effectiveGroupId, receiver, restricted);
+ startRemove(token, fingerId, groupId, receiver, restricted);
}
});
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 5ad8189..be9d800 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -77,8 +77,10 @@
if (cs != null) {
if (cs.getActiveNetworkInfo() != null) {
mNetworkConnected = cs.getActiveNetworkInfo().isConnected();
+ mNetworkUnmetered = mNetworkConnected && !cs.isActiveNetworkMetered();
+ } else {
+ mNetworkConnected = mNetworkUnmetered = false;
}
- mNetworkUnmetered = mNetworkConnected && !cs.isActiveNetworkMetered();
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index e08fad4..d80dc3b 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -39,6 +39,7 @@
import android.location.IGnssStatusListener;
import android.location.IGnssStatusProvider;
import android.location.GnssMeasurementsEvent;
+import android.location.GnssNavigationMessage;
import android.location.GnssNavigationMessageEvent;
import android.location.IGpsGeofenceHardware;
import android.location.ILocationManager;
@@ -1662,11 +1663,21 @@
/**
* called from native code - GPS navigation message callback
*/
- private void reportNavigationMessage(GnssNavigationMessageEvent event) {
+ private void reportNavigationMessage(GnssNavigationMessage event) {
mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
}
/**
+ * called from native code - GPS navigation message callback
+ */
+ private void reportNavigationMessage(GnssNavigationMessageEvent event) {
+ if (event != null) {
+ mGnssNavigationMessageProvider
+ .onNavigationMessageAvailable(event.getNavigationMessage());
+ }
+ }
+
+ /**
* called from native code to inform us what the GPS engine capabilities are
*/
private void setEngineCapabilities(int capabilities) {
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 734a8d4..caf1d6c 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -64,15 +64,15 @@
int status;
switch (result) {
case RESULT_SUCCESS:
- status = GnssMeasurementsEvent.STATUS_READY;
+ status = GnssMeasurementsEvent.Callback.STATUS_READY;
break;
case RESULT_NOT_AVAILABLE:
case RESULT_NOT_SUPPORTED:
case RESULT_INTERNAL_ERROR:
- status = GnssMeasurementsEvent.STATUS_NOT_SUPPORTED;
+ status = GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED;
break;
case RESULT_GPS_LOCATION_DISABLED:
- status = GnssMeasurementsEvent.STATUS_GNSS_LOCATION_DISABLED;
+ status = GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED;
break;
case RESULT_UNKNOWN:
return null;
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index fdef31f..8d21928 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -16,7 +16,7 @@
package com.android.server.location;
-import android.location.GnssNavigationMessageEvent;
+import android.location.GnssNavigationMessage;
import android.location.IGnssNavigationMessageListener;
import android.os.Handler;
import android.os.RemoteException;
@@ -37,7 +37,7 @@
super(handler, TAG);
}
- public void onNavigationMessageAvailable(final GnssNavigationMessageEvent event) {
+ public void onNavigationMessageAvailable(final GnssNavigationMessage event) {
ListenerOperation<IGnssNavigationMessageListener> operation =
new ListenerOperation<IGnssNavigationMessageListener>() {
@Override
@@ -65,16 +65,15 @@
int status;
switch (result) {
case RESULT_SUCCESS:
- status = GnssNavigationMessageEvent.STATUS_READY;
+ status = GnssNavigationMessage.Callback.STATUS_READY;
break;
case RESULT_NOT_AVAILABLE:
case RESULT_NOT_SUPPORTED:
case RESULT_INTERNAL_ERROR:
- status = GnssNavigationMessageEvent.STATUS_NOT_SUPPORTED;
+ status = GnssNavigationMessage.Callback.STATUS_NOT_SUPPORTED;
break;
case RESULT_GPS_LOCATION_DISABLED:
- status = GnssNavigationMessageEvent
- .STATUS_GNSS_LOCATION_DISABLED;
+ status = GnssNavigationMessage.Callback.STATUS_LOCATION_DISABLED;
break;
case RESULT_UNKNOWN:
return null;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index e3c540a5..a4d2cd2 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -962,6 +962,7 @@
mKeyEventReceiver.aquireWakeLockLocked();
}
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
try {
if (user.mLastMediaButtonReceiver != null) {
@@ -986,6 +987,7 @@
}
// Fallback to legacy behavior
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+ keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
if (needWakeLock) {
keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED,
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index 68dc715..959a823 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -23,6 +23,8 @@
import java.io.IOException;
import java.util.HashSet;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+
/**
* Identity of a {@code iface}, defined by the set of {@link NetworkIdentity}
* active on that interface.
@@ -34,6 +36,7 @@
private static final int VERSION_INIT = 1;
private static final int VERSION_ADD_ROAMING = 2;
private static final int VERSION_ADD_NETWORK_ID = 3;
+ private static final int VERSION_ADD_METERED = 4;
public NetworkIdentitySet() {
}
@@ -61,12 +64,22 @@
roaming = false;
}
- add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming));
+ final boolean metered;
+ if (version >= VERSION_ADD_METERED) {
+ metered = in.readBoolean();
+ } else {
+ // If this is the old data and the type is mobile, treat it as metered. (Note that
+ // if this is a mobile network, TYPE_MOBILE is the only possible type that could be
+ // used.)
+ metered = (type == TYPE_MOBILE);
+ }
+
+ add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered));
}
}
public void writeToStream(DataOutputStream out) throws IOException {
- out.writeInt(VERSION_ADD_NETWORK_ID);
+ out.writeInt(VERSION_ADD_METERED);
out.writeInt(size());
for (NetworkIdentity ident : this) {
out.writeInt(ident.getType());
@@ -74,6 +87,7 @@
writeOptionalString(out, ident.getSubscriberId());
writeOptionalString(out, ident.getNetworkId());
out.writeBoolean(ident.getRoaming());
+ out.writeBoolean(ident.getMetered());
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 612bae2..c248608 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -940,7 +940,7 @@
for (int subId : subIds) {
final String subscriberId = tele.getSubscriberId(subId);
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
- TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
if (template.matches(probeIdent)) {
return true;
}
@@ -1333,7 +1333,7 @@
private void ensureActiveMobilePolicyLocked(String subscriberId) {
// Poke around to see if we already have a policy
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
- TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
final NetworkTemplate template = mNetworkPolicy.keyAt(i);
if (template.matches(probeIdent)) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 99c41ea..f20d0a1 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -30,8 +30,11 @@
import static android.service.notification.NotificationRankerService.REASON_PACKAGE_CHANGED;
import static android.service.notification.NotificationRankerService.REASON_PACKAGE_SUSPENDED;
import static android.service.notification.NotificationRankerService.REASON_PROFILE_TURNED_OFF;
+import static android.service.notification.NotificationRankerService.REASON_UNAUTOBUNDLED;
import static android.service.notification.NotificationRankerService.REASON_USER_STOPPED;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS;
import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
import static android.service.notification.NotificationListenerService.TRIM_FULL;
@@ -39,8 +42,6 @@
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_NONE;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
import android.annotation.Nullable;
@@ -97,6 +98,7 @@
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
+import android.service.notification.Adjustment;
import android.service.notification.Condition;
import android.service.notification.IConditionProvider;
import android.service.notification.INotificationListener;
@@ -114,6 +116,7 @@
import android.util.AtomicFile;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.Xml;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -136,7 +139,6 @@
import libcore.io.IoUtils;
-import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
@@ -158,7 +160,6 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -248,8 +249,9 @@
private String mSoundNotificationKey;
private String mVibrateNotificationKey;
- private final ArraySet<ManagedServiceInfo> mListenersDisablingEffects = new ArraySet<>();
- private ComponentName mEffectsSuppressor;
+ private final SparseArray<ArraySet<ManagedServiceInfo>> mListenersDisablingEffects =
+ new SparseArray<ArraySet<ManagedServiceInfo>>();
+ private List<ComponentName> mEffectsSuppressors = new ArrayList<ComponentName>();
private int mListenerHints; // right now, all hints are global
private int mInterruptionFilter = NotificationListenerService.INTERRUPTION_FILTER_UNKNOWN;
@@ -263,6 +265,7 @@
new ArrayList<NotificationRecord>();
final ArrayMap<String, NotificationRecord> mNotificationsByKey =
new ArrayMap<String, NotificationRecord>();
+ final ArrayMap<String, String> mAutobundledSummaries = new ArrayMap<>();
final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>();
final ArrayMap<String, NotificationRecord> mSummaryByGroupKey = new ArrayMap<>();
final PolicyAccess mPolicyAccess = new PolicyAccess();
@@ -283,11 +286,6 @@
private static final String TAG_NOTIFICATION_POLICY = "notification-policy";
private static final String ATTR_VERSION = "version";
- // Obsolete: converted if present, but not resaved to disk.
- private static final String TAG_BLOCKED_PKGS = "blocked-packages";
- private static final String TAG_PACKAGE = "package";
- private static final String ATTR_NAME = "name";
-
private RankingHelper mRankingHelper;
private final UserProfiles mUserProfiles = new UserProfiles();
@@ -1118,23 +1116,112 @@
}
private void updateListenerHintsLocked() {
- final int hints = mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS;
+ final int hints = calculateHints();
if (hints == mListenerHints) return;
- ZenLog.traceListenerHintsChanged(mListenerHints, hints, mListenersDisablingEffects.size());
+ ZenLog.traceListenerHintsChanged(mListenerHints, hints, mEffectsSuppressors.size());
mListenerHints = hints;
scheduleListenerHintsChanged(hints);
}
private void updateEffectsSuppressorLocked() {
- final ComponentName suppressor = !mListenersDisablingEffects.isEmpty()
- ? mListenersDisablingEffects.valueAt(0).component : null;
- if (Objects.equals(suppressor, mEffectsSuppressor)) return;
- ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressor, suppressor);
- mEffectsSuppressor = suppressor;
- mZenModeHelper.setEffectsSuppressed(suppressor != null);
+ final long updatedSuppressedEffects = calculateSuppressedEffects();
+ if (updatedSuppressedEffects == mZenModeHelper.getSuppressedEffects()) return;
+ final List<ComponentName> suppressors = getSuppressors();
+ ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressors, suppressors, updatedSuppressedEffects);
+ mEffectsSuppressors = suppressors;
+ mZenModeHelper.setSuppressedEffects(updatedSuppressedEffects);
sendRegisteredOnlyBroadcast(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
}
+ private ArrayList<ComponentName> getSuppressors() {
+ ArrayList<ComponentName> names = new ArrayList<ComponentName>();
+ for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
+ ArraySet<ManagedServiceInfo> serviceInfoList = mListenersDisablingEffects.valueAt(i);
+
+ for (ManagedServiceInfo info : serviceInfoList) {
+ names.add(info.component);
+ }
+ }
+
+ return names;
+ }
+
+ private boolean removeDisabledHints(ManagedServiceInfo info) {
+ return removeDisabledHints(info, 0);
+ }
+
+ private boolean removeDisabledHints(ManagedServiceInfo info, int hints) {
+ boolean removed = false;
+
+ for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
+ final int hint = mListenersDisablingEffects.keyAt(i);
+ final ArraySet<ManagedServiceInfo> listeners =
+ mListenersDisablingEffects.valueAt(i);
+
+ if (hints == 0 || (hint & hints) == hint) {
+ removed = removed || listeners.remove(info);
+ }
+ }
+
+ return removed;
+ }
+
+ private void addDisabledHints(ManagedServiceInfo info, int hints) {
+ if ((hints & HINT_HOST_DISABLE_EFFECTS) != 0) {
+ addDisabledHint(info, HINT_HOST_DISABLE_EFFECTS);
+ }
+
+ if ((hints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) {
+ addDisabledHint(info, HINT_HOST_DISABLE_NOTIFICATION_EFFECTS);
+ }
+
+ if ((hints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) {
+ addDisabledHint(info, HINT_HOST_DISABLE_CALL_EFFECTS);
+ }
+ }
+
+ private void addDisabledHint(ManagedServiceInfo info, int hint) {
+ if (mListenersDisablingEffects.indexOfKey(hint) < 0) {
+ mListenersDisablingEffects.put(hint, new ArraySet<ManagedServiceInfo>());
+ }
+
+ ArraySet<ManagedServiceInfo> hintListeners = mListenersDisablingEffects.get(hint);
+ hintListeners.add(info);
+ }
+
+ private int calculateHints() {
+ int hints = 0;
+ for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
+ int hint = mListenersDisablingEffects.keyAt(i);
+ ArraySet<ManagedServiceInfo> serviceInfoList = mListenersDisablingEffects.valueAt(i);
+
+ if (!serviceInfoList.isEmpty()) {
+ hints |= hint;
+ }
+ }
+
+ return hints;
+ }
+
+ private long calculateSuppressedEffects() {
+ int hints = calculateHints();
+ long suppressedEffects = 0;
+
+ if ((hints & HINT_HOST_DISABLE_EFFECTS) != 0) {
+ suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_ALL;
+ }
+
+ if ((hints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) {
+ suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_NOTIFICATIONS;
+ }
+
+ if ((hints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) {
+ suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_CALLS;
+ }
+
+ return suppressedEffects;
+ }
+
private void updateInterruptionFilterLocked() {
int interruptionFilter = mZenModeHelper.getZenModeListenerInterruptionFilter();
if (interruptionFilter == mInterruptionFilter) return;
@@ -1259,10 +1346,13 @@
checkCallerIsSystemOrSameApp(pkg);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
- // Don't allow client applications to cancel foreground service notis.
+ // Don't allow client applications to cancel foreground service notis or autobundled
+ // summaries.
cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
- Binder.getCallingUid() == Process.SYSTEM_UID
- ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId,
+ (Binder.getCallingUid() == Process.SYSTEM_UID
+ ? 0 : Notification.FLAG_FOREGROUND_SERVICE)
+ | (Binder.getCallingUid() == Process.SYSTEM_UID
+ ? 0 : Notification.FLAG_AUTOGROUP_SUMMARY), false, userId,
REASON_APP_CANCEL, null);
}
@@ -1404,7 +1494,9 @@
final int N = mNotificationList.size();
for (int i = 0; i < N; i++) {
final StatusBarNotification sbn = mNotificationList.get(i).sbn;
- if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) {
+ if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId
+ && (sbn.getNotification().flags
+ & Notification.FLAG_AUTOGROUP_SUMMARY) != 0) {
// We could pass back a cloneLight() but clients might get confused and
// try to send this thing back to notify() again, which would not work
// very well.
@@ -1519,7 +1611,8 @@
checkCallerIsSystemOrSameApp(component.getPackageName());
long identity = Binder.clearCallingIdentity();
try {
- ManagedServices manager = mRankerServices.isComponentEnabledForCurrentProfiles(component)
+ ManagedServices manager =
+ mRankerServices.isComponentEnabledForCurrentProfiles(component)
? mRankerServices
: mListeners;
manager.setComponentState(component, true);
@@ -1651,11 +1744,14 @@
try {
synchronized (mNotificationList) {
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- final boolean disableEffects = (hints & HINT_HOST_DISABLE_EFFECTS) != 0;
+ final int disableEffectsMask = HINT_HOST_DISABLE_EFFECTS
+ | HINT_HOST_DISABLE_NOTIFICATION_EFFECTS
+ | HINT_HOST_DISABLE_CALL_EFFECTS;
+ final boolean disableEffects = (hints & disableEffectsMask) != 0;
if (disableEffects) {
- mListenersDisablingEffects.add(info);
+ addDisabledHints(info, hints);
} else {
- mListenersDisablingEffects.remove(info);
+ removeDisabledHints(info, hints);
}
updateListenerHintsLocked();
updateEffectsSuppressorLocked();
@@ -1913,7 +2009,7 @@
@Override
public ComponentName getEffectsSuppressor() {
enforceSystemOrSystemUIOrVolume("INotificationManager.getEffectsSuppressor");
- return mEffectsSuppressor;
+ return mEffectsSuppressors.get(0);
}
@Override
@@ -2035,25 +2131,123 @@
}
@Override
- public void setImportanceFromRankerService(INotificationListener token, String key,
- int importance, CharSequence explanation) throws RemoteException {
- if (importance == IMPORTANCE_NONE) {
- throw new IllegalArgumentException("blocking not allowed: key=" + key);
- }
+ public void applyAdjustmentFromRankerService(INotificationListener token,
+ Adjustment adjustment) throws RemoteException {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationList) {
mRankerServices.checkServiceTokenLocked(token);
- NotificationRecord n = mNotificationsByKey.get(key);
- n.setImportance(importance, explanation);
- mRankingHandler.requestSort();
+ applyAdjustmentLocked(adjustment);
}
+ maybeAddAutobundleSummary(adjustment);
+ mRankingHandler.requestSort();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void applyAdjustmentsFromRankerService(INotificationListener token,
+ List<Adjustment> adjustments) throws RemoteException {
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mNotificationList) {
+ mRankerServices.checkServiceTokenLocked(token);
+ for (Adjustment adjustment : adjustments) {
+ applyAdjustmentLocked(adjustment);
+ }
+ }
+ for (Adjustment adjustment : adjustments) {
+ maybeAddAutobundleSummary(adjustment);
+ }
+ mRankingHandler.requestSort();
} finally {
Binder.restoreCallingIdentity(identity);
}
}
};
+ private void applyAdjustmentLocked(Adjustment adjustment) {
+ maybeClearAutobundleSummaryLocked(adjustment);
+ NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
+ if (n == null) {
+ return;
+ }
+ if (adjustment.getImportance() != IMPORTANCE_NONE) {
+ n.setImportance(adjustment.getImportance(), adjustment.getExplanation());
+ }
+ if (adjustment.getSignals() != null) {
+ Bundle.setDefusable(adjustment.getSignals(), true);
+ n.sbn.setOverrideGroupKey(adjustment.getSignals().getString(
+ Adjustment.GROUP_KEY_OVERRIDE_KEY, null));
+ }
+ }
+
+ // Clears the 'fake' auto-bunding summary.
+ private void maybeClearAutobundleSummaryLocked(Adjustment adjustment) {
+ if (adjustment.getSignals() != null
+ && adjustment.getSignals().containsKey(Adjustment.NEEDS_AUTOGROUPING_KEY)
+ && !adjustment.getSignals().getBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false)) {
+ if (mAutobundledSummaries.containsKey(adjustment.getPackage())) {
+ // Clear summary.
+ final NotificationRecord removed = mNotificationsByKey.get(
+ mAutobundledSummaries.remove(adjustment.getPackage()));
+ if (removed != null) {
+ mNotificationList.remove(removed);
+ cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED);
+ }
+ }
+ }
+ }
+
+ // Posts a 'fake' summary for a package that has exceeded the solo-notification limit.
+ private void maybeAddAutobundleSummary(Adjustment adjustment) {
+ if (adjustment.getSignals() != null
+ && adjustment.getSignals().getBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false)) {
+ final String newAutoBundleKey =
+ adjustment.getSignals().getString(Adjustment.GROUP_KEY_OVERRIDE_KEY, null);
+ int userId = -1;
+ NotificationRecord summaryRecord = null;
+ synchronized (mNotificationList) {
+ if (!mAutobundledSummaries.containsKey(adjustment.getPackage())
+ && newAutoBundleKey != null) {
+ // Add summary
+ final StatusBarNotification adjustedSbn
+ = mNotificationsByKey.get(adjustment.getKey()).sbn;
+
+ final ApplicationInfo appInfo =
+ adjustedSbn.getNotification().extras.getParcelable(
+ Notification.EXTRA_BUILDER_APPLICATION_INFO);
+ final Bundle extras = new Bundle();
+ extras.putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, appInfo);
+ final Notification summaryNotification =
+ new Notification.Builder(getContext()).setSmallIcon(
+ adjustedSbn.getNotification().getSmallIcon())
+ .setGroupSummary(true)
+ .setGroup(newAutoBundleKey)
+ .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true)
+ .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
+ .build();
+ summaryNotification.extras.putAll(extras);
+ final StatusBarNotification summarySbn =
+ new StatusBarNotification(adjustedSbn.getPackageName(),
+ adjustedSbn.getOpPkg(),
+ Integer.MAX_VALUE, Adjustment.GROUP_KEY_OVERRIDE_KEY,
+ adjustedSbn.getUid(), adjustedSbn.getInitialPid(),
+ summaryNotification, adjustedSbn.getUser(), newAutoBundleKey,
+ System.currentTimeMillis());
+ summaryRecord = new NotificationRecord(getContext(), summarySbn);
+ mAutobundledSummaries.put(adjustment.getPackage(), summarySbn.getKey());
+ userId = adjustedSbn.getUser().getIdentifier();
+ }
+ }
+ if (summaryRecord != null) {
+ mHandler.post(new EnqueueNotificationRunnable(userId, summaryRecord));
+ }
+ }
+ }
+
private String disableNotificationEffects(NotificationRecord record) {
if (mDisableNotificationEffects) {
return "booleanState";
@@ -2175,9 +2369,19 @@
pw.print(" mListenersDisablingEffects: (");
N = mListenersDisablingEffects.size();
for (int i = 0; i < N; i++) {
- final ManagedServiceInfo listener = mListenersDisablingEffects.valueAt(i);
- if (i > 0) pw.print(',');
- pw.print(listener.component);
+ final int hint = mListenersDisablingEffects.keyAt(i);
+ if (i > 0) pw.print(';');
+ pw.print("hint[" + hint + "]:");
+
+ final ArraySet<ManagedServiceInfo> listeners =
+ mListenersDisablingEffects.valueAt(i);
+ final int listenerSize = listeners.size();
+
+ for (int j = 0; j < listenerSize; j++) {
+ if (i > 0) pw.print(',');
+ final ManagedServiceInfo listener = listeners.valueAt(i);
+ pw.print(listener.component);
+ }
}
pw.println(')');
pw.println("\n mRankerServicePackageName: " + mRankerServicePackageName);
@@ -2253,6 +2457,17 @@
callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
final UserHandle user = new UserHandle(userId);
+ // Fix the notification as best we can.
+ try {
+ Notification.addFieldsFromContext(getContext().createApplicationContext(
+ getContext().getPackageManager().getApplicationInfoAsUser(
+ pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId),
+ Context.CONTEXT_RESTRICTED), notification);
+ } catch (NameNotFoundException e) {
+ Slog.e(TAG, "Cannot create a context for sending app", e);
+ return;
+ }
+
// Limit the number of notifications that any given package except the android
// package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemNotification && !isNotificationFromListener) {
@@ -2492,7 +2707,7 @@
StatusBarNotification sbn = r.sbn;
String group = sbn.getGroupKey();
boolean isSummary = sbn.getNotification().isGroupSummary();
- boolean isChild = sbn.getNotification().isGroupChild();
+ boolean isChild = !isSummary && sbn.isGroup();
NotificationRecord summary = mSummaryByGroupKey.get(group);
if (isChild && summary != null) {
@@ -2857,11 +3072,13 @@
synchronized (mNotificationList) {
final int N = mNotificationList.size();
ArrayList<String> orderBefore = new ArrayList<String>(N);
+ ArrayList<String> groupOverrideBefore = new ArrayList<>(N);
int[] visibilities = new int[N];
- int [] importances = new int[N];
+ int[] importances = new int[N];
for (int i = 0; i < N; i++) {
final NotificationRecord r = mNotificationList.get(i);
orderBefore.add(r.getKey());
+ groupOverrideBefore.add(r.sbn.getGroupKey());
visibilities[i] = r.getPackageVisibilityOverride();
importances[i] = r.getImportance();
mRankingHelper.extractSignals(r);
@@ -2871,7 +3088,8 @@
final NotificationRecord r = mNotificationList.get(i);
if (!orderBefore.get(i).equals(r.getKey())
|| visibilities[i] != r.getPackageVisibilityOverride()
- || importances[i] != r.getImportance()) {
+ || importances[i] != r.getImportance()
+ || !groupOverrideBefore.get(i).equals(r.sbn.getGroupKey())) {
scheduleSendRankingUpdate();
return;
}
@@ -3070,6 +3288,7 @@
mLights.remove(canceledKey);
// Record usage stats
+ // TODO: add unbundling stats?
switch (reason) {
case REASON_DELEGATE_CANCEL:
case REASON_DELEGATE_CANCEL_ALL:
@@ -3089,6 +3308,9 @@
if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
mSummaryByGroupKey.remove(groupKey);
}
+ if (r.sbn.getKey().equals(mAutobundledSummaries.get(r.sbn.getPackageName()))) {
+ mAutobundledSummaries.remove(r.sbn.getPackageName());
+ }
// Save it for users of getHistoricalNotifications()
mArchive.record(r.sbn);
@@ -3287,7 +3509,7 @@
for (int i = N - 1; i >= 0; i--) {
NotificationRecord childR = mNotificationList.get(i);
StatusBarNotification childSbn = childR.sbn;
- if (childR.getNotification().isGroupChild() &&
+ if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
childR.getGroupKey().equals(r.getGroupKey())) {
EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
childSbn.getTag(), userId, 0, 0, reason, listenerName);
@@ -3438,6 +3660,7 @@
ArrayList<String> keys = new ArrayList<String>(N);
ArrayList<String> interceptedKeys = new ArrayList<String>(N);
ArrayList<Integer> importance = new ArrayList<>(N);
+ Bundle overrideGroupKeys = new Bundle();
Bundle visibilityOverrides = new Bundle();
Bundle suppressedVisualEffects = new Bundle();
Bundle explanation = new Bundle();
@@ -3461,6 +3684,7 @@
!= NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
visibilityOverrides.putInt(key, record.getPackageVisibilityOverride());
}
+ overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey());
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
@@ -3470,7 +3694,7 @@
importanceAr[i] = importance.get(i);
}
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
- suppressedVisualEffects, importanceAr, explanation);
+ suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys);
}
private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
@@ -3690,7 +3914,7 @@
@Override
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
- if (mListenersDisablingEffects.remove(removed)) {
+ if (removeDisabledHints(removed)) {
updateListenerHintsLocked();
updateEffectsSuppressorLocked();
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index fd893fa..a89a422 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -24,18 +24,15 @@
import android.app.Notification;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.media.AudioAttributes;
-import android.os.Build;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.EventLogTags;
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index c45071b..207bdba 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -31,6 +31,7 @@
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
public class ZenLog {
private static final String TAG = "ZenLog";
@@ -126,10 +127,11 @@
append(TYPE_DISABLE_EFFECTS, record.getKey() + "," + reason);
}
- public static void traceEffectsSuppressorChanged(ComponentName oldSuppressor,
- ComponentName newSuppressor) {
- append(TYPE_SUPPRESSOR_CHANGED, componentToString(oldSuppressor) + "->"
- + componentToString(newSuppressor));
+ public static void traceEffectsSuppressorChanged(List<ComponentName> oldSuppressors,
+ List<ComponentName> newSuppressors, long suppressedEffects) {
+ append(TYPE_SUPPRESSOR_CHANGED, "suppressed effects:" + suppressedEffects + ","
+ + componentListToString(oldSuppressors) + "->"
+ + componentListToString(newSuppressors));
}
public static void traceListenerHintsChanged(int oldHints, int newHints, int listenerCount) {
@@ -193,6 +195,19 @@
return component != null ? component.toShortString() : null;
}
+ private static String componentListToString(List<ComponentName> components) {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ for (int i = 0; i < components.size(); ++i) {
+ if (i > 0) {
+ stringBuilder.append(", ");
+ }
+ stringBuilder.append(componentToString(components.get(i)));
+ }
+
+ return stringBuilder.toString();
+ }
+
private static void append(int type, String msg) {
synchronized(MSGS) {
TIMES[sNext] = System.currentTimeMillis();
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 5c5c8f8..eb49e9f 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -102,7 +102,12 @@
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
private PackageManager mPm;
- private boolean mEffectsSuppressed;
+ private long mSuppressedEffects;
+
+ public static final long SUPPRESSED_EFFECT_NOTIFICATIONS = 1;
+ public static final long SUPPRESSED_EFFECT_CALLS = 1 << 1;
+ public static final long SUPPRESSED_EFFECT_ALL = SUPPRESSED_EFFECT_CALLS
+ | SUPPRESSED_EFFECT_NOTIFICATIONS;
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
mContext = context;
@@ -228,12 +233,16 @@
}
}
- public void setEffectsSuppressed(boolean effectsSuppressed) {
- if (mEffectsSuppressed == effectsSuppressed) return;
- mEffectsSuppressed = effectsSuppressed;
+ public void setSuppressedEffects(long suppressedEffects) {
+ if (mSuppressedEffects == suppressedEffects) return;
+ mSuppressedEffects = suppressedEffects;
applyRestrictions();
}
+ public long getSuppressedEffects() {
+ return mSuppressedEffects;
+ }
+
public int getZenMode() {
return mZenMode;
}
@@ -484,7 +493,8 @@
synchronized (mConfig) {
dump(pw, prefix, "mConfig", mConfig);
}
- pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
+
+ pw.print(prefix); pw.print("mSuppressedEffects="); pw.println(mSuppressedEffects);
mFiltering.dump(pw, prefix);
mConditions.dump(pw, prefix);
}
@@ -708,9 +718,11 @@
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
// notification restrictions
- final boolean muteNotifications = mEffectsSuppressed;
+ final boolean muteNotifications =
+ (mSuppressedEffects & SUPPRESSED_EFFECT_NOTIFICATIONS) != 0;
// call restrictions
- final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers;
+ final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
+ || (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0;
// total silence restrictions
final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 7e25632..a11ee74 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -28,6 +28,8 @@
import dalvik.system.VMRuntime;
+import java.util.Arrays;
+
public final class Installer extends SystemService {
private static final String TAG = "Installer";
@@ -90,14 +92,14 @@
mInstaller.execute("migrate_app_data", uuid, pkgname, userid, flags);
}
- public void clearAppData(String uuid, String pkgname, int userid, int flags)
+ public void clearAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)
throws InstallerException {
- mInstaller.execute("clear_app_data", uuid, pkgname, userid, flags);
+ mInstaller.execute("clear_app_data", uuid, pkgname, userid, flags, ceDataInode);
}
- public void destroyAppData(String uuid, String pkgname, int userid, int flags)
+ public void destroyAppData(String uuid, String pkgname, int userid, int flags, long ceDataInode)
throws InstallerException {
- mInstaller.execute("destroy_app_data", uuid, pkgname, userid, flags);
+ mInstaller.execute("destroy_app_data", uuid, pkgname, userid, flags, ceDataInode);
}
public void moveCompleteApp(String from_uuid, String to_uuid, String package_name,
@@ -107,31 +109,26 @@
data_app_name, appid, seinfo, targetSdkVersion);
}
- public void getAppSize(String uuid, String pkgname, int userid, int flags, String apkPath,
- String libDirPath, String fwdLockApkPath, String asecPath, String[] instructionSets,
- PackageStats pStats) throws InstallerException {
- for (String instructionSet : instructionSets) {
- assertValidInstructionSet(instructionSet);
- }
-
- // TODO: Extend getSizeInfo to look at the full subdirectory tree,
- // not just the first level.
- // TODO: Extend getSizeInfo to look at *all* instrution sets, not
- // just the primary.
- final String rawRes = mInstaller.executeForResult("get_app_size", uuid, pkgname, userid,
- flags, apkPath, libDirPath, fwdLockApkPath, asecPath, instructionSets[0]);
- final String res[] = rawRes.split(" ");
-
- if ((res == null) || (res.length != 5)) {
- throw new InstallerException("Invalid size result: " + rawRes);
- }
+ public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode,
+ String codePath, PackageStats stats) throws InstallerException {
+ final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags,
+ ceDataInode, codePath);
try {
- pStats.codeSize = Long.parseLong(res[1]);
- pStats.dataSize = Long.parseLong(res[2]);
- pStats.cacheSize = Long.parseLong(res[3]);
- pStats.externalCodeSize = Long.parseLong(res[4]);
- } catch (NumberFormatException e) {
- throw new InstallerException("Invalid size result: " + rawRes);
+ stats.codeSize += Long.parseLong(res[1]);
+ stats.dataSize += Long.parseLong(res[2]);
+ stats.cacheSize += Long.parseLong(res[3]);
+ } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
+ throw new InstallerException("Invalid size result: " + Arrays.toString(res));
+ }
+ }
+
+ public long getAppDataInode(String uuid, String pkgname, int userid, int flags)
+ throws InstallerException {
+ final String[] res = mInstaller.execute("get_app_data_inode", uuid, pkgname, userid, flags);
+ try {
+ return Long.parseLong(res[1]);
+ } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
+ throw new InstallerException("Invalid inode result: " + Arrays.toString(res));
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 928c19f..8368185 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -862,8 +862,12 @@
IntentSender statusReceiver, int userId) {
final int callingUid = Binder.getCallingUid();
mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
+ boolean allowSilentUninstall = true;
if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
mAppOps.checkPackage(callingUid, callerPackageName);
+ final String installerPackageName = mPm.getInstallerPackageName(packageName);
+ allowSilentUninstall = installerPackageName != null
+ && installerPackageName.equals(callerPackageName);
}
// Check whether the caller is device owner, in which case we do it silently.
@@ -874,8 +878,8 @@
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
statusReceiver, packageName, isDeviceOwner, userId);
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
- == PackageManager.PERMISSION_GRANTED) {
+ if (allowSilentUninstall && mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) {
// Sweet, call straight through!
mPm.deletePackage(packageName, adapter.getBinder(), userId, flags);
} else if (isDeviceOwner) {
@@ -901,7 +905,10 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, TAG);
synchronized (mSessions) {
- mSessions.get(sessionId).setPermissionsResult(accepted);
+ PackageInstallerSession session = mSessions.get(sessionId);
+ if (session != null) {
+ session.setPermissionsResult(accepted);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ef53905..6cdc40f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -81,6 +81,7 @@
import java.io.FileDescriptor;
import java.io.FileFilter;
import java.io.IOException;
+import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -151,6 +152,7 @@
private String mPackageName;
private int mVersionCode;
private Signature[] mSignatures;
+ private Certificate[][] mCertificates;
/**
* Path to the validated base APK for this session, which may point at an
@@ -633,7 +635,7 @@
mRelinquished = true;
mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params,
- installerPackageName, installerUid, user);
+ installerPackageName, installerUid, user, mCertificates);
}
/**
@@ -695,6 +697,7 @@
}
if (mSignatures == null) {
mSignatures = apk.signatures;
+ mCertificates = apk.certificates;
}
assertApkConsistent(String.valueOf(addedFile), apk);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 31eac1f..ddccbb3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -76,7 +76,6 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
import static android.content.pm.PackageParser.isApkFile;
-import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
@@ -117,7 +116,6 @@
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.IntentFilter.AuthorityEntry;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
@@ -150,7 +148,6 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ActivityIntentInfo;
-import android.content.pm.PackageParser.IntentInfo;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageStats;
@@ -250,6 +247,7 @@
import com.android.server.pm.Settings.VersionInfo;
import com.android.server.storage.DeviceStorageMonitorInternal;
+import dalvik.system.CloseGuard;
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
@@ -278,6 +276,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
+import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
@@ -300,14 +299,37 @@
import java.util.concurrent.atomic.AtomicLong;
/**
- * Keep track of all those .apks everywhere.
+ * Keep track of all those APKs everywhere.
+ * <p>
+ * Internally there are two important locks:
+ * <ul>
+ * <li>{@link #mPackages} is used to guard all in-memory parsed package details
+ * and other related state. It is a fine-grained lock that should only be held
+ * momentarily, as it's one of the most contended locks in the system.
+ * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
+ * operations typically involve heavy lifting of application data on disk. Since
+ * {@code installd} is single-threaded, and it's operations can often be slow,
+ * this lock should never be acquired while already holding {@link #mPackages}.
+ * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
+ * holding {@link #mInstallLock}.
+ * </ul>
+ * Many internal methods rely on the caller to hold the appropriate locks, and
+ * this contract is expressed through method name suffixes:
+ * <ul>
+ * <li>fooLI(): the caller must hold {@link #mInstallLock}
+ * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
+ * being modified must be frozen
+ * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
+ * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
+ * </ul>
+ * <p>
+ * Because this class is very central to the platform's security; please run all
+ * CTS and unit tests whenever making modifications:
*
- * This is very central to the platform's security; please run the unit
- * tests whenever making modifications here:
- *
-runtest -c android.content.pm.PackageManagerTests frameworks-core
- *
- * {@hide}
+ * <pre>
+ * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
+ * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
+ * </pre>
*/
public class PackageManagerService extends IPackageManager.Stub {
static final String TAG = "PackageManager";
@@ -369,6 +391,7 @@
static final int SCAN_INITIAL = 1<<14;
static final int SCAN_CHECK_ONLY = 1<<15;
static final int SCAN_DONT_KILL_APP = 1<<17;
+ static final int SCAN_IGNORE_FROZEN = 1<<18;
static final int REMOVE_CHATTY = 1<<16;
@@ -572,7 +595,19 @@
*/
boolean mPromoteSystemApps;
+ @GuardedBy("mPackages")
final Settings mSettings;
+
+ /**
+ * Set of package names that are currently "frozen", which means active
+ * surgery is being done on the code/data for that package. The platform
+ * will refuse to launch frozen packages to avoid race conditions.
+ *
+ * @see PackageFreezer
+ */
+ @GuardedBy("mPackages")
+ final ArraySet<String> mFrozenPackages = new ArraySet<>();
+
boolean mRestoredSettings;
// System configuration read by SystemConfig.
@@ -1065,8 +1100,9 @@
| FLAG_PERMISSION_REVOKE_ON_UPGRADE;
final @Nullable String mRequiredVerifierPackage;
- final @Nullable String mRequiredInstallerPackage;
+ final @NonNull String mRequiredInstallerPackage;
final @Nullable String mSetupWizardPackage;
+ final @NonNull String mServicesSystemSharedLibraryPackageName;
private final PackageUsage mPackageUsage = new PackageUsage();
@@ -2352,8 +2388,9 @@
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
logCriticalInfo(Log.WARN, "System package " + ps.name
- + " no longer exists; wiping its data");
- removeDataDirsLI(null, ps.name);
+ + " no longer exists; it's data will be wiped");
+ // Actual deletion of code and data will be handled by later
+ // reconciliation step
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
@@ -2365,11 +2402,16 @@
//look for any incomplete package installations
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
- //clean up list
- for(int i = 0; i < deletePkgsList.size(); i++) {
- //clean up here
- cleanupInstallFailedPackage(deletePkgsList.get(i));
+ for (int i = 0; i < deletePkgsList.size(); i++) {
+ // Actual deletion of code and data will be handled by later
+ // reconciliation step
+ final String packageName = deletePkgsList.get(i).name;
+ logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
+ synchronized (mPackages) {
+ mSettings.removePackageLPw(packageName);
+ }
}
+
//delete tmp files
deleteTempPackageFiles();
@@ -2400,8 +2442,9 @@
String msg;
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName
- + " no longer exists; wiping its data";
- removeDataDirsLI(null, deletedAppName);
+ + " no longer exists; it's data will be wiped";
+ // Actual deletion of code and data will be handled by later
+ // reconciliation step
} else {
msg = "Updated system app + " + deletedAppName
+ " no longer present; removing system privileges for "
@@ -2547,7 +2590,7 @@
} else {
storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
}
- reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
+ reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
storageFlags);
// If this is first boot after an OTA, and a normal boot, then
@@ -2557,8 +2600,12 @@
for (int i = 0; i < mSettings.mPackages.size(); i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
- deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
+ // No apps are running this early, so no need to freeze
+ clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
+ | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
+ clearAppProfilesLIF(ps.pkg);
}
ver.fingerprint = Build.FINGERPRINT;
}
@@ -2584,11 +2631,16 @@
mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
mIntentFilterVerifier = new IntentVerifierProxy(mContext,
mIntentFilterVerifierComponent);
+ mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
+ PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
+ getRequiredSharedLibraryLPr(
+ PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
} else {
mRequiredVerifierPackage = null;
mRequiredInstallerPackage = null;
mIntentFilterVerifierComponent = null;
mIntentFilterVerifier = null;
+ mServicesSystemSharedLibraryPackageName = null;
}
mInstallerService = new PackageInstallerService(context, this);
@@ -2668,6 +2720,16 @@
}
}
+ private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
+ synchronized (mPackages) {
+ SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
+ if (libraryEntry == null) {
+ throw new IllegalStateException("Missing required shared library:" + libraryName);
+ }
+ return libraryEntry.apk;
+ }
+ }
+
private @NonNull String getRequiredInstallerLPr() {
final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
@@ -2677,6 +2739,10 @@
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM);
if (matches.size() == 1) {
+ ResolveInfo resolveInfo = matches.get(0);
+ if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
+ throw new RuntimeException("The installer must be a privileged app");
+ }
return matches.get(0).getComponentInfo().packageName;
} else {
throw new RuntimeException("There must be exactly one installer; found " + matches);
@@ -2923,22 +2989,6 @@
}
}
- void cleanupInstallFailedPackage(PackageSetting ps) {
- logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
-
- removeDataDirsLI(ps.volumeUuid, ps.name);
- if (ps.codePath != null) {
- removeCodePathLI(ps.codePath);
- }
- if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
- if (ps.resourcePath.isDirectory()) {
- FileUtils.deleteContents(ps.resourcePath);
- }
- ps.resourcePath.delete();
- }
- mSettings.removePackageLPw(ps.name);
- }
-
static int[] appendInts(int[] cur, int[] add) {
if (add == null) return cur;
if (cur == null) return add;
@@ -2988,7 +3038,7 @@
throw new SecurityException("Package " + packageName + " not a system app!");
}
- if (ps.frozen) {
+ if (mFrozenPackages.contains(packageName)) {
throw new SecurityException("Package " + packageName + " is currently frozen!");
}
@@ -3037,7 +3087,7 @@
}
if (p == null) {
p = mPackages.get(packageName);
- if (matchFactoryOnly && !isSystemApp(p)) {
+ if (matchFactoryOnly && p != null && !isSystemApp(p)) {
return null;
}
}
@@ -3559,15 +3609,10 @@
}
@Override
- public @Nullable String getServicesSystemSharedLibraryPackageName() {
+ public @NonNull String getServicesSystemSharedLibraryPackageName() {
synchronized (mPackages) {
- SharedLibraryEntry libraryEntry = mSharedLibraries.get(
- PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
- if (libraryEntry != null) {
- return libraryEntry.apk;
- }
+ return mServicesSystemSharedLibraryPackageName;
}
- return null;
}
@Override
@@ -4390,6 +4435,13 @@
}
}
+ /**
+ * This method should typically only be used when granting or revoking
+ * permissions, since the app may immediately restart after this call.
+ * <p>
+ * If you're doing surgery on app code/data, use {@link PackageFreezer} to
+ * guard your work against the app being relaunched.
+ */
private void killUid(int appId, int userId, String reason) {
final long identity = Binder.clearCallingIdentity();
try {
@@ -6787,7 +6839,10 @@
!= PackageManager.SIGNATURE_MATCH) {
logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
+ " signatures don't match existing userdata copy; removing");
- deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null);
+ try (PackageFreezer freezer = freezePackage(pkg.packageName,
+ "scanPackageInternalLI")) {
+ deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
+ }
ps = null;
} else {
/*
@@ -7256,23 +7311,6 @@
return true;
}
- private boolean removeDataDirsLI(String volumeUuid, String packageName) {
- // TODO: triage flags as part of 26466827
- final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
-
- boolean res = true;
- final int[] users = sUserManager.getUserIds();
- for (int user : users) {
- try {
- mInstaller.destroyAppData(volumeUuid, packageName, user, flags);
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed to delete data directory", e);
- res = false;
- }
- }
- return res;
- }
-
void removeCodePathLI(File codePath) {
if (codePath.isDirectory()) {
try {
@@ -7285,87 +7323,106 @@
}
}
- void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) {
- try {
- mInstaller.destroyAppData(volumeUuid, packageName, userId, flags);
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed to destroy app data", e);
- }
+ private int[] resolveUserIds(int userId) {
+ return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
}
- void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags,
- int appId, String seinfo) {
- try {
- mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo);
- } catch (InstallerException e) {
- Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
- }
- }
-
- private void deleteProfilesLI(String packageName, boolean destroy) {
- final PackageParser.Package pkg;
- synchronized (mPackages) {
- pkg = mPackages.get(packageName);
- }
+ private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
if (pkg == null) {
- Slog.w(TAG, "Failed to delete profiles. No package: " + packageName);
+ Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
- deleteProfilesLI(pkg, destroy);
- }
-
- private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) {
- try {
- if (destroy) {
- mInstaller.destroyAppProfiles(pkg.packageName);
- } else {
- mInstaller.clearAppProfiles(pkg.packageName);
- }
- } catch (InstallerException ex) {
- Log.e(TAG, "Could not delete profiles for package " + pkg.packageName);
+ clearAppDataLeafLIF(pkg, userId, flags);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
}
}
- private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
- final PackageParser.Package pkg;
+ private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ final PackageSetting ps;
synchronized (mPackages) {
- pkg = mPackages.get(packageName);
+ ps = mSettings.mPackages.get(pkg.packageName);
}
- if (pkg == null) {
- Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName);
- return;
- }
- deleteCodeCacheDirsLI(pkg);
- }
-
- private void deleteCodeCacheDirsLI(PackageParser.Package pkg) {
- // TODO: triage flags as part of 26466827
- final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
-
- int[] users = sUserManager.getUserIds();
- int res = 0;
- for (int user : users) {
- // Remove the parent code cache
+ for (int realUserId : resolveUserIds(userId)) {
+ final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
try {
- mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user,
- flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
+ ceDataInode);
} catch (InstallerException e) {
- Slog.w(TAG, "Failed to delete code cache directory", e);
+ Slog.w(TAG, String.valueOf(e));
}
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- // Remove the child code cache
- try {
- mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName,
- user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed to delete code cache directory", e);
- }
+ }
+ }
+
+ private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
+ if (pkg == null) {
+ Slog.wtf(TAG, "Package was null!", new Throwable());
+ return;
+ }
+ destroyAppDataLeafLIF(pkg, userId, flags);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
+ }
+ }
+
+ private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ final PackageSetting ps;
+ synchronized (mPackages) {
+ ps = mSettings.mPackages.get(pkg.packageName);
+ }
+ for (int realUserId : resolveUserIds(userId)) {
+ final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
+ try {
+ mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
+ ceDataInode);
+ } catch (InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
}
}
}
+ private void destroyAppProfilesLIF(PackageParser.Package pkg) {
+ if (pkg == null) {
+ Slog.wtf(TAG, "Package was null!", new Throwable());
+ return;
+ }
+ destroyAppProfilesLeafLIF(pkg);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
+ }
+ }
+
+ private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
+ try {
+ mInstaller.destroyAppProfiles(pkg.packageName);
+ } catch (InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
+ }
+ }
+
+ private void clearAppProfilesLIF(PackageParser.Package pkg) {
+ if (pkg == null) {
+ Slog.wtf(TAG, "Package was null!", new Throwable());
+ return;
+ }
+ clearAppProfilesLeafLIF(pkg);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ clearAppProfilesLeafLIF(pkg.childPackages.get(i));
+ }
+ }
+
+ private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
+ try {
+ mInstaller.clearAppProfiles(pkg.packageName);
+ } catch (InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
+ }
+ }
+
private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
long lastUpdateTime) {
// Set parent install/update time
@@ -7551,7 +7608,10 @@
return res;
} finally {
if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
- removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
+ // DELETE_DATA_ON_FAILURES is only used by frozen paths
+ destroyAppDataLIF(pkg, UserHandle.USER_ALL,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ destroyAppProfilesLIF(pkg);
}
}
}
@@ -8108,20 +8168,17 @@
}
}
- // Request the ActivityManager to kill the process(only for existing packages)
- // so that we do not end up in a confused state while the user is still using the older
- // version of the application while the new one gets installed.
- final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0;
- final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
- if (killApp) {
- if (isReplacing) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
-
- killApplication(pkg.applicationInfo.packageName,
- pkg.applicationInfo.uid, "replace pkg");
-
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
+ if ((scanFlags & SCAN_BOOTING) != 0) {
+ // No apps can run during boot scan, so they don't need to be frozen
+ } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
+ // Caller asked to not kill app, so it's probably not frozen
+ } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
+ // Caller asked us to ignore frozen check for some reason; they
+ // probably didn't know the package name
+ } else {
+ // We're doing major surgery on this package, so it better be frozen
+ // right now to keep it from launching
+ checkPackageFrozen(pkgName);
}
// Also need to kill any apps that are dependent on the library.
@@ -8592,7 +8649,7 @@
if (abi32 >= 0) {
final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
if (abi64 >= 0) {
- if (cpuAbiOverride == null && pkg.use32bitAbi) {
+ if (pkg.use32bitAbi) {
pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
pkg.applicationInfo.primaryCpuAbi = abi;
} else {
@@ -8988,27 +9045,21 @@
}
}
- private void killPackage(PackageParser.Package pkg, String reason) {
- // Kill the parent package
- killApplication(pkg.packageName, pkg.applicationInfo.uid, reason);
- // Kill the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason);
- }
- }
-
private void killApplication(String pkgName, int appId, String reason) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
- IActivityManager am = ActivityManagerNative.getDefault();
- if (am != null) {
- try {
- am.killApplicationWithAppId(pkgName, appId, reason);
- } catch (RemoteException e) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ IActivityManager am = ActivityManagerNative.getDefault();
+ if (am != null) {
+ try {
+ am.killApplicationWithAppId(pkgName, appId, reason);
+ } catch (RemoteException e) {
+ }
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -10977,7 +11028,8 @@
null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
- null /*packageAbiOverride*/, null /*grantedPermissions*/);
+ null /*packageAbiOverride*/, null /*grantedPermissions*/,
+ null /*certificates*/);
params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -10991,7 +11043,8 @@
void installStage(String packageName, File stagedDir, String stagedCid,
IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
- String installerPackageName, int installerUid, UserHandle user) {
+ String installerPackageName, int installerUid, UserHandle user,
+ Certificate[][] certificates) {
if (DEBUG_EPHEMERAL) {
if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
Slog.d(TAG, "Ephemeral install of " + packageName);
@@ -11012,7 +11065,7 @@
final InstallParams params = new InstallParams(origin, null, observer,
sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
verificationInfo, user, sessionParams.abiOverride,
- sessionParams.grantedRuntimePermissions);
+ sessionParams.grantedRuntimePermissions, certificates);
params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -11190,7 +11243,10 @@
if (installed) {
if (pkgSetting.pkg != null) {
- prepareAppDataAfterInstall(pkgSetting.pkg);
+ synchronized (mInstallLock) {
+ // We don't need to freeze for a brand new install
+ prepareAppDataAfterInstallLIF(pkgSetting.pkg);
+ }
}
sendPackageAddedForUser(packageName, pkgSetting, userId);
}
@@ -11739,6 +11795,9 @@
// Okay!
targetPackageSetting.installerPackageName = installerPackageName;
+ if (installerPackageName != null) {
+ mSettings.mInstallerPackages.add(installerPackageName);
+ }
scheduleWriteSettingsLocked();
}
}
@@ -12107,11 +12166,12 @@
final String packageAbiOverride;
final String[] grantedRuntimePermissions;
final VerificationInfo verificationInfo;
+ final Certificate[][] certificates;
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
int installFlags, String installerPackageName, String volumeUuid,
VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
- String[] grantedPermissions) {
+ String[] grantedPermissions, Certificate[][] certificates) {
super(user);
this.origin = origin;
this.move = move;
@@ -12122,6 +12182,7 @@
this.verificationInfo = verificationInfo;
this.packageAbiOverride = packageAbiOverride;
this.grantedRuntimePermissions = grantedPermissions;
+ this.certificates = certificates;
}
@Override
@@ -12590,6 +12651,7 @@
/** If non-null, drop an async trace when the install completes */
final String traceMethod;
final int traceCookie;
+ final Certificate[][] certificates;
// The list of instruction sets supported by this app. This is currently
// only used during the rmdex() phase to clean up resources. We can get rid of this
@@ -12600,7 +12662,7 @@
int installFlags, String installerPackageName, String volumeUuid,
UserHandle user, String[] instructionSets,
String abiOverride, String[] installGrantPermissions,
- String traceMethod, int traceCookie) {
+ String traceMethod, int traceCookie, Certificate[][] certificates) {
this.origin = origin;
this.move = move;
this.installFlags = installFlags;
@@ -12613,6 +12675,7 @@
this.installGrantPermissions = installGrantPermissions;
this.traceMethod = traceMethod;
this.traceCookie = traceCookie;
+ this.certificates = certificates;
}
abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
@@ -12705,9 +12768,9 @@
FileInstallArgs(InstallParams params) {
super(params.origin, params.move, params.observer, params.installFlags,
params.installerPackageName, params.volumeUuid,
- params.getUser(), null /* instruction sets */, params.packageAbiOverride,
+ params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
params.grantedRuntimePermissions,
- params.traceMethod, params.traceCookie);
+ params.traceMethod, params.traceCookie, params.certificates);
if (isFwdLocked()) {
throw new IllegalArgumentException("Forward locking only supported in ASEC");
}
@@ -12716,7 +12779,7 @@
/** Existing install */
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
- null, null, null, 0);
+ null, null, null, 0, null /*certificates*/);
this.codeFile = (codePath != null) ? new File(codePath) : null;
this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
}
@@ -12941,15 +13004,15 @@
params.installerPackageName, params.volumeUuid,
params.getUser(), null /* instruction sets */, params.packageAbiOverride,
params.grantedRuntimePermissions,
- params.traceMethod, params.traceCookie);
+ params.traceMethod, params.traceCookie, params.certificates);
}
/** Existing install */
AsecInstallArgs(String fullCodePath, String[] instructionSets,
boolean isExternal, boolean isForwardLocked) {
super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
- | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
- instructionSets, null, null, null, 0);
+ | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
+ instructionSets, null, null, null, 0, null /*certificates*/);
// Hackily pretend we're still looking at a full code path
if (!fullCodePath.endsWith(RES_FILE_NAME)) {
fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
@@ -12965,8 +13028,8 @@
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
- | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
- instructionSets, null, null, null, 0);
+ | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
+ instructionSets, null, null, null, 0, null /*certificates*/);
this.cid = cid;
setMountPath(PackageHelper.getSdDir(cid));
}
@@ -13235,7 +13298,7 @@
params.installerPackageName, params.volumeUuid,
params.getUser(), null /* instruction sets */, params.packageAbiOverride,
params.grantedRuntimePermissions,
- params.traceMethod, params.traceCookie);
+ params.traceMethod, params.traceCookie, params.certificates);
}
int copyApk(IMediaContainerService imcs, boolean temp) {
@@ -13308,7 +13371,13 @@
Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
synchronized (mInstallLock) {
// Clean up both app data and code
- removeDataDirsLI(volumeUuid, move.packageName);
+ // All package moves are frozen until finished
+ try {
+ mInstaller.destroyAppData(volumeUuid, move.packageName, UserHandle.USER_ALL,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
+ } catch (InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
+ }
removeCodePathLI(codeFile);
}
return true;
@@ -13453,7 +13522,7 @@
/*
* Install a non-existing package.
*/
- private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
+ private void installNewPackageLIF(PackageParser.Package pkg, int parseFlags, int scanFlags,
UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
@@ -13489,12 +13558,12 @@
updateSettingsLI(newPackage, installerPackageName, null, res, user);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
- prepareAppDataAfterInstall(newPackage);
+ prepareAppDataAfterInstallLIF(newPackage);
} else {
// Remove package from internal structures, but keep around any
// data that might have already existed
- deletePackageLI(pkgName, UserHandle.ALL, false, null,
+ deletePackageLIF(pkgName, UserHandle.ALL, false, null,
PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
}
} catch (PackageManagerException e) {
@@ -13540,14 +13609,13 @@
return false;
}
- private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
+ private void replacePackageLIF(PackageParser.Package pkg, int parseFlags, int scanFlags,
UserHandle user, String installerPackageName, PackageInstalledInfo res) {
final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
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) {
@@ -13580,32 +13648,8 @@
// 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;
@@ -13645,10 +13689,10 @@
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
- replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
+ replaceSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
user, allUsers, installerPackageName, res);
} else {
- replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
+ replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
user, allUsers, installerPackageName, res);
}
}
@@ -13662,7 +13706,7 @@
return result;
}
- private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
+ private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
@@ -13680,7 +13724,7 @@
? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
// First delete the existing package while retaining the data directory
- if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags,
+ if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, pkg)) {
// If the existing package wasn't successfully deleted
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
@@ -13700,8 +13744,9 @@
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
- deleteCodeCacheDirsLI(pkg);
- deleteProfilesLI(pkg, /*destroy*/ false);
+ clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
+ | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ clearAppProfilesLIF(pkg);
try {
final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
@@ -13728,7 +13773,7 @@
childPs.oldCodePaths = ps.oldCodePaths;
}
}
- prepareAppDataAfterInstall(newPackage);
+ prepareAppDataAfterInstallLIF(newPackage);
addedPkg = true;
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
@@ -13740,7 +13785,7 @@
// Revert all internal state mutations and added folders for the failed install
if (addedPkg) {
- deletePackageLI(pkgName, null, true, allUsers, deleteFlags,
+ deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, null);
}
@@ -13800,7 +13845,7 @@
}
}
- private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
+ private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
@@ -13815,9 +13860,6 @@
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
- // Kill package processes including services, providers, etc.
- killPackage(deletedPackage, "replace sys pkg");
-
// Remove existing system package
removePackageLI(deletedPackage, true);
@@ -13835,8 +13877,9 @@
}
// Successfully disabled the old package. Now proceed with re-installation
- deleteCodeCacheDirsLI(pkg);
- deleteProfilesLI(pkg, /*destroy*/ false);
+ clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
+ | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ clearAppProfilesLIF(pkg);
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
@@ -13885,14 +13928,14 @@
if (ps != null && res.removedInfo.removedChildPackages != null) {
PackageRemovedInfo removedChildRes = res.removedInfo
.removedChildPackages.get(deletedChildPkg.packageName);
- removePackageDataLI(ps, allUsers, removedChildRes, 0, false);
+ removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
}
}
}
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
- prepareAppDataAfterInstall(newPackage);
+ prepareAppDataAfterInstallLIF(newPackage);
}
} catch (PackageManagerException e) {
res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
@@ -14274,7 +14317,18 @@
}
try {
- PackageParser.collectCertificates(pkg, parseFlags);
+ // either use what we've been given or parse directly from the APK
+ if (args.certificates != null) {
+ try {
+ PackageParser.populateCertificates(pkg, args.certificates);
+ } catch (PackageParserException e) {
+ // there was something wrong with the certificates we were given;
+ // try to pull them from the APK
+ PackageParser.collectCertificates(pkg, parseFlags);
+ }
+ } else {
+ PackageParser.collectCertificates(pkg, parseFlags);
+ }
} catch (PackageParserException e) {
res.setError("Failed collect during installPackageLI", e);
return;
@@ -14481,12 +14535,15 @@
startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
- if (replace) {
- replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
- installerPackageName, res);
- } else {
- installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
- args.user, installerPackageName, volumeUuid, res);
+ try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
+ "installPackageLI")) {
+ if (replace) {
+ replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
+ installerPackageName, res);
+ } else {
+ installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
+ args.user, installerPackageName, volumeUuid, res);
+ }
}
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
@@ -14734,13 +14791,13 @@
@Override
public void deletePackage(final String packageName,
- final IPackageDeleteObserver2 observer, final int userId, final int flags) {
+ final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
Preconditions.checkNotNull(packageName);
Preconditions.checkNotNull(observer);
final int uid = Binder.getCallingUid();
- final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0;
+ final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
mContext.enforceCallingOrSelfPermission(
@@ -14776,15 +14833,15 @@
mHandler.removeCallbacks(this);
int returnCode;
if (!deleteAllUsers) {
- returnCode = deletePackageX(packageName, userId, flags);
+ returnCode = deletePackageX(packageName, userId, deleteFlags);
} else {
int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
// If nobody is blocking uninstall, proceed with delete for all users
if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
- returnCode = deletePackageX(packageName, userId, flags);
+ returnCode = deletePackageX(packageName, userId, deleteFlags);
} else {
// Otherwise uninstall individually for users with blockUninstalls=false
- final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS;
+ final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
for (int userId : users) {
if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
returnCode = deletePackageX(packageName, userId, userFlags);
@@ -14865,7 +14922,7 @@
* This method is an internal method that could be get invoked either
* to delete an installed package or to clean up a failed installation.
* After deleting an installed package, a broadcast is sent to notify any
- * listeners that the package has been installed. For cleaning up a failed
+ * listeners that the package has been removed. For cleaning up a failed
* installation, the broadcast is not necessary since the package's
* installation wouldn't have sent the initial broadcast either
* The key steps in deleting a package are
@@ -14875,11 +14932,11 @@
* persisting settings for later use
* sending a broadcast if necessary
*/
- private int deletePackageX(String packageName, int userId, int flags) {
+ private int deletePackageX(String packageName, int userId, int deleteFlags) {
final PackageRemovedInfo info = new PackageRemovedInfo();
final boolean res;
- final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
+ final UserHandle removeForUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
? UserHandle.ALL : new UserHandle(userId);
if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
@@ -14904,8 +14961,11 @@
synchronized (mInstallLock) {
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
- res = deletePackageLI(packageName, removeForUser, true, allUsers,
- flags | REMOVE_CHATTY, info, true, null);
+ try (PackageFreezer freezer = freezePackageForDelete(packageName, deleteFlags,
+ "deletePackageX")) {
+ res = deletePackageLIF(packageName, removeForUser, true, allUsers,
+ deleteFlags | REMOVE_CHATTY, info, true, null);
+ }
synchronized (mPackages) {
if (res) {
mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
@@ -14914,7 +14974,7 @@
}
if (res) {
- final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0;
+ final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
info.sendPackageRemovedBroadcasts(killApp);
info.sendSystemPackageUpdatedBroadcasts();
info.sendSystemPackageAppearedBroadcasts();
@@ -15024,15 +15084,16 @@
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
- private void removePackageDataLI(PackageSetting ps, int[] allUserHandles,
+ private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
String packageName = ps.name;
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
- removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
// Retrieve object to delete permissions for shared user later on
+ final PackageParser.Package deletedPkg;
final PackageSetting deletedPs;
// reader
synchronized (mPackages) {
+ deletedPkg = mPackages.get(packageName);
deletedPs = mSettings.mPackages.get(packageName);
if (outInfo != null) {
outInfo.removedPackage = packageName;
@@ -15041,13 +15102,19 @@
: null;
}
}
- if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
- removeDataDirsLI(ps.volumeUuid, packageName);
+
+ removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
+
+ if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+ destroyAppDataLIF(deletedPkg, UserHandle.USER_ALL,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ destroyAppProfilesLIF(deletedPkg);
if (outInfo != null) {
outInfo.dataRemoved = true;
}
schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
}
+
// writer
synchronized (mPackages) {
if (deletedPs != null) {
@@ -15127,7 +15194,7 @@
/*
* Tries to delete system package.
*/
- private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg,
+ private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
if (deletedPs.parentPackageName != null) {
@@ -15192,7 +15259,7 @@
flags |= PackageManager.DELETE_KEEP_DATA;
}
- boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles,
+ boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
outInfo, writeSettings, disabledPs.pkg);
if (!ret) {
return false;
@@ -15222,7 +15289,7 @@
return false;
}
- prepareAppDataAfterInstall(newPkg);
+ prepareAppDataAfterInstallLIF(newPkg);
// writer
synchronized (mPackages) {
@@ -15260,7 +15327,7 @@
return true;
}
- private boolean deleteInstalledPackageLI(PackageSetting ps,
+ private boolean deleteInstalledPackageLIF(PackageSetting ps,
boolean deleteCodeAndResources, int flags, int[] allUserHandles,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
@@ -15288,7 +15355,7 @@
}
// Delete package data from internal structures and also remove data if flag is set
- removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings);
+ removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
// Delete the child packages data
final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
@@ -15305,7 +15372,7 @@
&& (replacingPackage != null
&& !replacingPackage.hasChildPackage(childPs.name))
? flags & ~DELETE_KEEP_DATA : flags;
- removePackageDataLI(childPs, allUserHandles, childOutInfo,
+ removePackageDataLIF(childPs, allUserHandles, childOutInfo,
deleteFlags, writeSettings);
}
}
@@ -15382,7 +15449,7 @@
/*
* This method handles package deletion in general
*/
- private boolean deletePackageLI(String packageName, UserHandle user,
+ private boolean deletePackageLIF(String packageName, UserHandle user,
boolean deleteCodeAndResources, int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
@@ -15410,7 +15477,7 @@
}
final int removedUserId = (user != null) ? user.getIdentifier()
: UserHandle.USER_ALL;
- if (!clearPackageStateForUser(ps, removedUserId, outInfo)) {
+ if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
return false;
}
markPackageUninstalledForUserLPw(ps, user);
@@ -15436,7 +15503,7 @@
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
- if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
+ if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
scheduleWritePackageRestrictionsLocked(user);
@@ -15453,7 +15520,7 @@
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
- if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
+ if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
scheduleWritePackageRestrictionsLocked(user);
@@ -15485,15 +15552,10 @@
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
// When an updated system application is deleted we delete the existing resources
// as well and fall back to existing code in system partition
- ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
+ ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
- // Kill application pre-emptively especially for apps on sd.
- final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0;
- if (killApp) {
- killApplication(packageName, ps.appId, "uninstall pkg");
- }
- ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles,
+ ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
outInfo, writeSettings, replacingPackage);
}
@@ -15553,7 +15615,7 @@
if (DEBUG_REMOVE) {
Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
}
- ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT,
+ ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
false /*installed*/, true /*stopped*/, true /*notLaunched*/,
false /*hidden*/, false /*suspended*/, null, null, null,
false /*blockUninstall*/,
@@ -15561,8 +15623,13 @@
}
}
- private boolean clearPackageStateForUser(PackageSetting ps, int userId,
+ private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
PackageRemovedInfo outInfo) {
+ final PackageParser.Package pkg;
+ synchronized (mPackages) {
+ pkg = mPackages.get(ps.name);
+ }
+
final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
: new int[] {userId};
for (int nextUserId : userIds) {
@@ -15570,13 +15637,9 @@
Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
+ nextUserId);
}
- final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE;
- try {
- mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags);
- } catch (InstallerException e) {
- Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e);
- return false;
- }
+
+ destroyAppDataLIF(pkg, userId,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
removeKeystoreDataIfNeeded(nextUserId, ps.appId);
schedulePackageCleaning(ps.name, nextUserId, false);
synchronized (mPackages) {
@@ -15613,6 +15676,8 @@
}
private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
+ if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
+
final boolean mounted;
if (Environment.isExternalStorageEmulated()) {
mounted = true;
@@ -15672,10 +15737,16 @@
@Override
public void clearApplicationProfileData(String packageName) {
enforceSystemOrRoot("Only the system can clear all profile data");
- try {
- mInstaller.clearAppProfiles(packageName);
- } catch (InstallerException ex) {
- Log.e(TAG, "Could not clear profile data of package " + packageName);
+
+ final PackageParser.Package pkg;
+ synchronized (mPackages) {
+ pkg = mPackages.get(packageName);
+ }
+
+ try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
+ synchronized (mInstallLock) {
+ clearAppProfilesLIF(pkg);
+ }
}
}
@@ -15698,10 +15769,13 @@
public void run() {
mHandler.removeCallbacks(this);
final boolean succeeded;
- synchronized (mInstallLock) {
- succeeded = clearApplicationUserDataLI(packageName, userId);
+ try (PackageFreezer freezer = freezePackage(packageName,
+ "clearApplicationUserData")) {
+ synchronized (mInstallLock) {
+ succeeded = clearApplicationUserDataLIF(packageName, userId);
+ }
+ clearExternalStorageDataSync(packageName, userId, true);
}
- clearExternalStorageDataSync(packageName, userId, true);
if (succeeded) {
// invoke DeviceStorageMonitor's update method to clear any notifications
DeviceStorageMonitorInternal dsm = LocalServices
@@ -15721,7 +15795,7 @@
});
}
- private boolean clearApplicationUserDataLI(String packageName, int userId) {
+ private boolean clearApplicationUserDataLIF(String packageName, int userId) {
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
@@ -15747,35 +15821,22 @@
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
}
- // Always delete data directories for package, even if we found no other
- // record of app. This helps users recover from UID mismatches without
- // resorting to a full data wipe.
- // TODO: triage flags as part of 26466827
- final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
- try {
- mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags);
- } catch (InstallerException e) {
- Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e);
- return false;
- }
+ clearAppDataLIF(pkg, userId,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
removeKeystoreDataIfNeeded(userId, appId);
- // Create a native library symlink only if we have native libraries
- // and if the native libraries are 32 bit libraries. We do not provide
- // this symlink for 64 bit libraries.
- if (pkg.applicationInfo.primaryCpuAbi != null &&
- !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
- final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
- try {
- mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
- nativeLibPath, userId);
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed linking native library dir", e);
- return false;
- }
+ final UserManager um = mContext.getSystemService(UserManager.class);
+ final int flags;
+ if (um.isUserUnlocked(userId)) {
+ flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
+ } else if (um.isUserRunning(userId)) {
+ flags = StorageManager.FLAG_STORAGE_DE;
+ } else {
+ flags = 0;
}
+ prepareAppDataContentsLIF(pkg, userId, flags);
return true;
}
@@ -15945,56 +16006,35 @@
android.Manifest.permission.DELETE_CACHE_FILES, null);
// Queue up an async operation since the package deletion may take a little while.
final int userId = UserHandle.getCallingUserId();
+
+ final PackageParser.Package pkg;
+ synchronized (mPackages) {
+ pkg = mPackages.get(packageName);
+ }
+
mHandler.post(new Runnable() {
public void run() {
- mHandler.removeCallbacks(this);
- final boolean succeded;
- synchronized (mInstallLock) {
- succeded = deleteApplicationCacheFilesLI(packageName, userId);
+ try (PackageFreezer freezer = freezePackage(packageName,
+ "deleteApplicationCacheFiles")) {
+ synchronized (mInstallLock) {
+ final int flags = StorageManager.FLAG_STORAGE_DE
+ | StorageManager.FLAG_STORAGE_CE;
+ clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
+ clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ }
+ clearExternalStorageDataSync(packageName, userId, false);
}
- clearExternalStorageDataSync(packageName, userId, false);
if (observer != null) {
try {
- observer.onRemoveCompleted(packageName, succeded);
+ observer.onRemoveCompleted(packageName, true);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
}
- } //end if observer
- } //end run
+ }
+ }
});
}
- private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
- if (packageName == null) {
- Slog.w(TAG, "Attempt to delete null packageName.");
- return false;
- }
- PackageParser.Package p;
- synchronized (mPackages) {
- p = mPackages.get(packageName);
- }
- if (p == null) {
- Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
- return false;
- }
- final ApplicationInfo applicationInfo = p.applicationInfo;
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
- return false;
- }
- // TODO: triage flags as part of 26466827
- final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
- try {
- mInstaller.clearAppData(p.volumeUuid, packageName, userId,
- flags | Installer.FLAG_CLEAR_CACHE_ONLY);
- } catch (InstallerException e) {
- Slog.w(TAG, "Couldn't remove cache files for package "
- + packageName + " u" + userId, e);
- return false;
- }
- return true;
- }
-
@Override
public void getPackageSizeInfo(final String packageName, int userHandle,
final IPackageStatsObserver observer) {
@@ -16015,90 +16055,24 @@
mHandler.sendMessage(msg);
}
- private boolean getPackageSizeInfoLI(String packageName, int userHandle,
- PackageStats pStats) {
- if (packageName == null) {
- Slog.w(TAG, "Attempt to get size of null packageName.");
- return false;
- }
- PackageParser.Package p;
- boolean dataOnly = false;
- String libDirRoot = null;
- String asecPath = null;
- PackageSetting ps = null;
+ private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
+ final PackageSetting ps;
synchronized (mPackages) {
- p = mPackages.get(packageName);
ps = mSettings.mPackages.get(packageName);
- if(p == null) {
- dataOnly = true;
- if((ps == null) || (ps.pkg == null)) {
- Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
- return false;
- }
- p = ps.pkg;
- }
- if (ps != null) {
- libDirRoot = ps.legacyNativeLibraryPathString;
- }
- if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
- final long token = Binder.clearCallingIdentity();
- try {
- String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
- if (secureContainerId != null) {
- asecPath = PackageHelper.getSdFilesystem(secureContainerId);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
- String publicSrcDir = null;
- if(!dataOnly) {
- final ApplicationInfo applicationInfo = p.applicationInfo;
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
+ if (ps == null) {
+ Slog.w(TAG, "Failed to find settings for " + packageName);
return false;
}
- if (p.isForwardLocked()) {
- publicSrcDir = applicationInfo.getBaseResourcePath();
- }
}
- // TODO: extend to measure size of split APKs
- // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
- // not just the first level.
- // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
- // just the primary.
- String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
-
- String apkPath;
- File packageDir = new File(p.codePath);
-
- if (packageDir.isDirectory() && p.canHaveOatDir()) {
- apkPath = packageDir.getAbsolutePath();
- // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
- if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
- libDirRoot = null;
- }
- } else {
- apkPath = p.baseCodePath;
- }
-
- // TODO: triage flags as part of 26466827
- final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
try {
- mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath,
- libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
+ mInstaller.getAppSize(ps.volumeUuid, packageName, userId,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE,
+ ps.getCeDataInode(userId), ps.codePathString, stats);
+ return true;
} catch (InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
return false;
}
-
- // Fix-up for forward-locked applications in ASEC containers.
- if (!isExternal(p)) {
- pStats.codeSize += pStats.externalCodeSize;
- pStats.externalCodeSize = 0L;
- }
-
- return true;
}
private int getUidTargetSdkVersionLockedLPr(int uid) {
@@ -17413,6 +17387,7 @@
public static final int DUMP_INSTALLS = 1 << 16;
public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
+ public static final int DUMP_FROZEN = 1 << 19;
public static final int OPTION_SHOW_FILTERS = 1 << 0;
@@ -17646,6 +17621,8 @@
dumpState.setDump(DumpState.DUMP_KEYSETS);
} else if ("installs".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_INSTALLS);
+ } else if ("frozen".equals(cmd)) {
+ dumpState.setDump(DumpState.DUMP_FROZEN);
} else if ("write".equals(cmd)) {
synchronized (mPackages) {
mSettings.writeLPr();
@@ -17984,6 +17961,25 @@
mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
}
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
+ // XXX should handle packageName != null by dumping only install data that
+ // the given package is involved with.
+ if (dumpState.onTitlePrinted()) pw.println();
+
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
+ ipw.println();
+ ipw.println("Frozen packages:");
+ ipw.increaseIndent();
+ if (mFrozenPackages.size() == 0) {
+ ipw.println("(none)");
+ } else {
+ for (int i = 0; i < mFrozenPackages.size(); i++) {
+ ipw.println(mFrozenPackages.valueAt(i));
+ }
+ }
+ ipw.decreaseIndent();
+ }
+
if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted()) pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
@@ -18296,7 +18292,9 @@
synchronized (mInstallLock) {
PackageParser.Package pkg = null;
try {
- pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
+ // Sadly we don't know the package name yet to freeze it
+ pkg = scanPackageTracedLI(new File(codePath), parseFlags,
+ SCAN_IGNORE_FROZEN, 0, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
}
@@ -18395,8 +18393,13 @@
// Delete package internally
PackageRemovedInfo outInfo = new PackageRemovedInfo();
synchronized (mInstallLock) {
- boolean res = deletePackageLI(pkgName, null, false, null,
- PackageManager.DELETE_KEEP_DATA, outInfo, false, null);
+ final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
+ final boolean res;
+ try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
+ "unloadMediaPackages")) {
+ res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
+ null);
+ }
if (res) {
pkgList.add(pkgName);
} else {
@@ -18451,6 +18454,7 @@
return;
}
+ final ArrayList<PackageFreezer> freezers = new ArrayList<>();
final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
@@ -18461,9 +18465,8 @@
packages = mSettings.getVolumePackagesLPr(volumeUuid);
}
- // TODO: introduce a new concept similar to "frozen" to prevent these
- // apps from being launched until after data has been fully reconciled
for (PackageSetting ps : packages) {
+ freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
synchronized (mInstallLock) {
final PackageParser.Package pkg;
try {
@@ -18475,7 +18478,9 @@
}
if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
- deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
+ clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
+ | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
}
@@ -18494,7 +18499,9 @@
}
sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
- reconcileAppsData(volumeUuid, user.id, flags);
+ synchronized (mInstallLock) {
+ reconcileAppsDataLI(volumeUuid, user.id, flags);
+ }
}
synchronized (mPackages) {
@@ -18512,6 +18519,10 @@
mSettings.writeLPr();
}
+ for (PackageFreezer freezer : freezers) {
+ freezer.close();
+ }
+
if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
sendResourcesChangedBroadcast(true, false, loaded, null);
}
@@ -18540,12 +18551,17 @@
if (ps.pkg == null) continue;
final ApplicationInfo info = ps.pkg.applicationInfo;
+ final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
final PackageRemovedInfo outInfo = new PackageRemovedInfo();
- if (deletePackageLI(ps.name, null, false, null,
- PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) {
- unloaded.add(info);
- } else {
- Slog.w(TAG, "Failed to unload " + ps.codePath);
+
+ try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
+ "unloadPrivatePackagesInner")) {
+ if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
+ false, null)) {
+ unloaded.add(info);
+ } else {
+ Slog.w(TAG, "Failed to unload " + ps.codePath);
+ }
}
}
@@ -18677,7 +18693,9 @@
final StorageManager storage = mContext.getSystemService(StorageManager.class);
for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
final String volumeUuid = vol.getFsUuid();
- reconcileAppsData(volumeUuid, userId, flags);
+ synchronized (mInstallLock) {
+ reconcileAppsDataLI(volumeUuid, userId, flags);
+ }
}
}
@@ -18690,7 +18708,7 @@
* Verifies that directories exist and that ownership and labeling is
* correct for all installed apps.
*/
- private void reconcileAppsData(String volumeUuid, int userId, int flags) {
+ private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
+ Integer.toHexString(flags));
@@ -18717,9 +18735,11 @@
assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
} catch (PackageManagerException e) {
logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
- synchronized (mInstallLock) {
- destroyAppDataLI(volumeUuid, packageName, userId,
- StorageManager.FLAG_STORAGE_CE);
+ try {
+ mInstaller.destroyAppData(volumeUuid, packageName, userId,
+ StorageManager.FLAG_STORAGE_CE, 0);
+ } catch (InstallerException e2) {
+ logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
}
}
}
@@ -18734,9 +18754,11 @@
assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
} catch (PackageManagerException e) {
logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
- synchronized (mInstallLock) {
- destroyAppDataLI(volumeUuid, packageName, userId,
- StorageManager.FLAG_STORAGE_DE);
+ try {
+ mInstaller.destroyAppData(volumeUuid, packageName, userId,
+ StorageManager.FLAG_STORAGE_DE, 0);
+ } catch (InstallerException e2) {
+ logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
}
}
}
@@ -18759,12 +18781,12 @@
}
if (ps.getInstalled(userId)) {
- prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
+ prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded);
- if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) {
+ if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
// We may have just shuffled around app data directories, so
// prepare them one more time
- prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
+ prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded);
}
preparedCount++;
@@ -18796,16 +18818,7 @@
* <p>
* <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
*/
- private void prepareAppDataAfterInstall(PackageParser.Package pkg) {
- prepareAppDataAfterInstallInternal(pkg);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPackage = pkg.childPackages.get(i);
- prepareAppDataAfterInstallInternal(childPackage);
- }
- }
-
- private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) {
+ private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
final PackageSetting ps;
synchronized (mPackages) {
ps = mSettings.mPackages.get(pkg.packageName);
@@ -18826,7 +18839,7 @@
if (ps.getInstalled(user.id)) {
// Whenever an app changes, force a restorecon of its data
// TODO: when user data is locked, mark that we're still dirty
- prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true);
+ prepareAppDataLIF(pkg, user.id, flags, true);
}
}
}
@@ -18839,57 +18852,112 @@
* will try recovering system apps by wiping data; third-party app data is
* left intact.
*/
- private void prepareAppData(String volumeUuid, int userId, int flags,
- PackageParser.Package pkg, boolean restoreconNeeded) {
+ private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags,
+ boolean restoreconNeeded) {
+ if (pkg == null) {
+ Slog.wtf(TAG, "Package was null!", new Throwable());
+ return;
+ }
+ prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded);
+ }
+ }
+
+ private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags,
+ boolean restoreconNeeded) {
if (DEBUG_APP_DATA) {
Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
+ Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : ""));
}
+ final String volumeUuid = pkg.volumeUuid;
final String packageName = pkg.packageName;
final ApplicationInfo app = pkg.applicationInfo;
final int appId = UserHandle.getAppId(app.uid);
Preconditions.checkNotNull(app.seinfo);
- synchronized (mInstallLock) {
- try {
- mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, app.seinfo, app.targetSdkVersion);
- } catch (InstallerException e) {
- if (app.isSystemApp()) {
- logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
- + ", but trying to recover: " + e);
- destroyAppDataLI(volumeUuid, packageName, userId, flags);
- try {
- mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, app.seinfo, app.targetSdkVersion);
- logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
- } catch (InstallerException e2) {
- logCriticalInfo(Log.DEBUG, "Recovery failed!");
- }
- } else {
- Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
+ try {
+ mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+ appId, app.seinfo, app.targetSdkVersion);
+ } catch (InstallerException e) {
+ if (app.isSystemApp()) {
+ logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
+ + ", but trying to recover: " + e);
+ destroyAppDataLeafLIF(pkg, userId, flags);
+ try {
+ mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+ appId, app.seinfo, app.targetSdkVersion);
+ logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
+ } catch (InstallerException e2) {
+ logCriticalInfo(Log.DEBUG, "Recovery failed!");
}
+ } else {
+ Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
}
+ }
- if (restoreconNeeded) {
- restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo);
+ if (restoreconNeeded) {
+ try {
+ mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId,
+ app.seinfo);
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
}
+ }
- if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
- // Create a native library symlink only if we have native libraries
- // and if the native libraries are 32 bit libraries. We do not provide
- // this symlink for 64 bit libraries.
- if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
- final String nativeLibPath = app.nativeLibraryDir;
- try {
- mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
- nativeLibPath, userId);
- } catch (InstallerException e) {
- Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
+ if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
+ try {
+ // CE storage is unlocked right now, so read out the inode and
+ // remember for use later when it's locked
+ // TODO: mark this structure as dirty so we persist it!
+ final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
+ StorageManager.FLAG_STORAGE_CE);
+ synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ ps.setCeDataInode(ceDataInode, userId);
}
}
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
+ }
+ }
+
+ prepareAppDataContentsLeafLIF(pkg, userId, flags);
+ }
+
+ private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
+ if (pkg == null) {
+ Slog.wtf(TAG, "Package was null!", new Throwable());
+ return;
+ }
+ prepareAppDataContentsLeafLIF(pkg, userId, flags);
+ final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
+ }
+ }
+
+ private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ final String volumeUuid = pkg.volumeUuid;
+ final String packageName = pkg.packageName;
+ final ApplicationInfo app = pkg.applicationInfo;
+
+ if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
+ // Create a native library symlink only if we have native libraries
+ // and if the native libraries are 32 bit libraries. We do not provide
+ // this symlink for 64 bit libraries.
+ if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
+ final String nativeLibPath = app.nativeLibraryDir;
+ try {
+ mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
+ nativeLibPath, userId);
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
+ }
}
}
}
@@ -18899,18 +18967,17 @@
* CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
* requested by the app.
*/
- private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) {
+ private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
- synchronized (mInstallLock) {
- try {
- mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget);
- } catch (InstallerException e) {
- logCriticalInfo(Log.WARN,
- "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
- }
+ try {
+ mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
+ storageTarget);
+ } catch (InstallerException e) {
+ logCriticalInfo(Log.WARN,
+ "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
}
return true;
} else {
@@ -18918,11 +18985,116 @@
}
}
- private void unfreezePackage(String packageName) {
+ public PackageFreezer freezePackage(String packageName, String killReason) {
+ return new PackageFreezer(packageName, killReason);
+ }
+
+ public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
+ String killReason) {
+ if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
+ return new PackageFreezer();
+ } else {
+ return freezePackage(packageName, killReason);
+ }
+ }
+
+ public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
+ String killReason) {
+ if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
+ return new PackageFreezer();
+ } else {
+ return freezePackage(packageName, killReason);
+ }
+ }
+
+ /**
+ * Class that freezes and kills the given package upon creation, and
+ * unfreezes it upon closing. This is typically used when doing surgery on
+ * app code/data to prevent the app from running while you're working.
+ */
+ private class PackageFreezer implements AutoCloseable {
+ private final String mPackageName;
+ private final PackageFreezer[] mChildren;
+
+ private final boolean mWeFroze;
+
+ private final AtomicBoolean mClosed = new AtomicBoolean();
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+
+ /**
+ * Create and return a stub freezer that doesn't actually do anything,
+ * typically used when someone requested
+ * {@link PackageManager#INSTALL_DONT_KILL_APP} or
+ * {@link PackageManager#DELETE_DONT_KILL_APP}.
+ */
+ public PackageFreezer() {
+ mPackageName = null;
+ mChildren = null;
+ mWeFroze = false;
+ mCloseGuard.open("close");
+ }
+
+ public PackageFreezer(String packageName, String killReason) {
+ synchronized (mPackages) {
+ mPackageName = packageName;
+ mWeFroze = mFrozenPackages.add(mPackageName);
+
+ final PackageSetting ps = mSettings.mPackages.get(mPackageName);
+ if (ps != null) {
+ killApplication(ps.name, ps.appId, killReason);
+ }
+
+ final PackageParser.Package p = mPackages.get(packageName);
+ if (p != null && p.childPackages != null) {
+ final int N = p.childPackages.size();
+ mChildren = new PackageFreezer[N];
+ for (int i = 0; i < N; i++) {
+ mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
+ killReason);
+ }
+ } else {
+ mChildren = null;
+ }
+ }
+ mCloseGuard.open("close");
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ mCloseGuard.warnIfOpen();
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ @Override
+ public void close() {
+ mCloseGuard.close();
+ if (mClosed.compareAndSet(false, true)) {
+ synchronized (mPackages) {
+ if (mWeFroze) {
+ mFrozenPackages.remove(mPackageName);
+ }
+
+ if (mChildren != null) {
+ for (PackageFreezer freezer : mChildren) {
+ freezer.close();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Verify that given package is currently frozen.
+ */
+ private void checkPackageFrozen(String packageName) {
synchronized (mPackages) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- ps.frozen = false;
+ if (!mFrozenPackages.contains(packageName)) {
+ Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
}
}
}
@@ -18962,6 +19134,7 @@
final String seinfo;
final String label;
final int targetSdkVersion;
+ final PackageFreezer freezer;
// reader
synchronized (mPackages) {
@@ -19003,11 +19176,10 @@
"Device admin cannot be moved");
}
- if (ps.frozen) {
+ if (mFrozenPackages.contains(packageName)) {
throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
"Failed to move already frozen package");
}
- ps.frozen = true;
codeFile = new File(pkg.codePath);
installerPackageName = ps.installerPackageName;
@@ -19016,14 +19188,7 @@
seinfo = pkg.applicationInfo.seinfo;
label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- }
-
- // Now that we're guarded by frozen state, kill app during move
- final long token = Binder.clearCallingIdentity();
- try {
- killApplication(packageName, appId, "move pkg");
- } finally {
- Binder.restoreCallingIdentity(token);
+ freezer = new PackageFreezer(packageName, "movePackageInternal");
}
final Bundle extras = new Bundle();
@@ -19047,7 +19212,7 @@
final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
|| !volume.isMountedWritable()) {
- unfreezePackage(packageName);
+ freezer.close();
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
"Move location not mounted private volume");
}
@@ -19062,7 +19227,7 @@
final PackageStats stats = new PackageStats(null, -1);
synchronized (mInstaller) {
if (!getPackageSizeInfoLI(packageName, -1, stats)) {
- unfreezePackage(packageName);
+ freezer.close();
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
"Failed to measure package size");
}
@@ -19080,7 +19245,7 @@
}
if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
- unfreezePackage(packageName);
+ freezer.close();
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
"Not enough free space to move");
}
@@ -19101,10 +19266,7 @@
+ PackageManager.installStatusToString(returnCode, msg));
installedLatch.countDown();
-
- // Regardless of success or failure of the move operation,
- // always unfreeze the package
- unfreezePackage(packageName);
+ freezer.close();
final int status = PackageManager.installStatusToPublicStatus(returnCode);
switch (status) {
@@ -19159,7 +19321,7 @@
final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
installerPackageName, volumeUuid, null /*verificationInfo*/, user,
- packageAbiOverride, null);
+ packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 1434718..9d04472 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -114,12 +114,6 @@
int installStatus = PKG_INSTALL_COMPLETE;
/**
- * Non-persisted value indicating this package has been temporarily frozen,
- * usually during a critical section of the package update pipeline. The
- * platform will refuse to launch packages in a frozen state.
- */
- boolean frozen = false;
- /**
* Non-persisted value. During an "upgrade without restart", we need the set
* of all previous code paths so we can surgically add the new APKs to the
* active classloader. If at any point an application is upgraded with a
@@ -329,6 +323,14 @@
return res;
}
+ long getCeDataInode(int userId) {
+ return readUserState(userId).ceDataInode;
+ }
+
+ void setCeDataInode(long ceDataInode, int userId) {
+ modifyUserState(userId).ceDataInode = ceDataInode;
+ }
+
boolean getStopped(int userId) {
return readUserState(userId).stopped;
}
@@ -369,12 +371,13 @@
modifyUserState(userId).blockUninstall = blockUninstall;
}
- void setUserState(int userId, int enabled, boolean installed, boolean stopped,
+ void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden, boolean suspended,
String lastDisableAppCaller, ArraySet<String> enabledComponents,
ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
int linkGeneration) {
PackageUserState state = modifyUserState(userId);
+ state.ceDataInode = ceDataInode;
state.enabled = enabled;
state.installed = installed;
state.stopped = stopped;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3c3c576..847f993 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -195,23 +195,26 @@
private static final String ATTR_NAME = "name";
private static final String ATTR_USER = "user";
private static final String ATTR_CODE = "code";
- private static final String ATTR_NOT_LAUNCHED = "nl";
- private static final String ATTR_ENABLED = "enabled";
private static final String ATTR_GRANTED = "granted";
private static final String ATTR_FLAGS = "flags";
- private static final String ATTR_ENABLED_CALLER = "enabledCaller";
+
+ private static final String ATTR_CE_DATA_INODE = "ceDataInode";
+ private static final String ATTR_INSTALLED = "inst";
private static final String ATTR_STOPPED = "stopped";
+ private static final String ATTR_NOT_LAUNCHED = "nl";
// Legacy, here for reading older versions of the package-restrictions.
private static final String ATTR_BLOCKED = "blocked";
// New name for the above attribute.
private static final String ATTR_HIDDEN = "hidden";
private static final String ATTR_SUSPENDED = "suspended";
- private static final String ATTR_INSTALLED = "inst";
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
+ private static final String ATTR_ENABLED = "enabled";
+ private static final String ATTR_ENABLED_CALLER = "enabledCaller";
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
+ private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
+
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_FINGERPRINT = "fingerprint";
- private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
private static final String ATTR_VOLUME_UUID = "volumeUuid";
private static final String ATTR_SDK_VERSION = "sdkVersion";
private static final String ATTR_DATABASE_VERSION = "databaseVersion";
@@ -247,6 +250,9 @@
/** Map from package name to settings */
final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();
+ /** List of packages that installed other packages */
+ final ArraySet<String> mInstallerPackages = new ArraySet<>();
+
/** Map from package name to appId */
private final ArrayMap<String, Integer> mKernelMapping = new ArrayMap<>();
@@ -360,7 +366,7 @@
// Packages that have been uninstalled and still need their external
// storage data deleted.
final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
-
+
// Packages that have been renamed since they were first installed.
// Keys are the new names of the packages, values are the original
// names. The packages appear everwhere else under their original
@@ -506,6 +512,9 @@
PackageSetting p = mPackages.get(pkgName);
if (p != null) {
p.setInstallerPackageName(installerPkgName);
+ if (installerPkgName != null) {
+ mInstallerPackages.add(installerPkgName);
+ }
}
}
@@ -572,7 +581,7 @@
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
- p.secondaryCpuAbiString, p.secondaryCpuAbiString,
+ p.secondaryCpuAbiString, p.cpuAbiOverrideString,
p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
p.parentPackageName, p.childPackageNames);
mDisabledSysPackages.remove(name);
@@ -784,7 +793,7 @@
|| (installUserId == UserHandle.USER_ALL
&& !isAdbInstallDisallowed(userManager, user.id))
|| installUserId == user.id;
- p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
+ p.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT,
installed,
true, // stopped,
true, // notLaunched
@@ -1062,6 +1071,7 @@
final PackageSetting p = mPackages.get(name);
if (p != null) {
mPackages.remove(name);
+ removeInstallerPackageStatus(name);
if (p.sharedUser != null) {
p.sharedUser.removePackage(p);
if (p.sharedUser.packages.size() == 0) {
@@ -1077,6 +1087,26 @@
return -1;
}
+ /**
+ * Checks if {@param packageName} is an installer package and if so, clear the installer
+ * package name of the packages that are installed by this.
+ */
+ private void removeInstallerPackageStatus(String packageName) {
+ // Check if the package to be removed is an installer package.
+ if (!mInstallerPackages.contains(packageName)) {
+ return;
+ }
+ for (int i = 0; i < mPackages.size(); i++) {
+ final PackageSetting ps = mPackages.valueAt(i);
+ final String installerPackageName = ps.getInstallerPackageName();
+ if (installerPackageName != null
+ && installerPackageName.equals(packageName)) {
+ ps.setInstallerPackageName(null);
+ }
+ }
+ mInstallerPackages.remove(packageName);
+ }
+
private void replacePackageLPw(String name, PackageSetting newp) {
final PackageSetting p = mPackages.get(name);
if (p != null) {
@@ -1547,7 +1577,7 @@
// in the stopped state, but not at first boot. Also
// consider all applications to be installed.
for (PackageSetting pkg : mPackages.values()) {
- pkg.setUserState(userId, COMPONENT_ENABLED_STATE_DEFAULT,
+ pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
true, // installed
false, // stopped
false, // notLaunched
@@ -1599,17 +1629,16 @@
XmlUtils.skipCurrentTag(parser);
continue;
}
- final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
- final int enabled = enabledStr == null
- ? COMPONENT_ENABLED_STATE_DEFAULT : Integer.parseInt(enabledStr);
- final String enabledCaller = parser.getAttributeValue(null,
- ATTR_ENABLED_CALLER);
- final String installedStr = parser.getAttributeValue(null, ATTR_INSTALLED);
- final boolean installed = installedStr == null
- ? true : Boolean.parseBoolean(installedStr);
- final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
- final boolean stopped = stoppedStr == null
- ? false : Boolean.parseBoolean(stoppedStr);
+
+ final long ceDataInode = XmlUtils.readLongAttribute(parser, ATTR_CE_DATA_INODE,
+ 0);
+ final boolean installed = XmlUtils.readBooleanAttribute(parser, ATTR_INSTALLED,
+ true);
+ final boolean stopped = XmlUtils.readBooleanAttribute(parser, ATTR_STOPPED,
+ false);
+ final boolean notLaunched = XmlUtils.readBooleanAttribute(parser,
+ ATTR_NOT_LAUNCHED, false);
+
// For backwards compatibility with the previous name of "blocked", which
// now means hidden, read the old attribute as well.
final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
@@ -1618,25 +1647,21 @@
final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
hidden = hiddenStr == null
? hidden : Boolean.parseBoolean(hiddenStr);
- final String suspendedStr = parser.getAttributeValue(null, ATTR_SUSPENDED);
- final boolean suspended = suspendedStr == null
- ? false : Boolean.parseBoolean(suspendedStr);
- final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
- final boolean notLaunched = stoppedStr == null
- ? false : Boolean.parseBoolean(notLaunchedStr);
- final String blockUninstallStr = parser.getAttributeValue(null,
- ATTR_BLOCK_UNINSTALL);
- final boolean blockUninstall = blockUninstallStr == null
- ? false : Boolean.parseBoolean(blockUninstallStr);
- final String verifStateStr =
- parser.getAttributeValue(null, ATTR_DOMAIN_VERIFICATON_STATE);
- final int verifState = (verifStateStr == null) ?
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED :
- Integer.parseInt(verifStateStr);
+ final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED,
+ false);
+ final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
+ ATTR_BLOCK_UNINSTALL, false);
+ final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
+ COMPONENT_ENABLED_STATE_DEFAULT);
+ final String enabledCaller = parser.getAttributeValue(null,
+ ATTR_ENABLED_CALLER);
- final String linkGenStr = parser.getAttributeValue(null, ATTR_APP_LINK_GENERATION);
- final int linkGeneration = linkGenStr == null ? 0 : Integer.parseInt(linkGenStr);
+ final int verifState = XmlUtils.readIntAttribute(parser,
+ ATTR_DOMAIN_VERIFICATON_STATE,
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ final int linkGeneration = XmlUtils.readIntAttribute(parser,
+ ATTR_APP_LINK_GENERATION, 0);
if (linkGeneration > maxAppLinkGeneration) {
maxAppLinkGeneration = linkGeneration;
}
@@ -1660,8 +1685,8 @@
}
}
- ps.setUserState(userId, enabled, installed, stopped, notLaunched, hidden,
- suspended, enabledCaller, enabledComponents, disabledComponents,
+ ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
+ hidden, suspended, enabledCaller, enabledComponents, disabledComponents,
blockUninstall, verifState, linkGeneration);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
@@ -1900,80 +1925,69 @@
serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
for (final PackageSetting pkg : mPackages.values()) {
- PackageUserState ustate = pkg.readUserState(userId);
- if (ustate.stopped || ustate.notLaunched || !ustate.installed
- || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
- || ustate.hidden
- || ustate.suspended
- || (ustate.enabledComponents != null
- && ustate.enabledComponents.size() > 0)
- || (ustate.disabledComponents != null
- && ustate.disabledComponents.size() > 0)
- || ustate.blockUninstall
- || (ustate.domainVerificationStatus !=
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED)) {
- serializer.startTag(null, TAG_PACKAGE);
- serializer.attribute(null, ATTR_NAME, pkg.name);
- if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled);
+ final PackageUserState ustate = pkg.readUserState(userId);
+ if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled);
- if (!ustate.installed) {
- serializer.attribute(null, ATTR_INSTALLED, "false");
- }
- if (ustate.stopped) {
- serializer.attribute(null, ATTR_STOPPED, "true");
- }
- if (ustate.notLaunched) {
- serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
- }
- if (ustate.hidden) {
- serializer.attribute(null, ATTR_HIDDEN, "true");
- }
- if (ustate.suspended) {
- serializer.attribute(null, ATTR_SUSPENDED, "true");
- }
- if (ustate.blockUninstall) {
- serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
- }
- if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
- serializer.attribute(null, ATTR_ENABLED,
- Integer.toString(ustate.enabled));
- if (ustate.lastDisableAppCaller != null) {
- serializer.attribute(null, ATTR_ENABLED_CALLER,
- ustate.lastDisableAppCaller);
- }
- }
- if (ustate.domainVerificationStatus !=
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
- serializer.attribute(null, ATTR_DOMAIN_VERIFICATON_STATE,
- Integer.toString(ustate.domainVerificationStatus));
- }
- if (ustate.appLinkGeneration != 0) {
- serializer.attribute(null, ATTR_APP_LINK_GENERATION,
- Integer.toString(ustate.appLinkGeneration));
- }
- if (ustate.enabledComponents != null
- && ustate.enabledComponents.size() > 0) {
- serializer.startTag(null, TAG_ENABLED_COMPONENTS);
- for (final String name : ustate.enabledComponents) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME, name);
- serializer.endTag(null, TAG_ITEM);
- }
- serializer.endTag(null, TAG_ENABLED_COMPONENTS);
- }
- if (ustate.disabledComponents != null
- && ustate.disabledComponents.size() > 0) {
- serializer.startTag(null, TAG_DISABLED_COMPONENTS);
- for (final String name : ustate.disabledComponents) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME, name);
- serializer.endTag(null, TAG_ITEM);
- }
- serializer.endTag(null, TAG_DISABLED_COMPONENTS);
- }
-
- serializer.endTag(null, TAG_PACKAGE);
+ serializer.startTag(null, TAG_PACKAGE);
+ serializer.attribute(null, ATTR_NAME, pkg.name);
+ if (ustate.ceDataInode != 0) {
+ XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode);
}
+ if (!ustate.installed) {
+ serializer.attribute(null, ATTR_INSTALLED, "false");
+ }
+ if (ustate.stopped) {
+ serializer.attribute(null, ATTR_STOPPED, "true");
+ }
+ if (ustate.notLaunched) {
+ serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
+ }
+ if (ustate.hidden) {
+ serializer.attribute(null, ATTR_HIDDEN, "true");
+ }
+ if (ustate.suspended) {
+ serializer.attribute(null, ATTR_SUSPENDED, "true");
+ }
+ if (ustate.blockUninstall) {
+ serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
+ }
+ if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
+ serializer.attribute(null, ATTR_ENABLED,
+ Integer.toString(ustate.enabled));
+ if (ustate.lastDisableAppCaller != null) {
+ serializer.attribute(null, ATTR_ENABLED_CALLER,
+ ustate.lastDisableAppCaller);
+ }
+ }
+ if (ustate.domainVerificationStatus !=
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+ XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE,
+ ustate.domainVerificationStatus);
+ }
+ if (ustate.appLinkGeneration != 0) {
+ XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION,
+ ustate.appLinkGeneration);
+ }
+ if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
+ serializer.startTag(null, TAG_ENABLED_COMPONENTS);
+ for (final String name : ustate.enabledComponents) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME, name);
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_ENABLED_COMPONENTS);
+ }
+ if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
+ serializer.startTag(null, TAG_DISABLED_COMPONENTS);
+ for (final String name : ustate.disabledComponents) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME, name);
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_DISABLED_COMPONENTS);
+ }
+
+ serializer.endTag(null, TAG_PACKAGE);
}
writePreferredActivitiesLPr(serializer, userId, true);
@@ -2742,6 +2756,7 @@
mPendingPackages.clear();
mPastSignatures.clear();
mKeySetRefs.clear();
+ mInstallerPackages.clear();
try {
if (str == null) {
@@ -3706,6 +3721,10 @@
packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
}
+ if (installerPackageName != null) {
+ mInstallerPackages.add(installerPackageName);
+ }
+
final String installStatusStr = parser.getAttributeValue(null, "installStatus");
if (installStatusStr != null) {
if (installStatusStr.equalsIgnoreCase("false")) {
@@ -3724,7 +3743,7 @@
}
String tagName = parser.getName();
- // Legacy
+ // Legacy
if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
readDisabledComponentsLPw(packageSetting, parser, 0);
} else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
@@ -4293,10 +4312,6 @@
pw.print(Integer.toHexString(System.identityHashCode(ps)));
pw.println("):");
- if (ps.frozen) {
- pw.print(prefix); pw.println(" FROZEN!");
- }
-
if (ps.realName != null) {
pw.print(prefix); pw.print(" compat name=");
pw.println(ps.name);
@@ -4504,6 +4519,8 @@
for (UserInfo user : users) {
pw.print(prefix); pw.print(" User "); pw.print(user.id); pw.print(": ");
+ pw.print("ceDataInode=");
+ pw.print(ps.getCeDataInode(user.id));
pw.print(" installed=");
pw.print(ps.getInstalled(user.id));
pw.print(" hidden=");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 06a91fb..60a0d62 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -467,13 +467,16 @@
@Override
public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
+ boolean returnFullInfo = true;
if (userId != UserHandle.getCallingUserId()) {
checkManageUsersPermission("getting profiles related to user " + userId);
+ } else {
+ returnFullInfo = hasManageUsersPermission();
}
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mUsersLock) {
- return getProfilesLU(userId, enabledOnly);
+ return getProfilesLU(userId, enabledOnly, returnFullInfo);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -481,7 +484,7 @@
}
/** Assume permissions already checked and caller's identity cleared */
- private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly) {
+ private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) {
UserInfo user = getUserInfoLU(userId);
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
if (user == null) {
@@ -503,7 +506,14 @@
if (profile.partial) {
continue;
}
- users.add(userWithName(profile));
+ UserInfo userInfo = userWithName(profile);
+ // If full info is not required - clear PII data to prevent 3P apps from reading it
+ if (!fullInfo) {
+ userInfo = new UserInfo(userInfo);
+ userInfo.name = null;
+ userInfo.iconPath = null;
+ }
+ users.add(userInfo);
}
return users;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index fb56a0c..5ce451f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -692,9 +692,7 @@
private final LogDecelerateInterpolator mLogDecelerateInterpolator
= new LogDecelerateInterpolator(100, 0);
- private boolean mForceWindowDrawsStatusBarBackground;
private final MutableBoolean mTmpBoolean = new MutableBoolean(false);
-
private static final int MSG_ENABLE_POINTER_LOCATION = 1;
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
@@ -1745,8 +1743,6 @@
mScreenshotChordEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableScreenshotChord);
- mForceWindowDrawsStatusBarBackground = mContext.getResources().getBoolean(
- R.bool.config_forceWindowDrawsStatusBarBackground);
mGlobalKeyManager = new GlobalKeyManager(mContext);
@@ -2217,9 +2213,12 @@
if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
+ final boolean forceWindowDrawsStatusBarBackground =
+ (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND)
+ != 0;
if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
- || (mForceWindowDrawsStatusBarBackground
- && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT)) {
+ || forceWindowDrawsStatusBarBackground
+ && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT) {
attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
}
}
@@ -4274,6 +4273,7 @@
}
final int fl = PolicyControl.getWindowFlags(win, attrs);
+ final int pfl = attrs.privateFlags;
final int sim = attrs.softInputMode;
final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null);
@@ -4369,7 +4369,7 @@
&& (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0
&& (fl & WindowManager.LayoutParams.
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
- && !mForceWindowDrawsStatusBarBackground) {
+ && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) {
// Ensure policy decor includes status bar
dcf.top = mStableTop;
}
@@ -7243,6 +7243,15 @@
return vis;
}
+ private boolean drawsSystemBarBackground(WindowState win) {
+ return win == null || (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+ }
+
+ private boolean forcesDrawStatusBarBackground(WindowState win) {
+ return win == null || (win.getAttrs().privateFlags
+ & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+ }
+
private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {
final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);
final boolean freeformStackVisible =
@@ -7256,11 +7265,22 @@
final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
// apply translucent bar vis flags
- WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen
+ WindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen
? mStatusBar
: mTopFullscreenOpaqueWindowState;
- vis = mStatusBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
- vis = mNavigationBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
+ vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
+ vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
+ final int dockedVis = mStatusBarController.applyTranslucentFlagLw(
+ mTopDockedOpaqueWindowState, 0, 0);
+
+ final boolean fullscreenDrawsStatusBarBackground =
+ (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState)
+ && (vis & View.STATUS_BAR_TRANSLUCENT) == 0)
+ || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState);
+ final boolean dockedDrawsStatusBarBackground =
+ (drawsSystemBarBackground(mTopDockedOpaqueWindowState)
+ && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0)
+ || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState);
// prevent status bar interaction from clearing certain flags
int type = win.getAttrs().type;
@@ -7277,18 +7297,16 @@
vis = (vis & ~flags) | (oldVis & flags);
}
- if ((!areTranslucentBarsAllowed() && transWin != mStatusBar)
+ if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {
+ vis |= View.STATUS_BAR_TRANSPARENT;
+ vis &= ~View.STATUS_BAR_TRANSLUCENT;
+ } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar)
|| forceOpaqueStatusBar) {
vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT);
}
vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing);
- if (mForceWindowDrawsStatusBarBackground) {
- vis |= View.STATUS_BAR_TRANSPARENT;
- vis &= ~View.STATUS_BAR_TRANSLUCENT;
- }
-
// update status bar
boolean immersiveSticky =
(vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index bcafddc..5b9d139 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -93,6 +93,7 @@
// Indicates whether we are rebooting into safe mode
public static final String REBOOT_SAFEMODE_PROPERTY = "persist.sys.safemode";
+ public static final String RO_SAFEMODE_PROPERTY = "ro.sys.safemode";
// Indicates whether we should stay in safe mode until ro.build.date.utc is newer than this
public static final String AUDIT_SAFEMODE_PROPERTY = "persist.sys.audit_safemode";
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 858f7c7..9c2c6bf 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -375,7 +375,7 @@
} else {
mTrustAgentService.onConfigure(Collections.EMPTY_LIST, null);
}
- final long maxTimeToLock = dpm.getMaximumTimeToLock(null);
+ final long maxTimeToLock = dpm.getMaximumTimeToLockForUserAndProfiles(mUserId);
if (maxTimeToLock != mMaximumTimeToLock) {
// If the timeout changes, cancel the alarm and send a timeout event to have
// the agent re-evaluate trust.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index e6e5a2d..f004b45 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -490,8 +490,15 @@
private void revokeNotificationPolicyAccess(String pkg) {
NotificationManager nm = mContext.getSystemService(NotificationManager.class);
if (mPreviousNotificationPolicyAccessPackage != null) {
- nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false);
- mPreviousNotificationPolicyAccessPackage = null;
+ if (mPreviousNotificationPolicyAccessPackage.equals(pkg)) {
+ // Remove any DND zen rules possibly created by the package.
+ nm.removeAutomaticZenRules(mPreviousNotificationPolicyAccessPackage);
+ // Remove Notification Policy Access.
+ nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false);
+ mPreviousNotificationPolicyAccessPackage = null;
+ } else {
+ Slog.e(TAG, "Couldn't remove Notification Policy Access for package: " + pkg);
+ }
}
}
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index d82b8b4..9486cfd 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -184,15 +184,18 @@
@Override
public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) {
- context.getPackageManager().deletePackage(packageName,
- new IPackageDeleteObserver.Stub() {
- public void packageDeleted(String packageName, int returnCode) {
- // Ignore returnCode since the deletion could fail, e.g. we might be trying
- // to delete a non-updated system-package (and we should still disable the
- // package)
- enablePackageForAllUsers(context, packageName, false);
+ enablePackageForAllUsers(context, packageName, false);
+ try {
+ PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
+ if (pm.getApplicationInfo(packageName, 0).isUpdatedSystemApp()) {
+ pm.deletePackage(packageName, new IPackageDeleteObserver.Stub() {
+ public void packageDeleted(String packageName, int returnCode) {
+ enablePackageForAllUsers(context, packageName, false);
+ }
+ }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS);
}
- }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS);
+ } catch (NameNotFoundException e) {
+ }
}
@Override
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 17efcc2..1f6fb2a 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -20,17 +20,12 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
import android.os.Binder;
import android.os.PatternMatcher;
import android.os.Process;
import android.os.ResultReceiver;
import android.os.UserHandle;
-import android.util.Base64;
import android.util.Slog;
import android.webkit.IWebViewUpdateService;
import android.webkit.WebViewFactory;
@@ -40,9 +35,7 @@
import com.android.server.SystemService;
import java.io.FileDescriptor;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
/**
* Private service to wait for the updatable WebView to be ready for use.
@@ -51,28 +44,18 @@
public class WebViewUpdateService extends SystemService {
private static final String TAG = "WebViewUpdateService";
- private static final int WAIT_TIMEOUT_MS = 4500; // KEY_DISPATCHING_TIMEOUT is 5000.
-
- // Keeps track of the number of running relro creations
- private int mNumRelroCreationsStarted = 0;
- private int mNumRelroCreationsFinished = 0;
- // Implies that we need to rerun relro creation because we are using an out-of-date package
- private boolean mWebViewPackageDirty = false;
- private boolean mAnyWebViewInstalled = false;
-
- private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE;
-
- private int mMinimumVersionCode = -1;
-
- // The WebView package currently in use (or the one we are preparing).
- private PackageInfo mCurrentWebViewPackage = null;
private BroadcastReceiver mWebViewUpdatedReceiver;
- private SystemInterface mSystemInterface;
+ private WebViewUpdateServiceImpl mImpl;
+
+ static final int PACKAGE_CHANGED = 0;
+ static final int PACKAGE_ADDED = 1;
+ static final int PACKAGE_ADDED_REPLACED = 2;
+ static final int PACKAGE_REMOVED = 3;
public WebViewUpdateService(Context context) {
super(context);
- mSystemInterface = new SystemImpl();
+ mImpl = new WebViewUpdateServiceImpl(context, new SystemImpl());
}
@Override
@@ -80,76 +63,36 @@
mWebViewUpdatedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // When a package is replaced we will receive two intents, one representing
- // the removal of the old package and one representing the addition of the
- // new package.
- // In the case where we receive an intent to remove the old version of the
- // package that is being replaced we early-out here so that we don't run the
- // update-logic twice.
- if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)
- && intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) {
- return;
- }
-
- // Ensure that we only heed PACKAGE_CHANGED intents if they change an entire
- // package, not just a component
- if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)) {
- if (!entirePackageChanged(intent)) {
- return;
- }
- }
-
- if (intent.getAction().equals(Intent.ACTION_USER_ADDED)) {
- int userId =
- intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
- handleNewUser(userId);
- return;
- }
-
- updateFallbackState(context, intent);
-
- for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
- String webviewPackage = "package:" + provider.packageName;
-
- if (webviewPackage.equals(intent.getDataString())) {
- boolean updateWebView = false;
- boolean removedOrChangedOldPackage = false;
- String oldProviderName = null;
- PackageInfo newPackage = null;
- synchronized(WebViewUpdateService.this) {
- try {
- newPackage = findPreferredWebViewPackage();
- if (mCurrentWebViewPackage != null)
- oldProviderName = mCurrentWebViewPackage.packageName;
- // Only trigger update actions if the updated package is the one
- // that will be used, or the one that was in use before the
- // update, or if we haven't seen a valid WebView package before.
- updateWebView =
- provider.packageName.equals(newPackage.packageName)
- || provider.packageName.equals(oldProviderName)
- || mCurrentWebViewPackage == null;
- // We removed the old package if we received an intent to remove
- // or replace the old package.
- removedOrChangedOldPackage =
- provider.packageName.equals(oldProviderName);
- if (updateWebView) {
- onWebViewProviderChanged(newPackage);
- }
- } catch (WebViewFactory.MissingWebViewPackageException e) {
- Slog.e(TAG, "Could not find valid WebView package to create " +
- "relro with " + e);
- }
+ switch (intent.getAction()) {
+ case Intent.ACTION_PACKAGE_REMOVED:
+ // When a package is replaced we will receive two intents, one
+ // representing the removal of the old package and one representing the
+ // addition of the new package.
+ // In the case where we receive an intent to remove the old version of
+ // the package that is being replaced we early-out here so that we don't
+ // run the update-logic twice.
+ if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) return;
+ mImpl.packageStateChanged(packageNameFromIntent(intent),
+ PACKAGE_REMOVED);
+ break;
+ case Intent.ACTION_PACKAGE_CHANGED:
+ // Ensure that we only heed PACKAGE_CHANGED intents if they change an
+ // entire package, not just a component
+ if (entirePackageChanged(intent)) {
+ mImpl.packageStateChanged(packageNameFromIntent(intent),
+ PACKAGE_CHANGED);
}
- if(updateWebView && !removedOrChangedOldPackage
- && oldProviderName != null) {
- // If the provider change is the result of adding or replacing a
- // package that was not the previous provider then we must kill
- // packages dependent on the old package ourselves. The framework
- // only kills dependents of packages that are being removed.
- mSystemInterface.killPackageDependents(oldProviderName);
- }
- return;
- }
+ break;
+ case Intent.ACTION_PACKAGE_ADDED:
+ mImpl.packageStateChanged(packageNameFromIntent(intent),
+ (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)
+ ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED));
+ break;
+ case Intent.ACTION_USER_ADDED:
+ int userId =
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ mImpl.handleNewUser(userId);
+ break;
}
}
};
@@ -159,7 +102,7 @@
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
// Make sure we only receive intents for WebView packages from our config file.
- for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
+ for (WebViewProviderInfo provider : mImpl.getWebViewPackages()) {
filter.addDataSchemeSpecificPart(provider.packageName, PatternMatcher.PATTERN_LITERAL);
}
getContext().registerReceiver(mWebViewUpdatedReceiver, filter);
@@ -171,349 +114,12 @@
publishBinderService("webviewupdate", new BinderService(), true /*allowIsolated*/);
}
- private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
- for (WebViewProviderInfo provider : providers) {
- if (provider.availableByDefault && !provider.isFallback) {
- try {
- PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(provider);
- if (isEnabledPackage(packageInfo) && isValidProvider(provider, packageInfo)) {
- return true;
- }
- } catch (NameNotFoundException e) {
- // A non-existent provider is neither valid nor enabled
- }
- }
- }
- return false;
- }
-
- /**
- * Called when a new user has been added to update the state of its fallback package.
- */
- void handleNewUser(int userId) {
- if (!mSystemInterface.isFallbackLogicEnabled()) return;
-
- WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
- WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
- if (fallbackProvider == null) return;
-
- mSystemInterface.enablePackageForUser(fallbackProvider.packageName,
- !existsValidNonFallbackProvider(webviewProviders), userId);
- }
-
- /**
- * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback
- * package that is valid (and available by default) then disable the fallback package,
- * otherwise, enable the fallback package.
- */
- void updateFallbackState(final Context context, final Intent intent) {
- if (!mSystemInterface.isFallbackLogicEnabled()) return;
-
- WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-
- if (intent != null && (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
- || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED))) {
- // A package was changed / updated / downgraded, early out if it is not one of the
- // webview packages that are available by default.
- String changedPackage = null;
- for (WebViewProviderInfo provider : webviewProviders) {
- String webviewPackage = "package:" + provider.packageName;
- if (webviewPackage.equals(intent.getDataString())) {
- if (provider.availableByDefault) {
- changedPackage = provider.packageName;
- }
- break;
- }
- }
- if (changedPackage == null) return;
- }
-
- // If there exists a valid and enabled non-fallback package - disable the fallback
- // package, otherwise, enable it.
- WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
- if (fallbackProvider == null) return;
- boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders);
-
- boolean isFallbackEnabled = false;
- try {
- isFallbackEnabled =
- isEnabledPackage(mSystemInterface.getPackageInfoForProvider(fallbackProvider));
- } catch (NameNotFoundException e) {
- }
-
- if (existsValidNonFallbackProvider
- // During an OTA the primary user's WebView state might differ from other users', so
- // ignore the state of that user during boot.
- && (isFallbackEnabled || intent == null)) {
- mSystemInterface.uninstallAndDisablePackageForAllUsers(context,
- fallbackProvider.packageName);
- } else if (!existsValidNonFallbackProvider
- // During an OTA the primary user's WebView state might differ from other users', so
- // ignore the state of that user during boot.
- && (!isFallbackEnabled || intent==null)) {
- // Enable the fallback package for all users.
- mSystemInterface.enablePackageForAllUsers(context, fallbackProvider.packageName, true);
- }
- }
-
- /**
- * Returns the only fallback provider, or null if there is none.
- */
- private static WebViewProviderInfo getFallbackProvider(WebViewProviderInfo[] webviewPackages) {
- for (WebViewProviderInfo provider : webviewPackages) {
- if (provider.isFallback) {
- return provider;
- }
- }
- return null;
- }
-
- private boolean isFallbackPackage(String packageName) {
- if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false;
-
- WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages();
- WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages);
- return (fallbackProvider != null
- && packageName.equals(fallbackProvider.packageName));
- }
-
- /**
- * Perform any WebView loading preparations that must happen at boot from the system server,
- * after the package manager has started or after an update to the webview is installed.
- * This must be called in the system server.
- * Currently, this means spawning the child processes which will create the relro files.
- */
public void prepareWebViewInSystemServer() {
- updateFallbackState(getContext(), null);
- try {
- synchronized(this) {
- mCurrentWebViewPackage = findPreferredWebViewPackage();
- onWebViewProviderChanged(mCurrentWebViewPackage);
- }
- } catch (Throwable t) {
- // Log and discard errors at this stage as we must not crash the system server.
- Slog.e(TAG, "error preparing webview provider from system server", t);
- }
+ mImpl.prepareWebViewInSystemServer();
}
-
- /**
- * Change WebView provider and provider setting and kill packages using the old provider.
- * Return the new provider (in case we are in the middle of creating relro files this new
- * provider will not be in use directly, but will when the relros are done).
- */
- private String changeProviderAndSetting(String newProviderName) {
- PackageInfo oldPackage = null;
- PackageInfo newPackage = null;
- synchronized(this) {
- oldPackage = mCurrentWebViewPackage;
- mSystemInterface.updateUserSetting(getContext(), newProviderName);
-
- try {
- newPackage = findPreferredWebViewPackage();
- if (oldPackage != null && newPackage.packageName.equals(oldPackage.packageName)) {
- // If we don't perform the user change, revert the settings change.
- mSystemInterface.updateUserSetting(getContext(), newPackage.packageName);
- return newPackage.packageName;
- }
- } catch (WebViewFactory.MissingWebViewPackageException e) {
- Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView package "
- + e);
- // If we don't perform the user change but don't have an installed WebView package,
- // we will have changed the setting and it will be used when a package is available.
- return newProviderName;
- }
- onWebViewProviderChanged(newPackage);
- }
- // Kill apps using the old provider
- if (oldPackage != null) {
- mSystemInterface.killPackageDependents(oldPackage.packageName);
- }
- return newPackage.packageName;
- }
-
- /**
- * This is called when we change WebView provider, either when the current provider is updated
- * or a new provider is chosen / takes precedence.
- */
- private void onWebViewProviderChanged(PackageInfo newPackage) {
- synchronized(this) {
- mAnyWebViewInstalled = true;
- if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
- mCurrentWebViewPackage = newPackage;
- mSystemInterface.updateUserSetting(getContext(), newPackage.packageName);
-
- // The relro creations might 'finish' (not start at all) before
- // WebViewFactory.onWebViewProviderChanged which means we might not know the number
- // of started creations before they finish.
- mNumRelroCreationsStarted = NUMBER_OF_RELROS_UNKNOWN;
- mNumRelroCreationsFinished = 0;
- mNumRelroCreationsStarted = mSystemInterface.onWebViewProviderChanged(newPackage);
- // If the relro creations finish before we know the number of started creations we
- // will have to do any cleanup/notifying here.
- checkIfRelrosDoneLocked();
- } else {
- mWebViewPackageDirty = true;
- }
- }
- }
-
- private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() {
- WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
- List<ProviderAndPackageInfo> providers = new ArrayList<>();
- for(int n = 0; n < allProviders.length; n++) {
- try {
- PackageInfo packageInfo =
- mSystemInterface.getPackageInfoForProvider(allProviders[n]);
- if (isValidProvider(allProviders[n], packageInfo)) {
- providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo));
- }
- } catch (NameNotFoundException e) {
- // Don't add non-existent packages
- }
- }
- return providers.toArray(new ProviderAndPackageInfo[providers.size()]);
- }
-
- /**
- * Fetch only the currently valid WebView packages.
- **/
- private WebViewProviderInfo[] getValidWebViewPackages() {
- ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos();
- WebViewProviderInfo[] providers = new WebViewProviderInfo[providersAndPackageInfos.length];
- for(int n = 0; n < providersAndPackageInfos.length; n++) {
- providers[n] = providersAndPackageInfos[n].provider;
- }
- return providers;
- }
-
- private class ProviderAndPackageInfo {
- public final WebViewProviderInfo provider;
- public final PackageInfo packageInfo;
-
- public ProviderAndPackageInfo(WebViewProviderInfo provider, PackageInfo packageInfo) {
- this.provider = provider;
- this.packageInfo = packageInfo;
- }
- }
-
- /**
- * Returns either the package info of the WebView provider determined in the following way:
- * If the user has chosen a provider then use that if it is valid,
- * otherwise use the first package in the webview priority list that is valid.
- *
- * @hide
- */
- private PackageInfo findPreferredWebViewPackage() {
- ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();
-
- String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(getContext());
-
- // If the user has chosen provider, use that
- for (ProviderAndPackageInfo providerAndPackage : providers) {
- if (providerAndPackage.provider.packageName.equals(userChosenProvider)
- && isEnabledPackage(providerAndPackage.packageInfo)) {
- return providerAndPackage.packageInfo;
- }
- }
-
- // User did not choose, or the choice failed; use the most stable provider that is
- // enabled and available by default (not through user choice).
- for (ProviderAndPackageInfo providerAndPackage : providers) {
- if (providerAndPackage.provider.availableByDefault
- && isEnabledPackage(providerAndPackage.packageInfo)) {
- return providerAndPackage.packageInfo;
- }
- }
-
- // Could not find any enabled package either, use the most stable provider.
- for (ProviderAndPackageInfo providerAndPackage : providers) {
- return providerAndPackage.packageInfo;
- }
-
- mAnyWebViewInstalled = false;
- throw new WebViewFactory.MissingWebViewPackageException(
- "Could not find a loadable WebView package");
- }
-
-
- /**
- * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode of
- * all available-by-default and non-fallback WebView provider packages. If there is no such
- * WebView provider package on the system, then return -1, which means all positive versionCode
- * WebView packages are accepted.
- */
- private int getMinimumVersionCode() {
- if (mMinimumVersionCode > 0) {
- return mMinimumVersionCode;
- }
-
- for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
- if (provider.availableByDefault && !provider.isFallback) {
- try {
- int versionCode = mSystemInterface.getFactoryPackageVersion(provider.packageName);
- if (mMinimumVersionCode < 0 || versionCode < mMinimumVersionCode) {
- mMinimumVersionCode = versionCode;
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Safe to ignore.
- }
- }
- }
-
- return mMinimumVersionCode;
- }
-
- /**
- * Returns whether this provider is valid for use as a WebView provider.
- */
- private boolean isValidProvider(WebViewProviderInfo configInfo,
- PackageInfo packageInfo) {
- if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
- && packageInfo.versionCode < getMinimumVersionCode()
- && !mSystemInterface.systemIsDebuggable()) {
- // Non-system package webview providers may be downgraded arbitrarily low, prevent that
- // by enforcing minimum version code. This check is only enforced for user builds.
- return false;
- }
- if (providerHasValidSignature(configInfo, packageInfo)
- && WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) {
- return true;
- }
- return false;
- }
-
- private boolean providerHasValidSignature(WebViewProviderInfo provider,
- PackageInfo packageInfo) {
- if (mSystemInterface.systemIsDebuggable()) {
- return true;
- }
- Signature[] packageSignatures;
- // If no signature is declared, instead check whether the package is included in the
- // system.
- if (provider.signatures == null || provider.signatures.length == 0) {
- return packageInfo.applicationInfo.isSystemApp();
- }
- packageSignatures = packageInfo.signatures;
- if (packageSignatures.length != 1)
- return false;
-
- final byte[] packageSignature = packageSignatures[0].toByteArray();
- // Return whether the package signature matches any of the valid signatures
- for (String signature : provider.signatures) {
- final byte[] validSignature = Base64.decode(signature, Base64.DEFAULT);
- if (Arrays.equals(packageSignature, validSignature))
- return true;
- }
- return false;
- }
-
- /**
- * Returns whether the given package is enabled.
- * This state can be changed by the user from Settings->Apps
- */
- public boolean isEnabledPackage(PackageInfo packageInfo) {
- return packageInfo.applicationInfo.enabled;
+ private static String packageNameFromIntent(Intent intent) {
+ return intent.getDataString().substring("package:".length());
}
/**
@@ -528,32 +134,6 @@
intent.getDataString().substring("package:".length()));
}
- /**
- * Returns whether WebView is ready and is not going to go through its preparation phase again
- * directly.
- */
- private boolean webViewIsReadyLocked() {
- return !mWebViewPackageDirty
- && (mNumRelroCreationsStarted == mNumRelroCreationsFinished)
- // The current package might be replaced though we haven't received an intent declaring
- // this yet, the following flag makes anyone loading WebView to wait in this case.
- && mAnyWebViewInstalled;
- }
-
- private void checkIfRelrosDoneLocked() {
- if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
- if (mWebViewPackageDirty) {
- mWebViewPackageDirty = false;
- // If we have changed provider since we started the relro creation we need to
- // redo the whole process using the new package instead.
- PackageInfo newPackage = findPreferredWebViewPackage();
- onWebViewProviderChanged(newPackage);
- } else {
- this.notifyAll();
- }
- }
- }
-
private class BinderService extends IWebViewUpdateService.Stub {
@Override
@@ -581,10 +161,7 @@
long callingId = Binder.clearCallingIdentity();
try {
- synchronized (WebViewUpdateService.this) {
- mNumRelroCreationsFinished++;
- checkIfRelrosDoneLocked();
- }
+ WebViewUpdateService.this.mImpl.notifyRelroCreationCompleted();
} finally {
Binder.restoreCallingIdentity(callingId);
}
@@ -604,34 +181,7 @@
throw new IllegalStateException("Cannot create a WebView from the SystemServer");
}
- PackageInfo webViewPackage = null;
- final long NS_PER_MS = 1000000;
- final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS;
- boolean webViewReady = false;
- int webViewStatus = WebViewFactory.LIBLOAD_SUCCESS;
- synchronized (WebViewUpdateService.this) {
- webViewReady = WebViewUpdateService.this.webViewIsReadyLocked();
- while (!webViewReady) {
- final long timeNowMs = System.nanoTime() / NS_PER_MS;
- if (timeNowMs >= timeoutTimeMs) break;
- try {
- WebViewUpdateService.this.wait(timeoutTimeMs - timeNowMs);
- } catch (InterruptedException e) {}
- webViewReady = WebViewUpdateService.this.webViewIsReadyLocked();
- }
- // Make sure we return the provider that was used to create the relro file
- webViewPackage = WebViewUpdateService.this.mCurrentWebViewPackage;
- if (webViewReady) {
- } else if (!mAnyWebViewInstalled) {
- webViewStatus = WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES;
- } else {
- // Either the current relro creation isn't done yet, or the new relro creatioin
- // hasn't kicked off yet (the last relro creation used an out-of-date WebView).
- webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO;
- }
- }
- if (!webViewReady) Slog.w(TAG, "creating relro file timed out");
- return new WebViewProviderResponse(webViewPackage, webViewStatus);
+ return WebViewUpdateService.this.mImpl.waitForAndGetProvider();
}
/**
@@ -652,7 +202,8 @@
long callingId = Binder.clearCallingIdentity();
try {
- return WebViewUpdateService.this.changeProviderAndSetting(newProvider);
+ return WebViewUpdateService.this.mImpl.changeProviderAndSetting(
+ newProvider);
} finally {
Binder.restoreCallingIdentity(callingId);
}
@@ -660,26 +211,22 @@
@Override // Binder call
public WebViewProviderInfo[] getValidWebViewPackages() {
- return WebViewUpdateService.this.getValidWebViewPackages();
+ return WebViewUpdateService.this.mImpl.getValidWebViewPackages();
}
@Override // Binder call
public WebViewProviderInfo[] getAllWebViewPackages() {
- return WebViewUpdateService.this.mSystemInterface.getWebViewPackages();
+ return WebViewUpdateService.this.mImpl.getWebViewPackages();
}
@Override // Binder call
public String getCurrentWebViewPackageName() {
- synchronized(WebViewUpdateService.this) {
- if (WebViewUpdateService.this.mCurrentWebViewPackage == null)
- return null;
- return WebViewUpdateService.this.mCurrentWebViewPackage.packageName;
- }
+ return WebViewUpdateService.this.mImpl.getCurrentWebViewPackageName();
}
@Override // Binder call
public boolean isFallbackPackage(String packageName) {
- return WebViewUpdateService.this.isFallbackPackage(packageName);
+ return WebViewUpdateService.this.mImpl.isFallbackPackage(packageName);
}
@Override // Binder call
@@ -695,7 +242,7 @@
throw new SecurityException(msg);
}
- WebViewUpdateService.this.mSystemInterface.enableFallbackLogic(enable);
+ WebViewUpdateService.this.mImpl.enableFallbackLogic(enable);
}
}
}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
new file mode 100644
index 0000000..32b195b
--- /dev/null
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -0,0 +1,588 @@
+/*
+ * 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.webkit;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.util.Base64;
+import android.util.Slog;
+import android.webkit.WebViewFactory;
+import android.webkit.WebViewProviderInfo;
+import android.webkit.WebViewProviderResponse;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Implementation of the WebViewUpdateService.
+ * This class doesn't depend on the android system like the actual Service does and can be used
+ * directly by tests (as long as they implement a SystemInterface).
+ * @hide
+ */
+public class WebViewUpdateServiceImpl {
+ private static final String TAG = WebViewUpdateServiceImpl.class.getSimpleName();
+
+ private SystemInterface mSystemInterface;
+ private WebViewUpdater mWebViewUpdater;
+ private Context mContext;
+
+ public WebViewUpdateServiceImpl(Context context, SystemInterface systemInterface) {
+ mContext = context;
+ mSystemInterface = systemInterface;
+ mWebViewUpdater = new WebViewUpdater(mContext, mSystemInterface);
+ }
+
+ void packageStateChanged(String packageName, int changedState) {
+ updateFallbackStateOnPackageChange(packageName, changedState);
+ mWebViewUpdater.packageStateChanged(packageName, changedState);
+ }
+
+ void prepareWebViewInSystemServer() {
+ updateFallbackStateOnBoot();
+ mWebViewUpdater.prepareWebViewInSystemServer();
+ }
+
+ private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
+ for (WebViewProviderInfo provider : providers) {
+ if (provider.availableByDefault && !provider.isFallback) {
+ try {
+ PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(provider);
+ if (isEnabledPackage(packageInfo)
+ && mWebViewUpdater.isValidProvider(provider, packageInfo)) {
+ return true;
+ }
+ } catch (NameNotFoundException e) {
+ // A non-existent provider is neither valid nor enabled
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Called when a new user has been added to update the state of its fallback package.
+ */
+ void handleNewUser(int userId) {
+ if (!mSystemInterface.isFallbackLogicEnabled()) return;
+
+ WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
+ WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
+ if (fallbackProvider == null) return;
+
+ mSystemInterface.enablePackageForUser(fallbackProvider.packageName,
+ !existsValidNonFallbackProvider(webviewProviders), userId);
+ }
+
+ void notifyRelroCreationCompleted() {
+ mWebViewUpdater.notifyRelroCreationCompleted();
+ }
+
+ WebViewProviderResponse waitForAndGetProvider() {
+ return mWebViewUpdater.waitForAndGetProvider();
+ }
+
+ String changeProviderAndSetting(String newProvider) {
+ return mWebViewUpdater.changeProviderAndSetting(newProvider);
+ }
+
+ WebViewProviderInfo[] getValidWebViewPackages() {
+ return mWebViewUpdater.getValidWebViewPackages();
+ }
+
+ WebViewProviderInfo[] getWebViewPackages() {
+ return mSystemInterface.getWebViewPackages();
+ }
+
+ String getCurrentWebViewPackageName() {
+ return mWebViewUpdater.getCurrentWebViewPackageName();
+ }
+
+ void enableFallbackLogic(boolean enable) {
+ mSystemInterface.enableFallbackLogic(enable);
+ }
+
+ private void updateFallbackStateOnBoot() {
+ WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
+ updateFallbackState(webviewProviders, true);
+ }
+
+ /**
+ * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback
+ * package that is valid (and available by default) then disable the fallback package,
+ * otherwise, enable the fallback package.
+ */
+ private void updateFallbackStateOnPackageChange(String changedPackage, int changedState) {
+ if (!mSystemInterface.isFallbackLogicEnabled()) return;
+
+ WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
+
+ // A package was changed / updated / downgraded, early out if it is not one of the
+ // webview packages that are available by default.
+ boolean changedPackageAvailableByDefault = false;
+ for (WebViewProviderInfo provider : webviewProviders) {
+ if (provider.packageName.equals(changedPackage)) {
+ if (provider.availableByDefault) {
+ changedPackageAvailableByDefault = true;
+ }
+ break;
+ }
+ }
+ if (!changedPackageAvailableByDefault) return;
+ updateFallbackState(webviewProviders, false);
+ }
+
+ private void updateFallbackState(WebViewProviderInfo[] webviewProviders, boolean isBoot) {
+ // If there exists a valid and enabled non-fallback package - disable the fallback
+ // package, otherwise, enable it.
+ WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
+ if (fallbackProvider == null) return;
+ boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders);
+
+ boolean isFallbackEnabled = false;
+ try {
+ isFallbackEnabled = isEnabledPackage(
+ mSystemInterface.getPackageInfoForProvider(fallbackProvider));
+ } catch (NameNotFoundException e) {
+ }
+
+ if (existsValidNonFallbackProvider
+ // During an OTA the primary user's WebView state might differ from other users', so
+ // ignore the state of that user during boot.
+ && (isFallbackEnabled || isBoot)) {
+ mSystemInterface.uninstallAndDisablePackageForAllUsers(mContext,
+ fallbackProvider.packageName);
+ } else if (!existsValidNonFallbackProvider
+ // During an OTA the primary user's WebView state might differ from other users', so
+ // ignore the state of that user during boot.
+ && (!isFallbackEnabled || isBoot)) {
+ // Enable the fallback package for all users.
+ mSystemInterface.enablePackageForAllUsers(mContext,
+ fallbackProvider.packageName, true);
+ }
+ }
+
+ /**
+ * Returns the only fallback provider in the set of given packages, or null if there is none.
+ */
+ private static WebViewProviderInfo getFallbackProvider(WebViewProviderInfo[] webviewPackages) {
+ for (WebViewProviderInfo provider : webviewPackages) {
+ if (provider.isFallback) {
+ return provider;
+ }
+ }
+ return null;
+ }
+
+ boolean isFallbackPackage(String packageName) {
+ if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false;
+
+ WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages();
+ WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages);
+ return (fallbackProvider != null
+ && packageName.equals(fallbackProvider.packageName));
+ }
+
+ /**
+ * Class that decides what WebView implementation to use and prepares that implementation for
+ * use.
+ */
+ private static class WebViewUpdater {
+ private Context mContext;
+ private SystemInterface mSystemInterface;
+ private int mMinimumVersionCode = -1;
+
+ public WebViewUpdater(Context context, SystemInterface systemInterface) {
+ mContext = context;
+ mSystemInterface = systemInterface;
+ }
+
+ private static final int WAIT_TIMEOUT_MS = 4500; // KEY_DISPATCHING_TIMEOUT is 5000.
+
+ // Keeps track of the number of running relro creations
+ private int mNumRelroCreationsStarted = 0;
+ private int mNumRelroCreationsFinished = 0;
+ // Implies that we need to rerun relro creation because we are using an out-of-date package
+ private boolean mWebViewPackageDirty = false;
+ private boolean mAnyWebViewInstalled = false;
+
+ private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE;
+
+ // The WebView package currently in use (or the one we are preparing).
+ private PackageInfo mCurrentWebViewPackage = null;
+
+ private Object mLock = new Object();
+
+ public void packageStateChanged(String packageName, int changedState) {
+ for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
+ String webviewPackage = provider.packageName;
+
+ if (webviewPackage.equals(packageName)) {
+ boolean updateWebView = false;
+ boolean removedOrChangedOldPackage = false;
+ String oldProviderName = null;
+ PackageInfo newPackage = null;
+ synchronized(mLock) {
+ try {
+ newPackage = findPreferredWebViewPackage();
+ if (mCurrentWebViewPackage != null)
+ oldProviderName = mCurrentWebViewPackage.packageName;
+ // Only trigger update actions if the updated package is the one
+ // that will be used, or the one that was in use before the
+ // update, or if we haven't seen a valid WebView package before.
+ updateWebView =
+ provider.packageName.equals(newPackage.packageName)
+ || provider.packageName.equals(oldProviderName)
+ || mCurrentWebViewPackage == null;
+ // We removed the old package if we received an intent to remove
+ // or replace the old package.
+ removedOrChangedOldPackage =
+ provider.packageName.equals(oldProviderName);
+ if (updateWebView) {
+ onWebViewProviderChanged(newPackage);
+ }
+ } catch (WebViewFactory.MissingWebViewPackageException e) {
+ Slog.e(TAG, "Could not find valid WebView package to create " +
+ "relro with " + e);
+ }
+ }
+ if(updateWebView && !removedOrChangedOldPackage
+ && oldProviderName != null) {
+ // If the provider change is the result of adding or replacing a
+ // package that was not the previous provider then we must kill
+ // packages dependent on the old package ourselves. The framework
+ // only kills dependents of packages that are being removed.
+ mSystemInterface.killPackageDependents(oldProviderName);
+ }
+ return;
+ }
+ }
+ }
+
+ public void prepareWebViewInSystemServer() {
+ try {
+ synchronized(mLock) {
+ mCurrentWebViewPackage = findPreferredWebViewPackage();
+ onWebViewProviderChanged(mCurrentWebViewPackage);
+ }
+ } catch (Throwable t) {
+ // Log and discard errors at this stage as we must not crash the system server.
+ Slog.e(TAG, "error preparing webview provider from system server", t);
+ }
+ }
+
+ /**
+ * Change WebView provider and provider setting and kill packages using the old provider.
+ * Return the new provider (in case we are in the middle of creating relro files this new
+ * provider will not be in use directly, but will when the relros are done).
+ */
+ public String changeProviderAndSetting(String newProviderName) {
+ PackageInfo oldPackage = null;
+ PackageInfo newPackage = null;
+ synchronized(mLock) {
+ oldPackage = mCurrentWebViewPackage;
+ mSystemInterface.updateUserSetting(mContext, newProviderName);
+
+ try {
+ newPackage = findPreferredWebViewPackage();
+ if (oldPackage != null
+ && newPackage.packageName.equals(oldPackage.packageName)) {
+ // If we don't perform the user change, revert the settings change.
+ mSystemInterface.updateUserSetting(mContext, newPackage.packageName);
+ return newPackage.packageName;
+ }
+ } catch (WebViewFactory.MissingWebViewPackageException e) {
+ Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView " +
+ "package " + e);
+ // If we don't perform the user change but don't have an installed WebView
+ // package, we will have changed the setting and it will be used when a package
+ // is available.
+ return newProviderName;
+ }
+ onWebViewProviderChanged(newPackage);
+ }
+ // Kill apps using the old provider
+ if (oldPackage != null) {
+ mSystemInterface.killPackageDependents(oldPackage.packageName);
+ }
+ return newPackage.packageName;
+ }
+
+ /**
+ * This is called when we change WebView provider, either when the current provider is
+ * updated or a new provider is chosen / takes precedence.
+ */
+ private void onWebViewProviderChanged(PackageInfo newPackage) {
+ synchronized(mLock) {
+ mAnyWebViewInstalled = true;
+ if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
+ mCurrentWebViewPackage = newPackage;
+ mSystemInterface.updateUserSetting(mContext, newPackage.packageName);
+
+ // The relro creations might 'finish' (not start at all) before
+ // WebViewFactory.onWebViewProviderChanged which means we might not know the
+ // number of started creations before they finish.
+ mNumRelroCreationsStarted = NUMBER_OF_RELROS_UNKNOWN;
+ mNumRelroCreationsFinished = 0;
+ mNumRelroCreationsStarted =
+ mSystemInterface.onWebViewProviderChanged(newPackage);
+ // If the relro creations finish before we know the number of started creations
+ // we will have to do any cleanup/notifying here.
+ checkIfRelrosDoneLocked();
+ } else {
+ mWebViewPackageDirty = true;
+ }
+ }
+ }
+
+ private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() {
+ WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
+ List<ProviderAndPackageInfo> providers = new ArrayList<>();
+ for(int n = 0; n < allProviders.length; n++) {
+ try {
+ PackageInfo packageInfo =
+ mSystemInterface.getPackageInfoForProvider(allProviders[n]);
+ if (isValidProvider(allProviders[n], packageInfo)) {
+ providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo));
+ }
+ } catch (NameNotFoundException e) {
+ // Don't add non-existent packages
+ }
+ }
+ return providers.toArray(new ProviderAndPackageInfo[providers.size()]);
+ }
+
+ /**
+ * Fetch only the currently valid WebView packages.
+ **/
+ public WebViewProviderInfo[] getValidWebViewPackages() {
+ ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos();
+ WebViewProviderInfo[] providers =
+ new WebViewProviderInfo[providersAndPackageInfos.length];
+ for(int n = 0; n < providersAndPackageInfos.length; n++) {
+ providers[n] = providersAndPackageInfos[n].provider;
+ }
+ return providers;
+ }
+
+
+ private class ProviderAndPackageInfo {
+ public final WebViewProviderInfo provider;
+ public final PackageInfo packageInfo;
+
+ public ProviderAndPackageInfo(WebViewProviderInfo provider, PackageInfo packageInfo) {
+ this.provider = provider;
+ this.packageInfo = packageInfo;
+ }
+ }
+
+ /**
+ * Returns either the package info of the WebView provider determined in the following way:
+ * If the user has chosen a provider then use that if it is valid,
+ * otherwise use the first package in the webview priority list that is valid.
+ *
+ */
+ private PackageInfo findPreferredWebViewPackage() {
+ ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();
+
+ String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext);
+
+ // If the user has chosen provider, use that
+ for (ProviderAndPackageInfo providerAndPackage : providers) {
+ if (providerAndPackage.provider.packageName.equals(userChosenProvider)
+ && isEnabledPackage(providerAndPackage.packageInfo)) {
+ return providerAndPackage.packageInfo;
+ }
+ }
+
+ // User did not choose, or the choice failed; use the most stable provider that is
+ // enabled and available by default (not through user choice).
+ for (ProviderAndPackageInfo providerAndPackage : providers) {
+ if (providerAndPackage.provider.availableByDefault
+ && isEnabledPackage(providerAndPackage.packageInfo)) {
+ return providerAndPackage.packageInfo;
+ }
+ }
+
+ // Could not find any enabled package either, use the most stable provider.
+ for (ProviderAndPackageInfo providerAndPackage : providers) {
+ return providerAndPackage.packageInfo;
+ }
+
+ mAnyWebViewInstalled = false;
+ throw new WebViewFactory.MissingWebViewPackageException(
+ "Could not find a loadable WebView package");
+ }
+
+ public void notifyRelroCreationCompleted() {
+ synchronized (mLock) {
+ mNumRelroCreationsFinished++;
+ checkIfRelrosDoneLocked();
+ }
+ }
+
+ public WebViewProviderResponse waitForAndGetProvider() {
+ PackageInfo webViewPackage = null;
+ final long NS_PER_MS = 1000000;
+ final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS;
+ boolean webViewReady = false;
+ int webViewStatus = WebViewFactory.LIBLOAD_SUCCESS;
+ synchronized (mLock) {
+ webViewReady = webViewIsReadyLocked();
+ while (!webViewReady) {
+ final long timeNowMs = System.nanoTime() / NS_PER_MS;
+ if (timeNowMs >= timeoutTimeMs) break;
+ try {
+ mLock.wait(timeoutTimeMs - timeNowMs);
+ } catch (InterruptedException e) {}
+ webViewReady = webViewIsReadyLocked();
+ }
+ // Make sure we return the provider that was used to create the relro file
+ webViewPackage = mCurrentWebViewPackage;
+ if (webViewReady) {
+ } else if (!mAnyWebViewInstalled) {
+ webViewStatus = WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES;
+ } else {
+ // Either the current relro creation isn't done yet, or the new relro creatioin
+ // hasn't kicked off yet (the last relro creation used an out-of-date WebView).
+ webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO;
+ }
+ }
+ if (!webViewReady) Slog.w(TAG, "creating relro file timed out");
+ return new WebViewProviderResponse(webViewPackage, webViewStatus);
+ }
+
+ public String getCurrentWebViewPackageName() {
+ synchronized(mLock) {
+ if (mCurrentWebViewPackage == null)
+ return null;
+ return mCurrentWebViewPackage.packageName;
+ }
+ }
+
+ /**
+ * Returns whether WebView is ready and is not going to go through its preparation phase
+ * again directly.
+ */
+ private boolean webViewIsReadyLocked() {
+ return !mWebViewPackageDirty
+ && (mNumRelroCreationsStarted == mNumRelroCreationsFinished)
+ // The current package might be replaced though we haven't received an intent
+ // declaring this yet, the following flag makes anyone loading WebView to wait in
+ // this case.
+ && mAnyWebViewInstalled;
+ }
+
+ private void checkIfRelrosDoneLocked() {
+ if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
+ if (mWebViewPackageDirty) {
+ mWebViewPackageDirty = false;
+ // If we have changed provider since we started the relro creation we need to
+ // redo the whole process using the new package instead.
+ PackageInfo newPackage = findPreferredWebViewPackage();
+ onWebViewProviderChanged(newPackage);
+ } else {
+ mLock.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Returns whether this provider is valid for use as a WebView provider.
+ */
+ public boolean isValidProvider(WebViewProviderInfo configInfo,
+ PackageInfo packageInfo) {
+ if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && packageInfo.versionCode < getMinimumVersionCode()
+ && !mSystemInterface.systemIsDebuggable()) {
+ // Non-system package webview providers may be downgraded arbitrarily low, prevent
+ // that by enforcing minimum version code. This check is only enforced for user
+ // builds.
+ return false;
+ }
+ if (providerHasValidSignature(configInfo, packageInfo, mSystemInterface) &&
+ WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode
+ * of all available-by-default and non-fallback WebView provider packages. If there is no
+ * such WebView provider package on the system, then return -1, which means all positive
+ * versionCode WebView packages are accepted.
+ */
+ private int getMinimumVersionCode() {
+ if (mMinimumVersionCode > 0) {
+ return mMinimumVersionCode;
+ }
+
+ for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
+ if (provider.availableByDefault && !provider.isFallback) {
+ try {
+ int versionCode =
+ mSystemInterface.getFactoryPackageVersion(provider.packageName);
+ if (mMinimumVersionCode < 0 || versionCode < mMinimumVersionCode) {
+ mMinimumVersionCode = versionCode;
+ }
+ } catch (NameNotFoundException e) {
+ // Safe to ignore.
+ }
+ }
+ }
+
+ return mMinimumVersionCode;
+ }
+ }
+
+ private static boolean providerHasValidSignature(WebViewProviderInfo provider,
+ PackageInfo packageInfo, SystemInterface systemInterface) {
+ if (systemInterface.systemIsDebuggable()) {
+ return true;
+ }
+ Signature[] packageSignatures;
+ // If no signature is declared, instead check whether the package is included in the
+ // system.
+ if (provider.signatures == null || provider.signatures.length == 0) {
+ return packageInfo.applicationInfo.isSystemApp();
+ }
+ packageSignatures = packageInfo.signatures;
+ if (packageSignatures.length != 1)
+ return false;
+
+ final byte[] packageSignature = packageSignatures[0].toByteArray();
+ // Return whether the package signature matches any of the valid signatures
+ for (String signature : provider.signatures) {
+ final byte[] validSignature = Base64.decode(signature, Base64.DEFAULT);
+ if (Arrays.equals(packageSignature, validSignature))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether the given package is enabled.
+ * This state can be changed by the user from Settings->Apps
+ */
+ private static boolean isEnabledPackage(PackageInfo packageInfo) {
+ return packageInfo.applicationInfo.enabled;
+ }
+
+}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index bae628a..3ef077b 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1214,7 +1214,10 @@
window.type = windowState.mAttrs.type;
window.layer = windowState.mLayer;
window.token = windowState.mClient.asBinder();
- window.title = windowState.mAttrs.getTitle();
+ window.title = windowState.mAttrs.accessibilityTitle;
+ if (window.title == null) {
+ window.title = windowState.mAttrs.getTitle();
+ }
window.accessibilityIdOfAnchor = windowState.mAttrs.accessibilityIdOfAnchor;
WindowState attachedWindow = windowState.mAttachedWindow;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 8a9ace7..7b16dbe 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,24 +16,17 @@
package com.android.server.wm;
+import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
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.HOME_STACK_ID;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.RESIZE_TASK;
-import static com.android.server.wm.WindowManagerService.H.SHOW_NON_RESIZEABLE_DOCK_TOAST;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
import android.app.ActivityManager.StackId;
import android.content.pm.ActivityInfo;
@@ -44,7 +37,6 @@
import android.view.DisplayInfo;
import android.view.Surface;
-import com.android.internal.R;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
@@ -94,11 +86,6 @@
// Resize mode of the task. See {@link ActivityInfo#resizeMode}
private int mResizeMode;
- // Whether we need to show toast about the app being non-resizeable when it becomes visible.
- // This flag is set when a non-resizeable task is docked (or side-by-side). It's cleared
- // after we show the toast.
- private boolean mShowNonResizeableDockToast;
-
// Whether the task is currently being drag-resized
private boolean mDragResizing;
private int mDragResizeMode;
@@ -118,30 +105,6 @@
return mStack.getDisplayContent();
}
- void setShowNonResizeableDockToast() {
- mShowNonResizeableDockToast = true;
- }
-
- void scheduleShowNonResizeableDockToastIfNeeded() {
- if (!mShowNonResizeableDockToast) {
- return;
- }
- final DisplayContent displayContent = mStack.getDisplayContent();
- // If docked stack is not yet visible, we don't want to show the toast yet,
- // since we need the visible rect of the docked task to position the toast.
- if (displayContent == null || displayContent.getDockedStackLocked() == null) {
- return;
- }
-
- mShowNonResizeableDockToast = false;
-
- if (mResizeMode == RESIZE_MODE_UNRESIZEABLE) {
- final String text =
- mService.mContext.getString(R.string.dock_non_resizeble_failed_to_dock_text);
- mService.mH.obtainMessage(SHOW_NON_RESIZEABLE_DOCK_TOAST, 0, 0, text).sendToTarget();
- }
- }
-
void addAppToken(int addPos, AppWindowToken wtoken, int resizeMode, boolean homeTask) {
final int lastPos = mAppTokens.size();
if (addPos >= lastPos) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 3430ac928..446b74b 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -720,9 +720,9 @@
}
} else {
if (splitHorizontally) {
- outBounds.left = position - dockDividerWidth;
+ outBounds.left = position + dockDividerWidth;
} else {
- outBounds.top = position - dockDividerWidth;
+ outBounds.top = position + dockDividerWidth;
}
}
return;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2af324d..57f38d1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4193,6 +4193,7 @@
WindowManagerPolicy.TRANSIT_EXIT);
}
}
+ win.mAnimatingExit = true;
changed = true;
win.setDisplayLayoutNeeded();
}
@@ -4940,17 +4941,6 @@
}
}
- public void scheduleShowNonResizeableDockToast(int taskId) {
- synchronized (mWindowMap) {
- Task task = mTaskIdToTask.get(taskId);
- if (task == null) {
- if (DEBUG_STACK) Slog.i(TAG_WM, "scheduleShowToast: could not find taskId=" + taskId);
- return;
- }
- task.setShowNonResizeableDockToast();
- }
- }
-
@Override
public void getStackBounds(int stackId, Rect bounds) {
synchronized (mWindowMap) {
@@ -6035,7 +6025,6 @@
minLayer = Integer.MAX_VALUE;
}
- int retryCount = 0;
WindowState appWin = null;
boolean appIsImTarget;
@@ -6049,193 +6038,172 @@
final int aboveAppLayer = (mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
- while (true) {
- if (retryCount++ > 0) {
- // Reset max/min layers on retries so we don't accidentally take a screenshot of a
- // layer based on the previous try.
- maxLayer = 0;
- minLayer = Integer.MAX_VALUE;
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- }
- }
- synchronized(mWindowMap) {
- // Figure out the part of the screen that is actually the app.
- appWin = null;
- final WindowList windows = displayContent.getWindowList();
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState ws = windows.get(i);
- if (!ws.mHasSurface) {
- continue;
- }
- if (ws.mLayer >= aboveAppLayer) {
- continue;
- }
- if (ws.mIsImWindow) {
- if (!appIsImTarget) {
- continue;
- }
- } else if (ws.mIsWallpaper) {
- if (appWin == null) {
- // We have not ran across the target window yet, so it is probably
- // behind the wallpaper. This can happen when the keyguard is up and
- // all windows are moved behind the wallpaper. We don't want to
- // include the wallpaper layer in the screenshot as it will coverup
- // the layer of the target window.
- continue;
- }
- // Fall through. The target window is in front of the wallpaper. For this
- // case we want to include the wallpaper layer in the screenshot because
- // the target window might have some transparent areas.
- } else if (appToken != null) {
- if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
- // This app window is of no interest if it is not associated with the
- // screenshot app.
- continue;
- }
- appWin = ws;
- }
-
- // Include this window.
-
- final WindowStateAnimator winAnim = ws.mWinAnimator;
- int layer = winAnim.mSurfaceController.getLayer();
- if (maxLayer < layer) {
- maxLayer = layer;
- }
- if (minLayer > layer) {
- minLayer = layer;
- }
-
- // Don't include wallpaper in bounds calculation
- if (!includeFullDisplay && !ws.mIsWallpaper) {
- final Rect wf = ws.mFrame;
- final Rect cr = ws.mContentInsets;
- int left = wf.left + cr.left;
- int top = wf.top + cr.top;
- int right = wf.right - cr.right;
- int bottom = wf.bottom - cr.bottom;
- frame.union(left, top, right, bottom);
- ws.getVisibleBounds(stackBounds);
- if (!Rect.intersects(frame, stackBounds)) {
- // Set frame empty if there's no intersection.
- frame.setEmpty();
- }
- }
-
- if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
- ws.isDisplayedLw() && winAnim.getShown()) {
- screenshotReady = true;
- }
-
- if (ws.isObscuringFullscreen(displayInfo)){
- break;
- }
- }
-
- if (appToken != null && appWin == null) {
- // Can't find a window to snapshot.
- if (DEBUG_SCREENSHOT) Slog.i(TAG_WM,
- "Screenshot: Couldn't find a surface matching " + appToken);
- return null;
- }
-
- if (!screenshotReady) {
- if (retryCount > MAX_SCREENSHOT_RETRIES) {
- Slog.i(TAG_WM, "Screenshot max retries " + retryCount + " of " + appToken +
- " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" +
- appWin.mWinAnimator.mDrawState)));
- return null;
- }
-
- // Delay and hope that window gets drawn.
- if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot: No image ready for " + appToken
- + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
+ synchronized(mWindowMap) {
+ // Figure out the part of the screen that is actually the app.
+ appWin = null;
+ final WindowList windows = displayContent.getWindowList();
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState ws = windows.get(i);
+ if (!ws.mHasSurface) {
continue;
}
-
- // Screenshot is ready to be taken. Everything from here below will continue
- // through the bottom of the loop and return a value. We only stay in the loop
- // because we don't want to release the mWindowMap lock until the screenshot is
- // taken.
-
- if (maxLayer == 0) {
- if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
- + ": returning null maxLayer=" + maxLayer);
- return null;
+ if (ws.mLayer >= aboveAppLayer) {
+ continue;
+ }
+ if (ws.mIsImWindow) {
+ if (!appIsImTarget) {
+ continue;
+ }
+ } else if (ws.mIsWallpaper) {
+ if (appWin == null) {
+ // We have not ran across the target window yet, so it is probably
+ // behind the wallpaper. This can happen when the keyguard is up and
+ // all windows are moved behind the wallpaper. We don't want to
+ // include the wallpaper layer in the screenshot as it will coverup
+ // the layer of the target window.
+ continue;
+ }
+ // Fall through. The target window is in front of the wallpaper. For this
+ // case we want to include the wallpaper layer in the screenshot because
+ // the target window might have some transparent areas.
+ } else if (appToken != null) {
+ if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
+ // This app window is of no interest if it is not associated with the
+ // screenshot app.
+ continue;
+ }
+ appWin = ws;
}
- if (!includeFullDisplay) {
- // Constrain frame to the screen size.
- if (!frame.intersect(0, 0, dw, dh)) {
+ // Include this window.
+
+ final WindowStateAnimator winAnim = ws.mWinAnimator;
+ int layer = winAnim.mSurfaceController.getLayer();
+ if (maxLayer < layer) {
+ maxLayer = layer;
+ }
+ if (minLayer > layer) {
+ minLayer = layer;
+ }
+
+ // Don't include wallpaper in bounds calculation
+ if (!includeFullDisplay && !ws.mIsWallpaper) {
+ final Rect wf = ws.mFrame;
+ final Rect cr = ws.mContentInsets;
+ int left = wf.left + cr.left;
+ int top = wf.top + cr.top;
+ int right = wf.right - cr.right;
+ int bottom = wf.bottom - cr.bottom;
+ frame.union(left, top, right, bottom);
+ ws.getVisibleBounds(stackBounds);
+ if (!Rect.intersects(frame, stackBounds)) {
+ // Set frame empty if there's no intersection.
frame.setEmpty();
}
- } else {
- // Caller just wants entire display.
- frame.set(0, 0, dw, dh);
- }
- if (frame.isEmpty()) {
- return null;
}
- if (width < 0) {
- width = (int) (frame.width() * frameScale);
- }
- if (height < 0) {
- height = (int) (frame.height() * frameScale);
+ if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
+ ws.isDisplayedLw() && winAnim.getShown()) {
+ screenshotReady = true;
}
- // Tell surface flinger what part of the image to crop. Take the top
- // right part of the application, and crop the larger dimension to fit.
- Rect crop = new Rect(frame);
- if (width / (float) frame.width() < height / (float) frame.height()) {
- int cropWidth = (int)((float)width / (float)height * frame.height());
- crop.right = crop.left + cropWidth;
- } else {
- int cropHeight = (int)((float)height / (float)width * frame.width());
- crop.bottom = crop.top + cropHeight;
- }
-
- // The screenshot API does not apply the current screen rotation.
- int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
-
- if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
- rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
- }
-
- // Surfaceflinger is not aware of orientation, so convert our logical
- // crop to surfaceflinger's portrait orientation.
- convertCropForSurfaceFlinger(crop, rot, dw, dh);
-
- if (DEBUG_SCREENSHOT) {
- Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
- + maxLayer + " appToken=" + appToken);
- for (int i = 0; i < windows.size(); i++) {
- WindowState win = windows.get(i);
- Slog.i(TAG_WM, win + ": " + win.mLayer
- + " animLayer=" + win.mWinAnimator.mAnimLayer
- + " surfaceLayer=" + win.mWinAnimator.mSurfaceController.getLayer());
- }
- }
-
- ScreenRotationAnimation screenRotationAnimation =
- mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
- final boolean inRotation = screenRotationAnimation != null &&
- screenRotationAnimation.isAnimating();
- if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
- "Taking screenshot while rotating");
-
- bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
- inRotation, rot);
- if (bm == null) {
- Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh
- + ") to layer " + maxLayer);
- return null;
+ if (ws.isObscuringFullscreen(displayInfo)){
+ break;
}
}
- break;
+ if (appToken != null && appWin == null) {
+ // Can't find a window to snapshot.
+ if (DEBUG_SCREENSHOT) Slog.i(TAG_WM,
+ "Screenshot: Couldn't find a surface matching " + appToken);
+ return null;
+ }
+
+ if (!screenshotReady) {
+ Slog.i(TAG_WM, "Failed to capture screenshot of " + appToken +
+ " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" +
+ appWin.mWinAnimator.mDrawState)));
+ return null;
+ }
+
+ // Screenshot is ready to be taken. Everything from here below will continue
+ // through the bottom of the loop and return a value. We only stay in the loop
+ // because we don't want to release the mWindowMap lock until the screenshot is
+ // taken.
+
+ if (maxLayer == 0) {
+ if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
+ + ": returning null maxLayer=" + maxLayer);
+ return null;
+ }
+
+ if (!includeFullDisplay) {
+ // Constrain frame to the screen size.
+ if (!frame.intersect(0, 0, dw, dh)) {
+ frame.setEmpty();
+ }
+ } else {
+ // Caller just wants entire display.
+ frame.set(0, 0, dw, dh);
+ }
+ if (frame.isEmpty()) {
+ return null;
+ }
+
+ if (width < 0) {
+ width = (int) (frame.width() * frameScale);
+ }
+ if (height < 0) {
+ height = (int) (frame.height() * frameScale);
+ }
+
+ // Tell surface flinger what part of the image to crop. Take the top
+ // right part of the application, and crop the larger dimension to fit.
+ Rect crop = new Rect(frame);
+ if (width / (float) frame.width() < height / (float) frame.height()) {
+ int cropWidth = (int)((float)width / (float)height * frame.height());
+ crop.right = crop.left + cropWidth;
+ } else {
+ int cropHeight = (int)((float)height / (float)width * frame.width());
+ crop.bottom = crop.top + cropHeight;
+ }
+
+ // The screenshot API does not apply the current screen rotation.
+ int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
+
+ if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+ rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
+ }
+
+ // Surfaceflinger is not aware of orientation, so convert our logical
+ // crop to surfaceflinger's portrait orientation.
+ convertCropForSurfaceFlinger(crop, rot, dw, dh);
+
+ if (DEBUG_SCREENSHOT) {
+ Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
+ + maxLayer + " appToken=" + appToken);
+ for (int i = 0; i < windows.size(); i++) {
+ WindowState win = windows.get(i);
+ Slog.i(TAG_WM, win + ": " + win.mLayer
+ + " animLayer=" + win.mWinAnimator.mAnimLayer
+ + " surfaceLayer=" + win.mWinAnimator.mSurfaceController.getLayer());
+ }
+ }
+
+ ScreenRotationAnimation screenRotationAnimation =
+ mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
+ final boolean inRotation = screenRotationAnimation != null &&
+ screenRotationAnimation.isAnimating();
+ if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
+ "Taking screenshot while rotating");
+
+ bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
+ inRotation, rot);
+ if (bm == null) {
+ Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh
+ + ") to layer " + maxLayer);
+ return null;
+ }
}
if (DEBUG_SCREENSHOT) {
@@ -7635,7 +7603,8 @@
mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
|| volumeDownState > 0;
try {
- if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
+ if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0
+ || SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) != 0) {
int auditSafeMode = SystemProperties.getInt(ShutdownThread.AUDIT_SAFEMODE_PROPERTY, 0);
if (auditSafeMode == 0) {
@@ -7659,6 +7628,7 @@
if (mSafeMode) {
Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+ " dpad=" + dpadState + " trackball=" + trackballState + ")");
+ SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1");
} else {
Log.i(TAG_WM, "SAFE MODE not enabled");
}
@@ -7770,7 +7740,6 @@
public static final int RESIZE_TASK = 43;
public static final int TWO_FINGER_SCROLL_START = 44;
- public static final int SHOW_NON_RESIZEABLE_DOCK_TOAST = 45;
public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
@@ -8338,16 +8307,6 @@
}
}
break;
- case SHOW_NON_RESIZEABLE_DOCK_TOAST: {
- final Toast toast = Toast.makeText(
- mContext, (String) msg.obj, Toast.LENGTH_SHORT);
- final int gravity = toast.getGravity();
- final int xOffset = toast.getXOffset() + msg.arg1;
- final int yOffset = toast.getYOffset() + msg.arg2;
- toast.setGravity(gravity, xOffset, yOffset);
- toast.show();
- }
- break;
case WINDOW_REPLACEMENT_TIMEOUT: {
final AppWindowToken token = (AppWindowToken) msg.obj;
synchronized (mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ddfc022..c991130 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -642,13 +642,14 @@
* Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
* from {@param frame}. In other words, it applies the insets that would result if
* {@param frame} would be shifted to {@param layoutFrame} and then applying the insets from
- * {@param insetFrame}.
+ * {@param insetFrame}. Also it respects {@param displayFrame} in case window has minimum
+ * width/height applied and insets should be overridden.
*/
- private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame) {
- final int left = Math.max(0, insetFrame.left - layoutFrame.left);
- final int top = Math.max(0, insetFrame.top - layoutFrame.top);
- final int right = Math.max(0, layoutFrame.right - insetFrame.right);
- final int bottom = Math.max(0, layoutFrame.bottom - insetFrame.bottom);
+ private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame) {
+ final int left = Math.max(0, insetFrame.left - Math.max(layoutFrame.left, displayFrame.left));
+ final int top = Math.max(0, insetFrame.top - Math.max(layoutFrame.top, displayFrame.top));
+ final int right = Math.max(0, Math.min(layoutFrame.right, displayFrame.right) - insetFrame.right);
+ final int bottom = Math.max(0, Math.min(layoutFrame.bottom, displayFrame.bottom) - insetFrame.bottom);
frame.inset(left, top, right, bottom);
}
@@ -687,8 +688,7 @@
// The offset from the layout containing frame to the actual containing frame.
final int layoutXDiff;
final int layoutYDiff;
- if (mInsetFrame.isEmpty() && (fullscreenTask
- || layoutInParentFrame())) {
+ if (mInsetFrame.isEmpty() && (fullscreenTask || layoutInParentFrame())) {
// We use the parent frame as the containing frame for fullscreen and child windows
mContainingFrame.set(pf);
mDisplayFrame.set(df);
@@ -733,9 +733,13 @@
layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0;
layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
- subtractInsets(mDisplayFrame, layoutContainingFrame, df);
- subtractInsets(mContainingFrame, layoutContainingFrame, pf);
- subtractInsets(mInsetFrame, layoutContainingFrame, pf);
+ mTmpRect.set(0, 0, mDisplayContent.getDisplayInfo().logicalWidth,
+ mDisplayContent.getDisplayInfo().logicalHeight);
+ subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect);
+ if (!layoutInParentFrame()) {
+ subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect);
+ subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect);
+ }
layoutDisplayFrame = df;
layoutDisplayFrame.intersect(layoutContainingFrame);
}
@@ -853,8 +857,8 @@
getDisplayContent().getLogicalDisplayRect(mTmpRect);
// 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 > mTmpRect.right;
- boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom;
+ boolean overrideRightInset = !fullscreenTask && layoutContainingFrame.right > mTmpRect.right;
+ boolean overrideBottomInset = !fullscreenTask && layoutContainingFrame.bottom > mTmpRect.bottom;
mContentInsets.set(mContentFrame.left - layoutContainingFrame.left,
mContentFrame.top - layoutContainingFrame.top,
overrideRightInset ? mTmpRect.right - mContentFrame.right
@@ -2353,6 +2357,10 @@
return mDragResizing;
}
+ boolean isDockedResizing() {
+ return mDragResizing && getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+ }
+
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
final TaskStack stack = getStack();
pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
@@ -2584,7 +2592,7 @@
final int ph = containingFrame.height();
final Task task = getTask();
final boolean nonFullscreenTask = isInMultiWindowMode();
- final boolean fitToDisplay = task != null && !task.isFloating() && !layoutInParentFrame();
+ final boolean fitToDisplay = task != null && !nonFullscreenTask && !layoutInParentFrame();
float x, y;
int w,h;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 34452ee..9c25f63 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1125,13 +1125,21 @@
final int top = w.mYOffset + w.mFrame.top;
// Initialize the decor rect to the entire frame.
- if (w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER) {
+ if (w.isDockedResizing() ||
+ (w.isChildWindow() && w.mAttachedWindow.isDockedResizing())) {
// If we are resizing with the divider, the task bounds might be smaller than the
// stack bounds. The system decor is used to clip to the task bounds, which we don't
// want in this case in order to avoid holes.
+ //
+ // We take care to not shrink the width, for surfaces which are larger than
+ // the display region. Of course this area will not eventually be visible
+ // but if we truncate the width now, we will calculate incorrectly
+ // when adjusting to the stack bounds.
final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
- mSystemDecorRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+ mSystemDecorRect.set(0, 0,
+ Math.max(width, displayInfo.logicalWidth),
+ Math.max(height, displayInfo.logicalHeight));
} else {
mSystemDecorRect.set(0, 0, width, height);
}
@@ -1483,11 +1491,6 @@
}
}
w.mToken.hasVisible = true;
-
- final Task task = w.getTask();
- if (task != null) {
- task.scheduleShowNonResizeableDockToastIfNeeded();
- }
}
}
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index ae05042..78b0844 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1112,7 +1112,7 @@
JavaObject object(env, "android/location/GnssClock");
GpsClockFlags flags = clock->flags;
- SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND,
+ SET_IF(GPS_CLOCK_HAS_LEAP_SECOND,
LeapSecond,
static_cast<int32_t>(clock->leap_second));
@@ -1121,8 +1121,9 @@
// old GPS_CLOCK types (active only in a limited number of older devices),
// the GPS time information is handled as an always discontinuous HW clock,
// with the GPS time information put into the full_bias_ns instead - so that
- // time_ns + full_bias_ns = local estimate of GPS time (as remains true, in
- // the new GnssClock struct.)
+ // time_ns - full_bias_ns = local estimate of GPS time. Additionally, the
+ // sign of full_bias_ns and bias_ns has flipped between GpsClock &
+ // GnssClock, so that is also handled below.
switch (clock->type) {
case GPS_CLOCK_TYPE_UNKNOWN:
// Clock type unsupported.
@@ -1133,7 +1134,7 @@
break;
case GPS_CLOCK_TYPE_GPS_TIME:
// GPS time, need to convert.
- flags |= GNSS_CLOCK_HAS_FULL_BIAS;
+ flags |= GPS_CLOCK_HAS_FULL_BIAS;
clock->full_bias_ns = clock->time_ns;
clock->time_ns = 0;
SET(HardwareClockDiscontinuityCount,
@@ -1142,16 +1143,20 @@
}
SET(TimeNanos, clock->time_ns);
- SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
+ SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
TimeUncertaintyNanos,
clock->time_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, clock->full_bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS, BiasNanos, clock->bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
+
+ // Definition of sign for full_bias_ns & bias_ns has been changed since N,
+ // so flip signs here.
+ SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, -(clock->full_bias_ns));
+ SET_IF(GPS_CLOCK_HAS_BIAS, BiasNanos, -(clock->bias_ns));
+
+ SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
BiasUncertaintyNanos,
clock->bias_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
- SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
+ SET_IF(GPS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
+ SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
DriftUncertaintyNanosPerSecond,
clock->drift_uncertainty_nsps);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 42b5705..72eebb5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3890,9 +3890,6 @@
// back in to the service.
final long ident = mInjector.binderClearCallingIdentity();
try {
- if (isManagedProfile(userHandle)) {
- mLockPatternUtils.setSeparateProfileChallengeEnabled(userHandle, true);
- }
if (!TextUtils.isEmpty(password)) {
mLockPatternUtils.saveLockPassword(password, null, quality, userHandle);
} else {
@@ -3981,6 +3978,15 @@
&& timeMs > admin.maximumTimeToUnlock) {
timeMs = admin.maximumTimeToUnlock;
}
+ // If userInfo.id is a managed profile, we also need to look at
+ // the policies set on the parent.
+ if (admin.hasParentActiveAdmin()) {
+ final ActiveAdmin parentAdmin = admin.getParentActiveAdmin();
+ if (parentAdmin.maximumTimeToUnlock > 0
+ && timeMs > parentAdmin.maximumTimeToUnlock) {
+ timeMs = parentAdmin.maximumTimeToUnlock;
+ }
+ }
}
}
@@ -4014,30 +4020,57 @@
}
enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
- long time = 0;
-
if (who != null) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
- return admin != null ? admin.maximumTimeToUnlock : time;
+ return admin != null ? admin.maximumTimeToUnlock : 0;
}
-
// Return the strictest policy across all participating admins.
List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
userHandle, parent);
- final int N = admins.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = admins.get(i);
- if (time == 0) {
- time = admin.maximumTimeToUnlock;
- } else if (admin.maximumTimeToUnlock != 0
- && time > admin.maximumTimeToUnlock) {
- time = admin.maximumTimeToUnlock;
+ return getMaximumTimeToLockPolicyFromAdmins(admins);
+ }
+ }
+
+ @Override
+ public long getMaximumTimeToLockForUserAndProfiles(int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
+ enforceFullCrossUsersPermission(userHandle);
+ synchronized (this) {
+ // All admins for this user.
+ ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>();
+ for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+ DevicePolicyData policy = getUserData(userInfo.id);
+ admins.addAll(policy.mAdminList);
+ // If it is a managed profile, it may have parent active admins
+ if (userInfo.isManagedProfile()) {
+ for (ActiveAdmin admin : policy.mAdminList) {
+ if (admin.hasParentActiveAdmin()) {
+ admins.add(admin.getParentActiveAdmin());
+ }
+ }
}
}
- return time;
+ return getMaximumTimeToLockPolicyFromAdmins(admins);
}
}
+ private long getMaximumTimeToLockPolicyFromAdmins(List<ActiveAdmin> admins) {
+ long time = 0;
+ final int N = admins.size();
+ for (int i = 0; i < N; i++) {
+ ActiveAdmin admin = admins.get(i);
+ if (time == 0) {
+ time = admin.maximumTimeToUnlock;
+ } else if (admin.maximumTimeToUnlock != 0
+ && time > admin.maximumTimeToUnlock) {
+ time = admin.maximumTimeToUnlock;
+ }
+ }
+ return time;
+ }
+
@Override
public void lockNow(boolean parent) {
if (!mHasFeature) {
@@ -8045,7 +8078,8 @@
}
}
}
- return null;
+ // We're not specifying the device admin because there isn't one.
+ return intent;
}
}
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index f430a30..6722332 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -252,15 +252,22 @@
long mLastSeen;
// For debugging only. Offsets into the packet where PIOs are.
- private final ArrayList<Integer> mPrefixOptionOffsets;
+ private final ArrayList<Integer> mPrefixOptionOffsets = new ArrayList<>();
+
+ // For debugging only. Offsets into the packet where RDNSS options are.
+ private final ArrayList<Integer> mRdnssOptionOffsets = new ArrayList<>();
+
// For debugging only. How many times this RA was seen.
int seenCount = 0;
// For debugging only. Returns the hex representation of the last matching packet.
String getLastMatchingPacket() {
- return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(), false /* lowercase */);
+ return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(),
+ false /* lowercase */);
}
+ // For debugging only. Returns the string representation of the IPv6 address starting at
+ // position pos in the packet.
private String IPv6AddresstoString(int pos) {
try {
byte[] array = mPacket.array();
@@ -295,19 +302,37 @@
return s & 0xffffffff;
}
+ private void prefixOptionToString(StringBuffer sb, int offset) {
+ String prefix = IPv6AddresstoString(offset + 16);
+ int length = uint8(mPacket.get(offset + 2));
+ long valid = mPacket.getInt(offset + 4);
+ long preferred = mPacket.getInt(offset + 8);
+ sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
+ }
+
+ private void rdnssOptionToString(StringBuffer sb, int offset) {
+ int optLen = uint8(mPacket.get(offset + 1)) * 8;
+ if (optLen < 24) return; // Malformed or empty.
+ long lifetime = uint32(mPacket.getInt(offset + 4));
+ int numServers = (optLen - 8) / 16;
+ sb.append("DNS ").append(lifetime).append("s");
+ for (int server = 0; server < numServers; server++) {
+ sb.append(" ").append(IPv6AddresstoString(offset + 8 + 16 * server));
+ }
+ }
+
public String toString() {
try {
StringBuffer sb = new StringBuffer();
- sb.append(String.format("RA %s -> %s %d ",
+ sb.append(String.format("RA %s -> %s %ds ",
IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
uint16(mPacket.getShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET))));
for (int i: mPrefixOptionOffsets) {
- String prefix = IPv6AddresstoString(i + 16);
- int length = uint8(mPacket.get(i + 2));
- long valid = mPacket.getInt(i + 4);
- long preferred = mPacket.getInt(i + 8);
- sb.append(String.format("%s/%d %d/%d ", prefix, length, valid, preferred));
+ prefixOptionToString(sb, i);
+ }
+ for (int i: mRdnssOptionOffsets) {
+ rdnssOptionToString(sb, i);
}
return sb.toString();
} catch (BufferUnderflowException | IndexOutOfBoundsException e) {
@@ -352,8 +377,7 @@
ICMP6_RA_ROUTER_LIFETIME_OFFSET,
ICMP6_RA_ROUTER_LIFETIME_LEN);
- // Parse ICMPv6 options
- mPrefixOptionOffsets = new ArrayList<>();
+ // Ensures that the RA is not truncated.
mPacket.position(ICMP6_RA_OPTION_OFFSET);
while (mPacket.hasRemaining()) {
int optionType = ((int)mPacket.get(mPacket.position())) & 0xff;
@@ -372,8 +396,10 @@
break;
// These three options have the same lifetime offset and size, so process
// together:
- case ICMP6_ROUTE_INFO_OPTION_TYPE:
case ICMP6_RDNSS_OPTION_TYPE:
+ mRdnssOptionOffsets.add(mPacket.position());
+ // Fall through.
+ case ICMP6_ROUTE_INFO_OPTION_TYPE:
case ICMP6_DNSSL_OPTION_TYPE:
// Parse lifetime
lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
@@ -520,6 +546,10 @@
@GuardedBy("this")
private byte[] mLastInstalledProgram;
+ // For debugging only. How many times the program was updated since we started.
+ @GuardedBy("this")
+ private int mNumProgramUpdates;
+
/**
* Generate filter code to process ARP packets. Execution of this code ends in either the
* DROP_LABEL or PASS_LABEL and does not fall off the end.
@@ -724,6 +754,8 @@
mLastTimeInstalledProgram = curTime();
mLastInstalledProgramMinLifetime = programMinLifetime;
mLastInstalledProgram = program;
+ mNumProgramUpdates++;
+
if (VDBG) {
hexDump("Installing filter: ", program, program.length);
}
@@ -865,19 +897,20 @@
}
public synchronized void dump(IndentingPrintWriter pw) {
- pw.println("APF caps: " + mApfCapabilities);
+ pw.println("Capabilities: " + mApfCapabilities);
pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
- pw.println("Multicast filtering: " + mMulticastFilter);
+ pw.println("Multicast: " + (mMulticastFilter ? "DROP" : "ALLOW"));
try {
- pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address));
+ pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address).getHostAddress());
} catch (UnknownHostException|NullPointerException e) {}
+
if (mLastTimeInstalledProgram == 0) {
pw.println("No program installed.");
return;
}
-
+ pw.println("Program updates: " + mNumProgramUpdates);
pw.println(String.format(
- "Last program length %d, installed %ds ago, lifetime %d",
+ "Last program length %d, installed %ds ago, lifetime %ds",
mLastInstalledProgram.length, curTime() - mLastTimeInstalledProgram,
mLastInstalledProgramMinLifetime));
@@ -896,6 +929,7 @@
}
pw.decreaseIndent();
}
+ pw.decreaseIndent();
if (DBG) {
pw.println("Last program:");
@@ -903,7 +937,5 @@
pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
pw.decreaseIndent();
}
-
- pw.decreaseIndent();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 8e11511..2f20a4b 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -59,6 +59,7 @@
import android.os.MessageQueue;
import android.os.Messenger;
import android.os.MessageQueue.IdleHandler;
+import android.os.Process;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -690,6 +691,7 @@
assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
// Test getActiveNetwork()
assertNotNull(mCm.getActiveNetwork());
+ assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid()));
switch (transport) {
case TRANSPORT_WIFI:
assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
@@ -713,6 +715,7 @@
assertNull(mCm.getActiveNetworkInfo());
// Test getActiveNetwork()
assertNull(mCm.getActiveNetwork());
+ assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
// Test getAllNetworks()
assertEquals(0, mCm.getAllNetworks().length);
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
index 6026644..9f53c87 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
@@ -162,7 +162,7 @@
final NetworkStats.Entry entry = new NetworkStats.Entry();
final NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- TEST_IMSI, null, false));
+ TEST_IMSI, null, false, true));
int myUid = Process.myUid();
int otherUidInSameUser = Process.myUid() + 1;
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
index 82c6b6d..cff5876 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
@@ -283,7 +283,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -315,7 +315,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -354,7 +354,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -393,13 +393,13 @@
NetworkIdentitySet identSet1 = new NetworkIdentitySet();
identSet1.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveIfaces.put(TEST_IFACE, identSet1);
NetworkIdentitySet identSet2 = new NetworkIdentitySet();
identSet2.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_2, null /* networkId */, false /* roaming */));
+ IMSI_2, null /* networkId */, false /* roaming */, true /* metered */));
mActiveIfaces.put(TEST_IFACE2, identSet2);
// Baseline
@@ -441,7 +441,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveUidIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -481,7 +481,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveUidIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -521,7 +521,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveUidIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -561,7 +561,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveUidIfaces.put(TEST_IFACE, identSet);
// Baseline
@@ -601,7 +601,7 @@
NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- IMSI_1, null /* networkId */, false /* roaming */));
+ IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
mActiveUidIfaces.put(TEST_IFACE, identSet);
// Baseline
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 40687b0..f13e019 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -41,6 +41,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Slog;
+import com.android.internal.logging.MetricsLogger;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -56,7 +57,6 @@
* (ii) Generic sound-trigger models: Supports multiple of these.
*
* Currently this just acts as an abstraction over all SoundTrigger API calls.
- *
* @hide
*/
public class SoundTriggerHelper implements SoundTrigger.StatusListener {
@@ -84,25 +84,23 @@
private final PhoneStateListener mPhoneStateListener;
private final PowerManager mPowerManager;
- // TODO: Since the voice layer currently only handles one recognition
- // we simplify things by assuming one listener here too.
- private IRecognitionStatusCallback mKeyphraseListener;
-
// The SoundTriggerManager layer handles multiple generic recognition models. We store the
// ModelData here in a hashmap.
private final HashMap<UUID, ModelData> mGenericModelDataMap;
- // Note: KeyphraseId is not really used.
+ // This ModelData instance ensures that the keyphrase sound model is a singleton and
+ // all other sound models are of type Generic. Any keyphrase sound model will be stored here
+ // and any previously running instances will be replaced. This restriction was earlier
+ // implemented by three instance variables which stored data about the keyphrase
+ // model. That data now gets encapsulated in this ModelData instance.
+ private ModelData mKeyphraseModelData;
+
+ // The keyphrase ID for keyphrase sound models. We store this specially here since ModelData
+ // does not support this.
+ // TODO: The role of the keyphrase ID is a bit unclear. Its just used to ensure that
+ // recognition events have the correct keyphrase ID check.
private int mKeyphraseId = INVALID_VALUE;
- // Current voice sound model handle. We only allow one voice model to run at any given time.
- private int mCurrentKeyphraseModelHandle = INVALID_VALUE;
- private KeyphraseSoundModel mCurrentSoundModel = null;
- // FIXME: Ideally this should not be stored if allowMultipleTriggers happens at a lower layer.
- private RecognitionConfig mRecognitionConfig = null;
-
- // Whether we are requesting recognition to start.
- private boolean mRequested = false;
private boolean mCallActive = false;
private boolean mIsPowerSaveMode = false;
// Indicates if the native sound trigger service is disabled or not.
@@ -112,8 +110,6 @@
// Whether we have ANY recognition (keyphrase or generic) running.
private boolean mRecognitionRunning = false;
- // Keeps track of whether the keyphrase recognition is running.
- private boolean mKeyphraseStarted = false;
private boolean mRecognitionAborted = false;
private PowerSaveModeListener mPowerSaveModeListener;
@@ -136,26 +132,89 @@
}
/**
- * Starts recognition for the given generic sound model ID.
+ * Starts recognition for the given generic sound model ID. This is a wrapper around {@link
+ * startRecognition()}.
*
- * @param soundModel The sound model to use for recognition.
- * @param listener The listener for the recognition events related to the given keyphrase.
+ * @param modelId UUID of the sound model.
+ * @param soundModel The generic sound model to use for recognition.
+ * @param callback Callack for the recognition events related to the given keyphrase.
+ * @param recognitionConfig Instance of RecognitionConfig containing the parameters for the
+ * recognition.
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
- if (soundModel == null || callback == null || recognitionConfig == null) {
+ MetricsLogger.count(mContext, "sth_start_recognition", 1);
+ if (modelId == null || soundModel == null || callback == null ||
+ recognitionConfig == null) {
Slog.w(TAG, "Passed in bad data to startGenericRecognition().");
return STATUS_ERROR;
}
synchronized (mLock) {
+ ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
+ return startRecognition(soundModel, modelData, callback, recognitionConfig,
+ INVALID_VALUE /* keyphraseId */);
+ }
+ }
+ /**
+ * Starts recognition for the given keyphraseId.
+ *
+ * @param keyphraseId The identifier of the keyphrase for which
+ * the recognition is to be started.
+ * @param soundModel The sound model to use for recognition.
+ * @param callback The callback for the recognition events related to the given keyphrase.
+ * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+ */
+ int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+ IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
+ synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_start_recognition", 1);
+ if (soundModel == null || callback == null || recognitionConfig == null) {
+ return STATUS_ERROR;
+ }
+
+ if (DBG) {
+ Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
+ + " soundModel=" + soundModel + ", callback=" + callback.asBinder()
+ + ", recognitionConfig=" + recognitionConfig);
+ Slog.d(TAG, "moduleProperties=" + mModuleProperties);
+ if (mKeyphraseModelData != null) {
+ Slog.d(TAG, mKeyphraseModelData.toString());
+ } else {
+ Slog.d(TAG, "Null KeyphraseModelData.");
+ }
+ }
+ if (mKeyphraseModelData == null) {
+ mKeyphraseModelData = ModelData.createKeyphraseModelData(soundModel.uuid);
+ }
+ return startRecognition(soundModel, mKeyphraseModelData, callback, recognitionConfig,
+ keyphraseId);
+ }
+ }
+
+ /**
+ * Starts recognition for the given sound model. A single routine for both keyphrase and
+ * generic sound models.
+ *
+ * @param soundModel The sound model to use for recognition.
+ * @param modelData Instance of {@link #ModelData} for the given model.
+ * @param callback Callback for the recognition events related to the given keyphrase.
+ * @param recognitionConfig Instance of {@link RecognitionConfig} containing the parameters
+ * @param keyphraseId Keyphrase ID for keyphrase models only. Pass in INVALID_VALUE for other
+ * models.
+ * for the recognition.
+ * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+ */
+ int startRecognition(SoundModel soundModel, ModelData modelData,
+ IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
+ int keyphraseId) {
+ synchronized (mLock) {
if (mModuleProperties == null) {
Slog.w(TAG, "Attempting startRecognition without the capability");
return STATUS_ERROR;
}
-
if (mModule == null) {
mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null);
if (mModule == null) {
@@ -169,13 +228,43 @@
initializeTelephonyAndPowerStateListeners();
}
- // Fetch a ModelData instance from the hash map. Creates a new one if none
- // exists.
- ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
+ // If the previous model is different (for the same UUID), ensure that its unloaded
+ // and stopped before proceeding. This works for both keyphrase and generic models.
+ // Specifically for keyphrase since we have 'mKeyphraseModelData' holding a single
+ // allowed instance of such a model, this ensures that a previously loaded (or started)
+ // keyphrase model is appropriately stopped. This ensures no regression with the
+ // previous version of this code as given in the startKeyphrase() routine.
+ //
+ // For generic sound models, all this means is that if we are given a different sound
+ // model with the same UUID, then we will "replace" it.
+ if (modelData.getSoundModel() != null) {
+ boolean stopModel = false; // Stop the model after checking that its started.
+ boolean unloadModel = false;
+ if (modelData.getSoundModel().equals(soundModel) && modelData.isModelStarted()) {
+ // The model has not changed, but the previous model is "started".
+ // Stop the previously running model.
+ stopModel = true;
+ unloadModel = false; // No need to unload if the model hasn't changed.
+ } else if (!modelData.getSoundModel().equals(soundModel)) {
+ // We have a different model for this UUID. Stop and unload if needed. This
+ // helps maintain the singleton restriction for keyphrase sound models.
+ stopModel = modelData.isModelStarted();
+ unloadModel = modelData.isModelLoaded();
+ }
+ if (stopModel || unloadModel) {
+ int status = tryStopAndUnloadLocked(modelData, stopModel, unloadModel);
+ if (status != STATUS_OK) {
+ Slog.w(TAG, "Unable to stop or unload previous model: " +
+ modelData.toString());
+ return status;
+ }
+ }
+ }
IRecognitionStatusCallback oldCallback = modelData.getCallback();
- if (oldCallback != null) {
- Slog.w(TAG, "Canceling previous recognition for model id: " + modelId);
+ if (oldCallback != null && oldCallback.asBinder() != callback.asBinder()) {
+ Slog.w(TAG, "Canceling previous recognition for model id: " +
+ modelData.getModelId());
try {
oldCallback.onError(STATUS_ERROR);
} catch (RemoteException e) {
@@ -199,182 +288,49 @@
}
modelData.setHandle(handle[0]);
modelData.setLoaded();
- Slog.d(TAG, "Generic sound model loaded with handle:" + handle[0]);
+ Slog.d(TAG, "Sound model loaded with handle:" + handle[0]);
}
modelData.setCallback(callback);
+ if (modelData.isKeyphraseModel()) {
+ mKeyphraseId = keyphraseId;
+ }
+ modelData.setRequested(true);
modelData.setRecognitionConfig(recognitionConfig);
+ modelData.setSoundModel(soundModel);
- // Don't notify for synchronous calls.
- return startGenericRecognitionLocked(modelData, false);
+ return startRecognitionLocked(modelData,
+ false /* Don't notify for synchronous calls */);
}
}
/**
- * Starts recognition for the given keyphraseId.
- *
- * @param keyphraseId The identifier of the keyphrase for which
- * the recognition is to be started.
- * @param soundModel The sound model to use for recognition.
- * @param listener The listener for the recognition events related to the given keyphrase.
- * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
- */
- int startKeyphraseRecognition(int keyphraseId,
- KeyphraseSoundModel soundModel,
- IRecognitionStatusCallback listener,
- RecognitionConfig recognitionConfig) {
- if (soundModel == null || listener == null || recognitionConfig == null) {
- return STATUS_ERROR;
- }
-
- synchronized (mLock) {
- if (DBG) {
- Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
- + " soundModel=" + soundModel + ", listener=" + listener.asBinder()
- + ", recognitionConfig=" + recognitionConfig);
- Slog.d(TAG, "moduleProperties=" + mModuleProperties);
- Slog.d(TAG, "current listener="
- + (mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder()));
- Slog.d(TAG, "current SoundModel handle=" + mCurrentKeyphraseModelHandle);
- Slog.d(TAG, "current SoundModel UUID="
- + (mCurrentSoundModel == null ? null : mCurrentSoundModel.uuid));
- }
-
- if (!mRecognitionRunning) {
- initializeTelephonyAndPowerStateListeners();
- }
-
- if (mModuleProperties == null) {
- Slog.w(TAG, "Attempting startKeyphraseRecognition without the capability");
- return STATUS_ERROR;
- }
- if (mModule == null) {
- mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null);
- if (mModule == null) {
- Slog.w(TAG, "startKeyphraseRecognition cannot attach to sound trigger module");
- return STATUS_ERROR;
- }
- }
-
- // Unload the previous model if the current one isn't invalid
- // and, it's not the same as the new one.
- // This helps use cache and reuse the model and just start/stop it when necessary.
- if (mCurrentKeyphraseModelHandle != INVALID_VALUE
- && !soundModel.equals(mCurrentSoundModel)) {
- Slog.w(TAG, "Unloading previous sound model");
- int status = mModule.unloadSoundModel(mCurrentKeyphraseModelHandle);
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "unloadSoundModel call failed with " + status);
- }
- internalClearKeyphraseSoundModelLocked();
- mKeyphraseStarted = false;
- }
-
- // If the previous recognition was by a different listener,
- // Notify them that it was stopped.
- if (mKeyphraseListener != null && mKeyphraseListener.asBinder() != listener.asBinder()) {
- Slog.w(TAG, "Canceling previous recognition");
- try {
- mKeyphraseListener.onError(STATUS_ERROR);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onDetectionStopped", e);
- }
- mKeyphraseListener = null;
- }
-
- // Load the sound model if the current one is null.
- int soundModelHandle = mCurrentKeyphraseModelHandle;
- if (mCurrentKeyphraseModelHandle == INVALID_VALUE
- || mCurrentSoundModel == null) {
- int[] handle = new int[] { INVALID_VALUE };
- int status = mModule.loadSoundModel(soundModel, handle);
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "loadSoundModel call failed with " + status);
- return status;
- }
- if (handle[0] == INVALID_VALUE) {
- Slog.w(TAG, "loadSoundModel call returned invalid sound model handle");
- return STATUS_ERROR;
- }
- soundModelHandle = handle[0];
- } else {
- if (DBG) Slog.d(TAG, "Reusing previously loaded sound model");
- }
-
- // Start the recognition.
- mRequested = true;
- mKeyphraseId = keyphraseId;
- mCurrentKeyphraseModelHandle = soundModelHandle;
- mCurrentSoundModel = soundModel;
- mRecognitionConfig = recognitionConfig;
- // Register the new listener. This replaces the old one.
- // There can only be a maximum of one active listener at any given time.
- mKeyphraseListener = listener;
-
- return updateRecognitionLocked(false /* don't notify for synchronous calls */);
- }
- }
-
- /**
- * Stops recognition for the given generic sound model.
+ * Stops recognition for the given generic sound model. This is a wrapper for {@link
+ * #stopRecognition}.
*
* @param modelId The identifier of the generic sound model for which
* the recognition is to be stopped.
- * @param listener The listener for the recognition events related to the given sound model.
+ * @param callback The callback for the recognition events related to the given sound model.
*
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
- int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback listener) {
- if (listener == null) {
- return STATUS_ERROR;
- }
-
+ int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback callback) {
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_stop_recognition", 1);
+ if (callback == null || modelId == null) {
+ Slog.e(TAG, "Null callbackreceived for stopGenericRecognition() for modelid:" +
+ modelId);
+ return STATUS_ERROR;
+ }
+
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) {
Slog.w(TAG, "Attempting stopRecognition on invalid model with id:" + modelId);
return STATUS_ERROR;
}
- IRecognitionStatusCallback currentCallback = modelData.getCallback();
- if (DBG) {
- Slog.d(TAG, "stopRecognition for modelId=" + modelId
- + ", listener=" + listener.asBinder());
- Slog.d(TAG, "current callback ="
- + (currentCallback == null ? "null" : currentCallback.asBinder()));
- }
-
- if (mModuleProperties == null || mModule == null) {
- Slog.w(TAG, "Attempting stopRecognition without the capability");
- return STATUS_ERROR;
- }
-
- if (currentCallback == null || !modelData.isModelStarted()) {
- // startGenericRecognition hasn't been called or it failed.
- Slog.w(TAG, "Attempting stopGenericRecognition without a successful" +
- " startGenericRecognition");
- return STATUS_ERROR;
- }
- if (currentCallback.asBinder() != listener.asBinder()) {
- // We don't allow a different listener to stop the recognition than the one
- // that started it.
- Slog.w(TAG, "Attempting stopGenericRecognition for another recognition");
- return STATUS_ERROR;
- }
-
- int status = stopGenericRecognitionLocked(modelData,
- false /* don't notify for synchronous calls */);
+ int status = stopRecognition(modelData, callback);
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "stopGenericRecognition failed: " + status);
- return status;
- }
-
- // We leave the sound model loaded but not started, this helps us when we start
- // back.
- // Also clear the internal state once the recognition has been stopped.
- modelData.setLoaded();
- modelData.clearCallback();
- if (!computeRecognitionRunningLocked()) {
- internalClearGlobalStateLocked();
}
return status;
}
@@ -382,47 +338,30 @@
/**
* Stops recognition for the given {@link Keyphrase} if a recognition is
- * currently active.
+ * currently active. This is a wrapper for {@link #stopRecognition()}.
*
* @param keyphraseId The identifier of the keyphrase for which
* the recognition is to be stopped.
- * @param listener The listener for the recognition events related to the given keyphrase.
+ * @param callback The callback for the recognition events related to the given keyphrase.
*
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
- int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
- if (listener == null) {
- return STATUS_ERROR;
- }
-
+ int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback callback) {
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_stop_recognition", 1);
+ if (callback == null) {
+ Slog.e(TAG, "Null callback received for stopKeyphraseRecognition() for keyphraseId:" +
+ keyphraseId);
+ return STATUS_ERROR;
+ }
+
if (DBG) {
- Slog.d(TAG, "stopRecognition for keyphraseId=" + keyphraseId
- + ", listener=" + listener.asBinder());
- Slog.d(TAG, "current listener="
- + (mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder()));
+ Slog.d(TAG, "stopRecognition for keyphraseId=" + keyphraseId + ", callback =" +
+ callback.asBinder());
+ Slog.d(TAG, "current callback=" + (mKeyphraseModelData == null ? "null" :
+ mKeyphraseModelData.getCallback().asBinder()));
}
-
- if (mModuleProperties == null || mModule == null) {
- Slog.w(TAG, "Attempting stopRecognition without the capability");
- return STATUS_ERROR;
- }
-
- if (mKeyphraseListener == null) {
- // startRecognition hasn't been called or it failed.
- Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition");
- return STATUS_ERROR;
- }
- if (mKeyphraseListener.asBinder() != listener.asBinder()) {
- // We don't allow a different listener to stop the recognition than the one
- // that started it.
- Slog.w(TAG, "Attempting stopRecognition for another recognition");
- return STATUS_ERROR;
- }
-
- // Stop recognition if it's the current one, ignore otherwise.
- mRequested = false;
- int status = updateRecognitionLocked(false /* don't notify for synchronous calls */);
+ int status = stopRecognition(mKeyphraseModelData, callback);
if (status != SoundTrigger.STATUS_OK) {
return status;
}
@@ -431,25 +370,115 @@
// back.
// Also clear the internal state once the recognition has been stopped.
internalClearKeyphraseStateLocked();
- internalClearGlobalStateLocked();
return status;
}
}
/**
+ * Stops recognition for the given ModelData instance.
+ *
+ * @param modelData Instance of {@link #ModelData} sound model.
+ * @param callback The callback for the recognition events related to the given keyphrase.
+ * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+ */
+ private int stopRecognition(ModelData modelData, IRecognitionStatusCallback callback) {
+ synchronized (mLock) {
+ if (callback == null) {
+ return STATUS_ERROR;
+ }
+ if (mModuleProperties == null || mModule == null) {
+ Slog.w(TAG, "Attempting stopRecognition without the capability");
+ return STATUS_ERROR;
+ }
+
+ IRecognitionStatusCallback currentCallback = modelData.getCallback();
+ if (modelData == null || currentCallback == null || !modelData.isModelStarted()) {
+ // startGenericRecognition hasn't been called or it failed.
+ Slog.w(TAG, "Attempting stopGenericRecognition without a successful" +
+ " startGenericRecognition");
+ return STATUS_ERROR;
+ }
+
+ if (currentCallback.asBinder() != callback.asBinder()) {
+ // We don't allow a different listener to stop the recognition than the one
+ // that started it.
+ Slog.w(TAG, "Attempting stopRecognition for another recognition");
+ return STATUS_ERROR;
+ }
+
+ // Request stop recognition via the update() method.
+ modelData.setRequested(false);
+ int status = updateRecognitionLocked(modelData, isRecognitionAllowed(),
+ false /* don't notify for synchronous calls */);
+ if (status != SoundTrigger.STATUS_OK) {
+ return status;
+ }
+
+ // We leave the sound model loaded but not started, this helps us when we start back.
+ // Also clear the internal state once the recognition has been stopped.
+ modelData.setLoaded();
+ modelData.clearCallback();
+ modelData.setRecognitionConfig(null);
+
+ if (!computeRecognitionRunningLocked()) {
+ internalClearGlobalStateLocked();
+ }
+
+ if (modelData.isKeyphraseModel()) {
+ mKeyphraseId = INVALID_VALUE;
+ }
+ return status;
+ }
+ }
+
+ // Stop a previously started model if it was started. Optionally, unload if the previous model
+ // is stale and is about to be replaced.
+ // Needs to be called with the mLock held.
+ private int tryStopAndUnloadLocked(ModelData modelData, boolean stopModel,
+ boolean unloadModel) {
+ int status = STATUS_OK;
+ if (modelData.isModelNotLoaded()) {
+ return status;
+ }
+ if (stopModel && modelData.isModelStarted()) {
+ status = stopRecognitionLocked(modelData,
+ false /* don't notify for synchronous calls */);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "stopRecognition failed: " + status);
+ return status;
+ }
+ }
+
+ if (unloadModel && modelData.isModelLoaded()) {
+ Slog.d(TAG, "Unloading previously loaded stale model.");
+ status = mModule.unloadSoundModel(modelData.getHandle());
+ MetricsLogger.count(mContext, "sth_unloading_stale_model", 1);
+ if (status != SoundTrigger.STATUS_OK) {
+ Slog.w(TAG, "unloadSoundModel call failed with " + status);
+ } else {
+ // Clear the ModelData state if successful.
+ modelData.clearState();
+ modelData.clearCallback();
+ modelData.setRecognitionConfig(null);
+ }
+ }
+ return status;
+ }
+
+ /**
* Stops all recognitions active currently and clears the internal state.
*/
void stopAllRecognitions() {
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_stop_all_recognitions", 1);
if (mModuleProperties == null || mModule == null) {
return;
}
// Stop Keyphrase recognition if one exists.
- if (mCurrentKeyphraseModelHandle != INVALID_VALUE) {
-
- mRequested = false;
- int status = updateRecognitionLocked(
+ if (mKeyphraseModelData != null && mKeyphraseModelData.getHandle() != INVALID_VALUE) {
+ mKeyphraseModelData.setRequested(false);
+ int status = updateRecognitionLocked(mKeyphraseModelData, isRecognitionAllowed(),
false /* don't notify for synchronous calls */);
internalClearKeyphraseStateLocked();
}
@@ -457,7 +486,7 @@
// Stop all generic recognition models.
for (ModelData model : mGenericModelDataMap.values()) {
if (model.isModelStarted()) {
- int status = stopGenericRecognitionLocked(model,
+ int status = stopRecognitionLocked(model,
false /* do not notify for synchronous calls */);
if (status != STATUS_OK) {
// What else can we do if there is an error here.
@@ -476,39 +505,40 @@
}
int unloadKeyphraseSoundModel(int keyphraseId) {
- if (mModule == null || mCurrentKeyphraseModelHandle == INVALID_VALUE) {
- return STATUS_ERROR;
- }
- if (mKeyphraseId != keyphraseId) {
- Slog.w(TAG, "Given sound model is not the one loaded.");
- return STATUS_ERROR;
- }
-
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_unload_keyphrase_sound_model", 1);
+ if (mModule == null || mKeyphraseModelData == null ||
+ mKeyphraseModelData.getHandle() == INVALID_VALUE) {
+ return STATUS_ERROR;
+ }
+
// Stop recognition if it's the current one.
- mRequested = false;
- int status = updateRecognitionLocked(false /* don't notify */);
+ mKeyphraseModelData.setRequested(false);
+ int status = updateRecognitionLocked(mKeyphraseModelData, isRecognitionAllowed(),
+ false /* don't notify */);
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "Stop recognition failed for keyphrase ID:" + status);
}
- status = mModule.unloadSoundModel(mCurrentKeyphraseModelHandle);
+ status = mModule.unloadSoundModel(mKeyphraseModelData.getHandle());
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "unloadKeyphraseSoundModel call failed with " + status);
}
- internalClearKeyphraseSoundModelLocked();
+ mKeyphraseModelData.clearState();
return status;
}
}
int unloadGenericSoundModel(UUID modelId) {
- if (modelId == null || mModule == null) {
- return STATUS_ERROR;
- }
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_unload_generic_sound_model", 1);
+ if (modelId == null || mModule == null) {
+ return STATUS_ERROR;
+ }
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) {
- Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" + modelId);
+ Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" +
+ modelId);
return STATUS_ERROR;
}
if (!modelData.isModelLoaded()) {
@@ -517,7 +547,7 @@
return STATUS_OK;
}
if (modelData.isModelStarted()) {
- int status = stopGenericRecognitionLocked(modelData,
+ int status = stopRecognitionLocked(modelData,
false /* don't notify for synchronous calls */);
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "stopGenericRecognition failed: " + status);
@@ -577,6 +607,7 @@
}
private void onGenericRecognitionSuccessLocked(GenericRecognitionEvent event) {
+ MetricsLogger.count(mContext, "sth_generic_recognition_event", 1);
if (event.status != SoundTrigger.RECOGNITION_STATUS_SUCCESS) {
return;
}
@@ -608,9 +639,11 @@
return;
}
+ model.setRequested(config.allowMultipleTriggers);
// TODO: Remove this block if the lower layer supports multiple triggers.
- if (config.allowMultipleTriggers) {
- startGenericRecognitionLocked(model, true /* notify */);
+ if (model.getRequested()) {
+ updateRecognitionLocked(model, isRecognitionAllowed() /* isAllowed */,
+ true /* notify */);
}
}
@@ -622,6 +655,7 @@
}
if (DBG) Slog.d(TAG, "onSoundModelUpdate: " + event);
synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_sound_model_updated", 1);
onSoundModelUpdatedLocked(event);
}
}
@@ -637,6 +671,7 @@
@Override
public void onServiceDied() {
Slog.e(TAG, "onServiceDied!!");
+ MetricsLogger.count(mContext, "sth_service_died", 1);
synchronized (mLock) {
onServiceDiedLocked();
}
@@ -649,7 +684,7 @@
return;
}
mCallActive = callActive;
- updateRecognitionLocked(true /* notify */);
+ updateAllRecognitionsLocked(true /* notify */);
}
private void onPowerSaveModeChangedLocked(boolean isPowerSaveMode) {
@@ -657,7 +692,7 @@
return;
}
mIsPowerSaveMode = isPowerSaveMode;
- updateRecognitionLocked(true /* notify */);
+ updateAllRecognitionsLocked(true /* notify */);
}
private void onSoundModelUpdatedLocked(SoundModelEvent event) {
@@ -669,11 +704,12 @@
return;
}
mServiceDisabled = disabled;
- updateRecognitionLocked(true /* notify */);
+ updateAllRecognitionsLocked(true /* notify */);
}
private void onRecognitionAbortLocked() {
Slog.w(TAG, "Recognition aborted");
+ MetricsLogger.count(mContext, "sth_recognition_aborted", 1);
// If abort has been called, the hardware has already stopped recognition, so we shouldn't
// call it again when we process the state change.
mRecognitionAborted = true;
@@ -681,23 +717,29 @@
private void onRecognitionFailureLocked() {
Slog.w(TAG, "Recognition failure");
+ MetricsLogger.count(mContext, "sth_recognition_failure_event", 1);
try {
- if (mKeyphraseListener != null) {
- mKeyphraseListener.onError(STATUS_ERROR);
- }
+ sendErrorCallbacksToAll(STATUS_ERROR);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onError", e);
} finally {
internalClearKeyphraseStateLocked();
+ internalClearGenericModelStateLocked();
internalClearGlobalStateLocked();
}
}
private void onKeyphraseRecognitionSuccessLocked(KeyphraseRecognitionEvent event) {
Slog.i(TAG, "Recognition success");
+ MetricsLogger.count(mContext, "sth_keyphrase_recognition_event", 1);
- if (mKeyphraseListener == null) {
- Slog.w(TAG, "received onRecognition event without any listener for it");
+ if (mKeyphraseModelData == null) {
+ Slog.e(TAG, "Received onRecognition event for null keyphrase model data.");
+ return;
+ }
+
+ if (mKeyphraseModelData.getCallback() == null) {
+ Slog.w(TAG, "Received onRecognition event without any listener for it.");
return;
}
@@ -714,30 +756,62 @@
}
try {
- if (mKeyphraseListener != null) {
- mKeyphraseListener.onKeyphraseDetected((KeyphraseRecognitionEvent) event);
- }
+ mKeyphraseModelData.getCallback().onKeyphraseDetected(
+ (KeyphraseRecognitionEvent) event);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onKeyphraseDetected", e);
}
- mKeyphraseStarted = false;
- mRequested = mRecognitionConfig.allowMultipleTriggers;
+ mKeyphraseModelData.setStopped();
+
+ RecognitionConfig config = mKeyphraseModelData.getRecognitionConfig();
+ if (config != null) {
+ // Whether we should continue by starting this again.
+ mKeyphraseModelData.setRequested(config.allowMultipleTriggers);
+ }
// TODO: Remove this block if the lower layer supports multiple triggers.
- if (mRequested) {
- updateRecognitionLocked(true /* notify */);
+ if (mKeyphraseModelData.getRequested()) {
+ updateRecognitionLocked(mKeyphraseModelData, isRecognitionAllowed(),
+ true /* notify */);
+ }
+ }
+
+ private void updateAllRecognitionsLocked(boolean notify) {
+ boolean isAllowed = isRecognitionAllowed();
+ // Keyphrase model.
+ if (mKeyphraseModelData != null) {
+ updateRecognitionLocked(mKeyphraseModelData, isAllowed, notify);
+ }
+ for (UUID modelId : mGenericModelDataMap.keySet()) {
+ ModelData modelData = mGenericModelDataMap.get(modelId);
+ updateRecognitionLocked(modelData, isAllowed, notify);
+ }
+ }
+
+ private int updateRecognitionLocked(ModelData model, boolean isAllowed,
+ boolean notify) {
+ boolean start = model.getRequested() && isAllowed;
+ if (start == model.isModelStarted()) {
+ // No-op.
+ return STATUS_OK;
+ }
+ if (start) {
+ return startRecognitionLocked(model, notify);
+ } else {
+ return stopRecognitionLocked(model, notify);
}
}
private void onServiceDiedLocked() {
try {
- if (mKeyphraseListener != null) {
- mKeyphraseListener.onError(SoundTrigger.STATUS_DEAD_OBJECT);
- }
+ MetricsLogger.count(mContext, "sth_service_died", 1);
+ sendErrorCallbacksToAll(SoundTrigger.STATUS_DEAD_OBJECT);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onError", e);
} finally {
- internalClearKeyphraseSoundModelLocked();
+ if (mKeyphraseModelData != null) {
+ mKeyphraseModelData.clearState();
+ }
internalClearKeyphraseStateLocked();
internalClearGenericModelStateLocked();
internalClearGlobalStateLocked();
@@ -748,78 +822,6 @@
}
}
- private int updateRecognitionLocked(boolean notify) {
- if (mModule == null || mModuleProperties == null
- || mCurrentKeyphraseModelHandle == INVALID_VALUE || mKeyphraseListener == null) {
- // Nothing to do here.
- return STATUS_OK;
- }
-
- boolean start = mRequested && !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
- if (start == mKeyphraseStarted) {
- // No-op.
- return STATUS_OK;
- }
-
- // See if the recognition needs to be started.
- if (start) {
- // Start recognition.
- int status = mModule.startRecognition(mCurrentKeyphraseModelHandle,
- mRecognitionConfig);
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "startKeyphraseRecognition failed with " + status);
- // Notify of error if needed.
- if (notify) {
- try {
- mKeyphraseListener.onError(status);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onError", e);
- }
- }
- } else {
- mKeyphraseStarted = true;
- // Notify of resume if needed.
- if (notify) {
- try {
- mKeyphraseListener.onRecognitionResumed();
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
- }
- }
- }
- return status;
- } else {
- // Stop recognition (only if we haven't been aborted).
- int status = STATUS_OK;
- if (!mRecognitionAborted) {
- status = mModule.stopRecognition(mCurrentKeyphraseModelHandle);
- } else {
- mRecognitionAborted = false;
- }
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "stopRecognition call failed with " + status);
- if (notify) {
- try {
- mKeyphraseListener.onError(status);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onError", e);
- }
- }
- } else {
- mKeyphraseStarted = false;
- // Notify of pause if needed.
- if (notify) {
- try {
- mKeyphraseListener.onRecognitionPaused();
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
- }
- }
- }
- return status;
- }
- }
-
// internalClearGlobalStateLocked() gets split into two routines. Cleanup that is
// specific to keyphrase sound models named as internalClearKeyphraseStateLocked() and
// internalClearGlobalStateLocked() for global state. The global cleanup routine will be used
@@ -836,12 +838,14 @@
}
private void internalClearKeyphraseStateLocked() {
- mKeyphraseStarted = false;
- mRequested = false;
+ if (mKeyphraseModelData != null) {
+ mKeyphraseModelData.setStopped();
+ mKeyphraseModelData.setRequested(false);
+ mKeyphraseModelData.setRecognitionConfig(null);
+ mKeyphraseModelData.setCallback(null);
+ }
mKeyphraseId = INVALID_VALUE;
- mRecognitionConfig = null;
- mKeyphraseListener = null;
}
private void internalClearGenericModelStateLocked() {
@@ -852,13 +856,6 @@
}
}
- // This routine is a replacement for internalClearSoundModelLocked(). However, we
- // should see why this should be different from internalClearKeyphraseStateLocked().
- private void internalClearKeyphraseSoundModelLocked() {
- mCurrentKeyphraseModelHandle = INVALID_VALUE;
- mCurrentSoundModel = null;
- }
-
class MyCallStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String arg1) {
@@ -888,17 +885,13 @@
pw.print(" module properties=");
pw.println(mModuleProperties == null ? "null" : mModuleProperties);
pw.print(" keyphrase ID="); pw.println(mKeyphraseId);
- pw.print(" sound model handle="); pw.println(mCurrentKeyphraseModelHandle);
- pw.print(" sound model UUID=");
- pw.println(mCurrentSoundModel == null ? "null" : mCurrentSoundModel.uuid);
- pw.print(" current listener=");
- pw.println(mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder());
- pw.print(" requested="); pw.println(mRequested);
- pw.print(" started="); pw.println(mKeyphraseStarted);
pw.print(" call active="); pw.println(mCallActive);
pw.print(" power save mode active="); pw.println(mIsPowerSaveMode);
pw.print(" service disabled="); pw.println(mServiceDisabled);
+ if (mKeyphraseModelData != null) {
+ pw.println(mKeyphraseModelData.toString());
+ }
}
}
@@ -919,11 +912,25 @@
mIsPowerSaveMode = mPowerManager.isPowerSaveMode();
}
+ // Sends an error callback to all models with a valid registered callback.
+ private void sendErrorCallbacksToAll(int errorCode) throws RemoteException {
+ IRecognitionStatusCallback keyphraseListener = mKeyphraseModelData.getCallback();
+ if (keyphraseListener != null) {
+ keyphraseListener.onError(STATUS_ERROR);
+ }
+ for (UUID modelId: mGenericModelDataMap.keySet()) {
+ ModelData modelData = mGenericModelDataMap.get(modelId);
+ IRecognitionStatusCallback keyphraseCallback = mKeyphraseModelData.getCallback();
+ if (keyphraseCallback != null) {
+ keyphraseCallback.onError(STATUS_ERROR);
+ }
+ }
+ }
+
private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) {
- modelData = new ModelData(modelId);
- modelData.setTypeGeneric();
+ modelData = ModelData.createGenericModelData(modelId);
mGenericModelDataMap.put(modelId, modelData);
}
return modelData;
@@ -949,25 +956,30 @@
return !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
}
- private int startGenericRecognitionLocked(ModelData modelData, boolean notify) {
+ // A single routine that implements the start recognition logic for both generic and keyphrase
+ // models.
+ private int startRecognitionLocked(ModelData modelData, boolean notify) {
IRecognitionStatusCallback callback = modelData.getCallback();
int handle = modelData.getHandle();
RecognitionConfig config = modelData.getRecognitionConfig();
if (callback == null || handle == INVALID_VALUE || config == null) {
// Nothing to do here.
- Slog.w(TAG, "startGenericRecognition: Bad data passed in.");
+ Slog.w(TAG, "startRecognition: Bad data passed in.");
+ MetricsLogger.count(mContext, "sth_start_recognition_error", 1);
return STATUS_ERROR;
}
if (!isRecognitionAllowed()) {
// Nothing to do here.
- Slog.w(TAG, "startGenericRecognition requested but not allowed.");
+ Slog.w(TAG, "startRecognition requested but not allowed.");
+ MetricsLogger.count(mContext, "sth_start_recognition_not_allowed", 1);
return STATUS_OK;
}
int status = mModule.startRecognition(handle, config);
if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "startGenericRecognition failed with " + status);
+ Slog.w(TAG, "startRecognition failed with " + status);
+ MetricsLogger.count(mContext, "sth_start_recognition_error", 1);
// Notify of error if needed.
if (notify) {
try {
@@ -978,6 +990,7 @@
}
} else {
Slog.i(TAG, "startRecognition successful.");
+ MetricsLogger.count(mContext, "sth_start_recognition_success", 1);
modelData.setStarted();
// Notify of resume if needed.
if (notify) {
@@ -988,17 +1001,31 @@
}
}
}
- if (DBG) dumpGenericModelStateLocked();
+ if (DBG) {
+ Slog.d(TAG, "Model being started :" + modelData.toString());
+ }
return status;
}
- private int stopGenericRecognitionLocked(ModelData modelData, boolean notify) {
+ private int stopRecognitionLocked(ModelData modelData, boolean notify) {
IRecognitionStatusCallback callback = modelData.getCallback();
// Stop recognition (only if we haven't been aborted).
- int status = mModule.stopRecognition(modelData.getHandle());
+ int status = STATUS_OK;
+
+ // This logic for "recognition aborted" now works for both generic and keyphrase models.
+ // The idea here is to "skip" the stopRecognition() call if the lower layer has
+ // aborted recognition. Also we "consume" the abort state as well, so if there is another
+ // stopRecognition() request, it will go through -- this seems to have been the previously
+ // intended design.
+ if (!mRecognitionAborted) {
+ status = mModule.stopRecognition(modelData.getHandle());
+ } else {
+ mRecognitionAborted = false;
+ }
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "stopRecognition call failed with " + status);
+ MetricsLogger.count(mContext, "sth_stop_recognition_error", 1);
if (notify) {
try {
callback.onError(status);
@@ -1008,6 +1035,7 @@
}
} else {
modelData.setStopped();
+ MetricsLogger.count(mContext, "sth_stop_recognition_success", 1);
// Notify of pause if needed.
if (notify) {
try {
@@ -1017,7 +1045,9 @@
}
}
}
- if (DBG) dumpGenericModelStateLocked();
+ if (DBG) {
+ Slog.d(TAG, "Model being stopped :" + modelData.toString());
+ }
return status;
}
@@ -1035,8 +1065,9 @@
mRecognitionRunning = false;
return mRecognitionRunning;
}
- if (mKeyphraseListener != null && mKeyphraseStarted &&
- mCurrentKeyphraseModelHandle != INVALID_VALUE && mCurrentSoundModel != null) {
+ if (mKeyphraseModelData != null && mKeyphraseModelData.getCallback() != null &&
+ mKeyphraseModelData.isModelStarted() &&
+ mKeyphraseModelData.getHandle() != INVALID_VALUE) {
mRecognitionRunning = true;
return mRecognitionRunning;
}
@@ -1065,26 +1096,55 @@
// One of MODEL_NOTLOADED, MODEL_LOADED, MODEL_STARTED (which implies loaded).
private int mModelState;
-
private UUID mModelId;
+ // mRequested captures the explicit intent that a start was requested for this model. We
+ // continue to capture and retain this state even after the model gets started, so that we
+ // know when a model gets stopped due to "other" reasons, that we should start it again.
+ // This was the intended behavior of the "mRequested" variable in the previous version of
+ // this code that we are replicating here.
+ //
+ // The "other" reasons include power save, abort being called from the lower layer (due
+ // to concurrent capture not being supported) and phone call state. Once we recover from
+ // these transient disruptions, we would start such models again where mRequested == true.
+ // Thus, mRequested gets reset only when there is an explicit intent to stop the model
+ // coming from the SoundTriggerService layer that uses this class (and thus eventually
+ // from the app that manages this model).
+ private boolean mRequested = false;
+
// One of SoundModel.TYPE_GENERIC or SoundModel.TYPE_KEYPHRASE. Initially set
// to SoundModel.TYPE_UNKNOWN;
private int mModelType = SoundModel.TYPE_UNKNOWN;
+
private IRecognitionStatusCallback mCallback = null;
private RecognitionConfig mRecognitionConfig = null;
-
// Model handle is an integer used by the HAL as an identifier for sound
// models.
private int mModelHandle = INVALID_VALUE;
- ModelData(UUID modelId) {
+ // The SoundModel instance, one of KeyphraseSoundModel or GenericSoundModel.
+ private SoundModel mSoundModel = null;
+
+ private ModelData(UUID modelId, int modelType) {
mModelId = modelId;
+ // Private constructor, since we require modelType to be one of TYPE_GENERIC,
+ // TYPE_KEYPHRASE or TYPE_UNKNOWN.
+ mModelType = modelType;
}
- synchronized void setTypeGeneric() {
- mModelType = SoundModel.TYPE_GENERIC_SOUND;
+ static ModelData createKeyphraseModelData(UUID modelId) {
+ return new ModelData(modelId, SoundModel.TYPE_KEYPHRASE);
+ }
+
+ static ModelData createGenericModelData(UUID modelId) {
+ return new ModelData(modelId, SoundModel.TYPE_GENERIC_SOUND);
+ }
+
+ // Note that most of the functionality in this Java class will not work for
+ // SoundModel.TYPE_UNKNOWN nevertheless we have it since lower layers support it.
+ static ModelData createModelDataOfUnknownType(UUID modelId) {
+ return new ModelData(modelId, SoundModel.TYPE_UNKNOWN);
}
synchronized void setCallback(IRecognitionStatusCallback callback) {
@@ -1099,6 +1159,10 @@
return (mModelState == MODEL_LOADED || mModelState == MODEL_STARTED);
}
+ synchronized boolean isModelNotLoaded() {
+ return mModelState == MODEL_NOTLOADED;
+ }
+
synchronized void setStarted() {
mModelState = MODEL_STARTED;
}
@@ -1136,11 +1200,40 @@
return mModelHandle;
}
+ synchronized UUID getModelId() {
+ return mModelId;
+ }
+
synchronized RecognitionConfig getRecognitionConfig() {
return mRecognitionConfig;
}
- String stateToString() {
+ // Whether a start recognition was requested.
+ synchronized boolean getRequested() {
+ return mRequested;
+ }
+
+ synchronized void setRequested(boolean requested) {
+ mRequested = requested;
+ }
+
+ synchronized void setSoundModel(SoundModel soundModel) {
+ mSoundModel = soundModel;
+ }
+
+ synchronized SoundModel getSoundModel() {
+ return mSoundModel;
+ }
+
+ synchronized int getModelType() {
+ return mModelType;
+ }
+
+ synchronized boolean isKeyphraseModel() {
+ return mModelType == SoundModel.TYPE_KEYPHRASE;
+ }
+
+ synchronized String stateToString() {
switch(mModelState) {
case MODEL_NOTLOADED: return "NOT_LOADED";
case MODEL_LOADED: return "LOADED";
@@ -1149,8 +1242,24 @@
return "Unknown state";
}
- public String toString() {
- return "Handle: " + mModelHandle + "ModelState: " + stateToString();
+ synchronized String requestedToString() {
+ return "Requested: " + (mRequested ? "Yes" : "No");
+ }
+
+ synchronized String callbackToString() {
+ return "Callback: " + (mCallback != null ? mCallback.asBinder() : "null");
+ }
+
+ synchronized String uuidToString() {
+ return "UUID: " + mModelId;
+ }
+
+ synchronized public String toString() {
+ return "Handle: " + mModelHandle + "\n" +
+ "ModelState: " + stateToString() + "\n" +
+ requestedToString() + "\n" +
+ callbackToString() + "\n" +
+ uuidToString();
}
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 461611d..adc7c21 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -419,6 +419,13 @@
public static final String KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG =
"carrier_data_call_apn_delay_faster_long";
+ /**
+ * Default APN types that are metered by the carrier
+ * @hide
+ */
+ public static final String KEY_CARRIER_METERED_APN_TYPES_STRINGS =
+ "carrier_metered_apn_types_strings";
+
/* The following 3 fields are related to carrier visual voicemail. */
/**
@@ -699,6 +706,8 @@
sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG, 20000);
sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 3000);
sDefaults.putInt(KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT, 7200);
+ sDefaults.putStringArray(KEY_CARRIER_METERED_APN_TYPES_STRINGS,
+ new String[]{"default", "mms", "dun", "supl"});
sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 0da1bb1..6c8be39 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -86,6 +86,155 @@
}
private Test[] mTests = new Test[] {
+ new Test("Post a group") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("Min priority group 1")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setGroup("group1")
+ .build();
+ mNM.notify(6000, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("low priority group 1")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setGroup("group1")
+ .build();
+ mNM.notify(6001, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("default priority group 1")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setGroup("group1")
+ .build();
+ mNM.notify(6002, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("summary group 1")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setGroup("group1")
+ .setGroupSummary(true)
+ .build();
+ mNM.notify(6003, n);
+ }
+ },
+ new Test("Post a group (2) w/o summary") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("Min priority group 2")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setGroup("group2")
+ .build();
+ mNM.notify(6100, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("low priority group 2")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setGroup("group2")
+ .build();
+ mNM.notify(6101, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("default priority group 2")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setGroup("group2")
+ .build();
+ mNM.notify(6102, n);
+ }
+ },
+ new Test("Summary for group 2") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("summary group 2")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setGroup("group2")
+ .setGroupSummary(true)
+ .build();
+ mNM.notify(6103, n);
+ }
+ },
+ new Test("Group up public-secret") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("public notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setGroup("public-secret")
+ .build();
+ mNM.notify("public", 7009, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("private only notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PRIVATE)
+ .setGroup("public-secret")
+ .build();
+ mNM.notify("no public", 7010, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("private version of notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PRIVATE)
+ .setGroup("public-secret")
+ .setPublicVersion(new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("public notification of private notification")
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .build())
+ .build();
+ mNM.notify("priv with pub", 7011, n);
+ n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("secret notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_SECRET)
+ .setGroup("public-secret")
+ .build();
+ mNM.notify("secret", 7012, n);
+
+ Notification s = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("summary group public-secret")
+ .setLights(0xff0000ff, 1, 0)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setGroup("public-secret")
+ .setGroupSummary(true)
+ .build();
+ mNM.notify(7113, s);
+ }
+ },
+ new Test("Cancel priority autogroup") {
+ public void run()
+ {
+ try {
+ mNM.cancel(Integer.MAX_VALUE);
+ } catch (Exception e) {
+ Toast.makeText(NotificationTestList.this, "cancel failed (yay)",
+ Toast.LENGTH_LONG).show();
+ }
+ }
+ },
new Test("Min priority") {
public void run()
{
@@ -95,7 +244,7 @@
.setLights(0xff0000ff, 1, 0)
.setPriority(Notification.PRIORITY_MIN)
.build();
- mNM.notify(7000, n);
+ mNM.notify("min", 7000, n);
}
},
new Test("Min priority, high pri flag") {
@@ -123,7 +272,7 @@
.setLights(0xff0000ff, 1, 0)
.setPriority(Notification.PRIORITY_LOW)
.build();
- mNM.notify(7002, n);
+ mNM.notify("low", 7002, n);
}
},
new Test("Default priority") {
@@ -135,7 +284,7 @@
.setLights(0xff0000ff, 1, 0)
.setPriority(Notification.PRIORITY_DEFAULT)
.build();
- mNM.notify(7004, n);
+ mNM.notify("default", 7004, n);
}
},
new Test("High priority") {
@@ -150,7 +299,7 @@
getPackageName() + "/raw/ringer"))
.setPriority(Notification.PRIORITY_HIGH)
.build();
- mNM.notify(7006, n);
+ mNM.notify("high", 7006, n);
}
},
new Test("Max priority") {
@@ -166,7 +315,7 @@
.setPriority(Notification.PRIORITY_MAX)
.setFullScreenIntent(makeIntent2(), false)
.build();
- mNM.notify(7007, n);
+ mNM.notify("max", 7007, n);
}
},
new Test("Max priority with delay") {
@@ -199,7 +348,7 @@
.setPriority(Notification.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.build();
- mNM.notify(7009, n);
+ mNM.notify("public", 7009, n);
}
},
new Test("private notification, no public") {
@@ -212,7 +361,7 @@
.setPriority(Notification.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.build();
- mNM.notify(7010, n);
+ mNM.notify("no public", 7010, n);
}
},
new Test("private notification, has public") {
@@ -231,7 +380,7 @@
.setVisibility(Notification.VISIBILITY_PUBLIC)
.build())
.build();
- mNM.notify(7011, n);
+ mNM.notify("priv with pub", 7011, n);
}
},
new Test("secret notification") {
@@ -244,7 +393,7 @@
.setPriority(Notification.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_SECRET)
.build();
- mNM.notify(7012, n);
+ mNM.notify("secret", 7012, n);
}
},
new Test("Off") {
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 0bb88a7..db40416 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -492,6 +492,21 @@
SortedVector<String8> reasons;
};
+struct Feature {
+ Feature() : required(false), version(-1) {}
+ Feature(bool required, int32_t version = -1) : required(required), version(version) {}
+
+ /**
+ * Whether the feature is required.
+ */
+ bool required;
+
+ /**
+ * What version of the feature is requested.
+ */
+ int32_t version;
+};
+
/**
* Represents a <feature-group> tag in the AndroidManifest.xml
*/
@@ -506,7 +521,7 @@
/**
* Explicit features defined in the group
*/
- KeyedVector<String8, bool> features;
+ KeyedVector<String8, Feature> features;
/**
* OpenGL ES version required
@@ -541,11 +556,18 @@
const size_t numFeatures = grp.features.size();
for (size_t i = 0; i < numFeatures; i++) {
- const bool required = grp.features[i];
+ const Feature& feature = grp.features[i];
+ const bool required = feature.required;
+ const int32_t version = feature.version;
const String8& featureName = grp.features.keyAt(i);
- printf(" uses-feature%s: name='%s'\n", (required ? "" : "-not-required"),
+ printf(" uses-feature%s: name='%s'", (required ? "" : "-not-required"),
ResTable::normalizeForOutput(featureName.string()).string());
+
+ if (version > 0) {
+ printf(" version='%d'", version);
+ }
+ printf("\n");
}
const size_t numImpliedFeatures =
@@ -590,15 +612,15 @@
static void addParentFeatures(FeatureGroup* grp, const String8& name) {
if (name == "android.hardware.camera.autofocus" ||
name == "android.hardware.camera.flash") {
- grp->features.add(String8("android.hardware.camera"), true);
+ grp->features.add(String8("android.hardware.camera"), Feature(true));
} else if (name == "android.hardware.location.gps" ||
name == "android.hardware.location.network") {
- grp->features.add(String8("android.hardware.location"), true);
+ grp->features.add(String8("android.hardware.location"), Feature(true));
} else if (name == "android.hardware.touchscreen.multitouch") {
- grp->features.add(String8("android.hardware.touchscreen"), true);
+ grp->features.add(String8("android.hardware.touchscreen"), Feature(true));
} else if (name == "android.hardware.touchscreen.multitouch.distinct") {
- grp->features.add(String8("android.hardware.touchscreen.multitouch"), true);
- grp->features.add(String8("android.hardware.touchscreen"), true);
+ grp->features.add(String8("android.hardware.touchscreen.multitouch"), Feature(true));
+ grp->features.add(String8("android.hardware.touchscreen"), Feature(true));
} else if (name == "android.hardware.opengles.aep") {
const int openGLESVersion31 = 0x00030001;
if (openGLESVersion31 > grp->openGLESVersion) {
@@ -727,6 +749,9 @@
return 1;
}
+ // Source for AndroidManifest.xml
+ const String8 manifestFile = String8::format("%s@AndroidManifest.xml", filename);
+
// The dynamicRefTable can be null if there are no resources for this asset cookie.
// This fine.
const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie);
@@ -1424,10 +1449,28 @@
} else if (tag == "uses-feature") {
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (name != "" && error == "") {
- int req = AaptXml::getIntegerAttribute(tree,
- REQUIRED_ATTR, 1);
+ const char* androidSchema =
+ "http://schemas.android.com/apk/res/android";
- commonFeatures.features.add(name, req);
+ int32_t req = AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1,
+ &error);
+ if (error != "") {
+ SourcePos(manifestFile, tree.getLineNumber()).error(
+ "failed to read attribute 'android:required': %s",
+ error.string());
+ goto bail;
+ }
+
+ int32_t version = AaptXml::getIntegerAttribute(tree, androidSchema,
+ "version", 0, &error);
+ if (error != "") {
+ SourcePos(manifestFile, tree.getLineNumber()).error(
+ "failed to read attribute 'android:version': %s",
+ error.string());
+ goto bail;
+ }
+
+ commonFeatures.features.add(name, Feature(req != 0, version));
if (req) {
addParentFeatures(&commonFeatures, name);
}
@@ -1751,12 +1794,27 @@
}
}
} else if (withinFeatureGroup && tag == "uses-feature") {
+ const String8 androidSchema("http://schemas.android.com/apk/res/android");
FeatureGroup& top = featureGroups.editTop();
String8 name = AaptXml::getResolvedAttribute(res, tree, NAME_ATTR, &error);
if (name != "" && error == "") {
- top.features.add(name, true);
+ Feature feature(true);
+
+ int32_t featureVers = AaptXml::getIntegerAttribute(
+ tree, androidSchema.string(), "version", 0, &error);
+ if (error == "") {
+ feature.version = featureVers;
+ } else {
+ SourcePos(manifestFile, tree.getLineNumber()).error(
+ "failed to read attribute 'android:version': %s",
+ error.string());
+ goto bail;
+ }
+
+ top.features.add(name, feature);
addParentFeatures(&top, name);
+
} else {
int vers = AaptXml::getIntegerAttribute(tree, GL_ES_VERSION_ATTR,
&error);
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index ef11d66..3a1e2bb 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -131,33 +131,40 @@
libbase \
libprotobuf-cpp-lite_static
-# Do not add any shared libraries. AAPT2 is built to run on many
-# environments that may not have the required dependencies.
-hostSharedLibs :=
-ifneq ($(strip $(USE_MINGW)),)
- hostStaticLibs += libz
-else
- hostLdLibs += -lz
-endif
+# Statically link libz for MinGW (Win SDK under Linux),
+# and dynamically link for all others.
+hostStaticLibs_windows := libz
+hostLdLibs_linux := -lz
+hostLdLibs_darwin := -lz
cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
-cppFlags := -std=c++14 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
+cFlags_darwin := -D_DARWIN_UNLIMITED_STREAMS
+cFlags_windows := -Wno-maybe-uninitialized # Incorrectly marking use of Maybe.value() as error.
+cppFlags := -std=c++11 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST)
# ==========================================================
+# NOTE: Do not add any shared libraries.
+# AAPT2 is built to run on many environments
+# that may not have the required dependencies.
+# ==========================================================
+
+# ==========================================================
# Build the host static library: libaapt2
# ==========================================================
include $(CLEAR_VARS)
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libaapt2
-
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := $(cFlags)
+LOCAL_CFLAGS_darwin := $(cFlags_darwin)
+LOCAL_CFLAGS_windows := $(cFlags_windows)
+LOCAL_CPPFLAGS := $(cppFlags)
+LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(sources)
-LOCAL_STATIC_LIBRARIES += $(hostStaticLibs)
-LOCAL_CFLAGS += $(cFlags)
-LOCAL_CPPFLAGS += $(cppFlags)
-LOCAL_C_INCLUDES += $(protoIncludes)
-
+LOCAL_STATIC_LIBRARIES := $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
include $(BUILD_HOST_STATIC_LIBRARY)
# ==========================================================
@@ -166,16 +173,18 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libaapt2_tests
LOCAL_MODULE_TAGS := tests
-
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := $(cFlags)
+LOCAL_CFLAGS_darwin := $(cFlags_darwin)
+LOCAL_CFLAGS_windows := $(cFlags_windows)
+LOCAL_CPPFLAGS := $(cppFlags)
+LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(testSources)
-
-LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
-LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
-LOCAL_LDLIBS += $(hostLdLibs)
-LOCAL_CFLAGS += $(cFlags)
-LOCAL_CPPFLAGS += $(cppFlags)
-LOCAL_C_INCLUDES += $(protoIncludes)
-
+LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
+LOCAL_LDLIBS := $(hostLdLibs)
+LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
include $(BUILD_HOST_NATIVE_TEST)
# ==========================================================
@@ -183,16 +192,18 @@
# ==========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := aapt2
-
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := $(cFlags)
+LOCAL_CFLAGS_darwin := $(cFlags_darwin)
+LOCAL_CFLAGS_windows := $(cFlags_windows)
+LOCAL_CPPFLAGS := $(cppFlags)
+LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(main) $(toolSources)
-
-LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
-LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
-LOCAL_LDLIBS += $(hostLdLibs)
-LOCAL_CFLAGS += $(cFlags)
-LOCAL_CPPFLAGS += $(cppFlags)
-LOCAL_C_INCLUDES += $(protoIncludes)
-
+LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
+LOCAL_LDLIBS := $(hostLdLibs)
+LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
include $(BUILD_HOST_EXECUTABLE)
ifeq ($(ONE_SHOT_MAKEFILE),)
diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp
index e93c2fba..2b2d348 100644
--- a/tools/aapt2/StringPool_test.cpp
+++ b/tools/aapt2/StringPool_test.cpp
@@ -20,8 +20,6 @@
#include <gtest/gtest.h>
#include <string>
-using namespace android;
-
namespace aapt {
TEST(StringPoolTest, InsertOneString) {
@@ -171,24 +169,28 @@
}
TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
+ using namespace android; // For NO_ERROR on Windows.
+
StringPool pool;
BigBuffer buffer(1024);
StringPool::flattenUtf8(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
- android::ResStringPool test;
- ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
+ ResStringPool test;
+ ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
}
TEST(StringPoolTest, FlattenOddCharactersUtf16) {
+ using namespace android; // For NO_ERROR on Windows.
+
StringPool pool;
pool.makeRef(u"\u093f");
BigBuffer buffer(1024);
StringPool::flattenUtf16(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
- android::ResStringPool test;
- ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
+ ResStringPool test;
+ ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
size_t len = 0;
const char16_t* str = test.stringAt(0, &len);
EXPECT_EQ(1u, len);
@@ -199,6 +201,8 @@
constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。";
TEST(StringPoolTest, FlattenUtf8) {
+ using namespace android; // For NO_ERROR on Windows.
+
StringPool pool;
StringPool::Ref ref1 = pool.makeRef(u"hello");
@@ -219,8 +223,8 @@
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
{
- android::ResStringPool test;
- ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
+ ResStringPool test;
+ ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
EXPECT_EQ(util::getString(test, 0), u"hello");
EXPECT_EQ(util::getString(test, 1), u"goodbye");
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index be26b52..99c2077 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -20,6 +20,8 @@
#include "compile/PseudolocaleGenerator.h"
#include "compile/Pseudolocalizer.h"
+#include <algorithm>
+
namespace aapt {
std::unique_ptr<StyledString> pseudolocalizeStyledString(StyledString* string,
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index da81046..28a7928 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -24,6 +24,7 @@
#include "util/BigBuffer.h"
#include <android-base/macros.h>
+#include <algorithm>
#include <type_traits>
#include <numeric>
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index 3eac633..570cd96 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -21,6 +21,7 @@
#include "xml/XmlDom.h"
#include <androidfw/ResourceTypes.h>
+#include <algorithm>
#include <utils/misc.h>
#include <vector>
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index fef5ca3..4e6eb81 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -46,6 +46,8 @@
::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree,
XmlFlattenerOptions options = {}) {
+ using namespace android; // For NO_ERROR on windows because it is a macro.
+
BigBuffer buffer(1024);
XmlFlattener flattener(&buffer, options);
if (!flattener.consume(mContext.get(), doc)) {
@@ -53,7 +55,7 @@
}
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
- if (outTree->setTo(data.get(), buffer.size(), true) != android::NO_ERROR) {
+ if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
return ::testing::AssertionFailure() << "flattened XML is corrupt";
}
return ::testing::AssertionSuccess();
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index ba74439..b7e7f90 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -21,7 +21,7 @@
namespace aapt {
-void AnnotationProcessor::appendCommentLine(const std::string& comment) {
+void AnnotationProcessor::appendCommentLine(std::string& comment) {
static const std::string sDeprecated = "@deprecated";
static const std::string sSystemApi = "@SystemApi";
@@ -29,8 +29,14 @@
mAnnotationBitMask |= kDeprecated;
}
- if (comment.find(sSystemApi) != std::string::npos) {
+ std::string::size_type idx = comment.find(sSystemApi);
+ if (idx != std::string::npos) {
mAnnotationBitMask |= kSystemApi;
+ comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size());
+ }
+
+ if (util::trimWhitespace(comment).empty()) {
+ return;
}
if (!mHasComments) {
@@ -46,7 +52,8 @@
for (StringPiece16 line : util::tokenize(comment, u'\n')) {
line = util::trimWhitespace(line);
if (!line.empty()) {
- appendCommentLine(util::utf16ToUtf8(line));
+ std::string utf8Line = util::utf16ToUtf8(line);
+ appendCommentLine(utf8Line);
}
}
}
@@ -55,7 +62,8 @@
for (StringPiece line : util::tokenize(comment, '\n')) {
line = util::trimWhitespace(line);
if (!line.empty()) {
- appendCommentLine(line.toString());
+ std::string utf8Line = line.toString();
+ appendCommentLine(utf8Line);
}
}
}
diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h
index 0fc5b08..8309dd9 100644
--- a/tools/aapt2/java/AnnotationProcessor.h
+++ b/tools/aapt2/java/AnnotationProcessor.h
@@ -43,7 +43,6 @@
* /\*
* * This is meant to be hidden because
* * It is system api. Also it is @deprecated
- * * @SystemApi
* *\/
*
* Output Annotations:
@@ -79,7 +78,7 @@
bool mHasComments = false;
uint32_t mAnnotationBitMask = 0;
- void appendCommentLine(const std::string& line);
+ void appendCommentLine(std::string& line);
};
} // namespace aapt
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index da96b84..5a39add 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -14,57 +14,18 @@
* limitations under the License.
*/
-#include "ResourceParser.h"
-#include "ResourceTable.h"
-#include "ResourceValues.h"
#include "java/AnnotationProcessor.h"
-#include "test/Builders.h"
-#include "test/Context.h"
-#include "xml/XmlPullParser.h"
-
-#include <gtest/gtest.h>
+#include "test/Test.h"
namespace aapt {
-struct AnnotationProcessorTest : public ::testing::Test {
- std::unique_ptr<IAaptContext> mContext;
- ResourceTable mTable;
-
- void SetUp() override {
- mContext = test::ContextBuilder().build();
- }
-
- ::testing::AssertionResult parse(const StringPiece& str) {
- ResourceParserOptions options;
- ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{}, ConfigDescription{},
- options);
- std::stringstream in;
- in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
- xml::XmlPullParser xmlParser(in);
- if (parser.parse(&xmlParser)) {
- return ::testing::AssertionSuccess();
- }
- return ::testing::AssertionFailure();
- }
-};
-
-TEST_F(AnnotationProcessorTest, EmitsDeprecated) {
- ASSERT_TRUE(parse(R"EOF(
- <resources>
- <declare-styleable name="foo">
- <!-- Some comment, and it should contain
- a marker word, something that marks
- this resource as nor needed.
- {@deprecated That's the marker! } -->
- <attr name="autoText" format="boolean" />
- </declare-styleable>
- </resources>)EOF"));
-
- Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText");
- ASSERT_NE(nullptr, attr);
+TEST(AnnotationProcessorTest, EmitsDeprecated) {
+ const char* comment = "Some comment, and it should contain a marker word, "
+ "something that marks this resource as nor needed. "
+ "{@deprecated That's the marker! }";
AnnotationProcessor processor;
- processor.appendComment(attr->getComment());
+ processor.appendComment(comment);
std::stringstream result;
processor.writeToStream(&result, "");
@@ -73,6 +34,19 @@
EXPECT_NE(std::string::npos, annotations.find("@Deprecated"));
}
+TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) {
+ AnnotationProcessor processor;
+ processor.appendComment("@SystemApi This is a system API");
+
+ std::stringstream result;
+ processor.writeToStream(&result, "");
+ std::string annotations = result.str();
+
+ EXPECT_NE(std::string::npos, annotations.find("@android.annotation.SystemApi"));
+ EXPECT_EQ(std::string::npos, annotations.find("@SystemApi"));
+ EXPECT_NE(std::string::npos, annotations.find("This is a system API"));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index 53e0f6f..d45328f 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -125,7 +125,7 @@
void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
ClassMember::writeToStream(prefix, final, out);
- *out << "public static final int[] " << mName << "={";
+ *out << prefix << "public static final int[] " << mName << "={";
const auto begin = mElements.begin();
const auto end = mElements.end();
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 092bab2..24347a1 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -188,8 +188,8 @@
struct StyleableAttr {
const Reference* attrRef;
- std::shared_ptr<Attribute> attribute;
std::string fieldName;
+ std::unique_ptr<SymbolTable::Symbol> symbol;
};
static bool lessStyleableAttr(const StyleableAttr& lhs, const StyleableAttr& rhs) {
@@ -245,8 +245,9 @@
// legal values for this attribute.
const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference(
mangledReference);
- if (symbol) {
- styleableAttr.attribute = symbol->attribute;
+ if (symbol && symbol->attribute) {
+ // Copy the symbol data structure because the returned instance can be destroyed.
+ styleableAttr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol);
}
sortedAttributes.push_back(std::move(styleableAttr));
}
@@ -273,6 +274,16 @@
"<tr><th>Attribute</th><th>Description</th></tr>\n";
for (const StyleableAttr& entry : sortedAttributes) {
+ if (!entry.symbol) {
+ continue;
+ }
+
+ if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+ !entry.symbol->isPublic) {
+ // Don't write entries for non-public attributes.
+ continue;
+ }
+
const ResourceName& attrName = entry.attrRef->name.value();
styleableComment << "<tr><td>";
styleableComment << "<code>{@link #"
@@ -284,14 +295,30 @@
styleableComment << "</td>";
styleableComment << "<td>";
- if (entry.attribute) {
- styleableComment << entry.attribute->getComment();
+
+ // Only use the comment up until the first '.'. This is to stay compatible with
+ // the way old AAPT did it (presumably to keep it short and to avoid including
+ // annotations like @hide which would affect this Styleable).
+ StringPiece16 attrCommentLine = entry.symbol->attribute->getComment();
+ auto iter = std::find(attrCommentLine.begin(), attrCommentLine.end(), u'.');
+ if (iter != attrCommentLine.end()) {
+ attrCommentLine = attrCommentLine.substr(
+ 0, (iter - attrCommentLine.begin()) + 1);
}
- styleableComment << "</td></tr>\n";
+ styleableComment << attrCommentLine << "</td></tr>\n";
}
styleableComment << "</table>\n";
for (const StyleableAttr& entry : sortedAttributes) {
+ if (!entry.symbol) {
+ continue;
+ }
+
+ if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+ !entry.symbol->isPublic) {
+ // Don't write entries for non-public attributes.
+ continue;
+ }
styleableComment << "@see #" << entry.fieldName << "\n";
}
@@ -310,6 +337,17 @@
// Now we emit the indices into the array.
for (size_t i = 0; i < attrCount; i++) {
const StyleableAttr& styleableAttr = sortedAttributes[i];
+
+ if (!styleableAttr.symbol) {
+ continue;
+ }
+
+ if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+ !styleableAttr.symbol->isPublic) {
+ // Don't write entries for non-public attributes.
+ continue;
+ }
+
const ResourceName& attrName = styleableAttr.attrRef->name.value();
StringPiece16 packageName = attrName.package;
@@ -318,13 +356,13 @@
}
std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>(
- sortedAttributes[i].fieldName, i);
+ sortedAttributes[i].fieldName, static_cast<uint32_t>(i));
AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder();
StringPiece16 comment = styleableAttr.attrRef->getComment();
- if (styleableAttr.attribute && comment.empty()) {
- comment = styleableAttr.attribute->getComment();
+ if (styleableAttr.symbol->attribute && comment.empty()) {
+ comment = styleableAttr.symbol->attribute->getComment();
}
if (!comment.empty()) {
@@ -342,10 +380,8 @@
attrProcessor->appendNewLine();
- if (styleableAttr.attribute) {
- addAttributeFormatDoc(attrProcessor, styleableAttr.attribute.get());
- attrProcessor->appendNewLine();
- }
+ addAttributeFormatDoc(attrProcessor, styleableAttr.symbol->attribute.get());
+ attrProcessor->appendNewLine();
std::stringstream doclavaName;
doclavaName << "@attr name " << packageName << ":" << attrName.entry;;
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index 4f041b8..7d0aa83 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -43,7 +43,8 @@
std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
.setPackageId(u"android", 0x01)
.addSimple(u"@android:id/hey-man", ResourceId(0x01020000))
- .addSimple(u"@android:attr/cool.attr", ResourceId(0x01010000))
+ .addValue(u"@android:attr/cool.attr", ResourceId(0x01010000),
+ test::AttributeBuilder(false).build())
.addValue(u"@android:styleable/hey.dude", ResourceId(0x01030000),
test::StyleableBuilder()
.addItem(u"@android:attr/cool.attr", ResourceId(0x01010000))
@@ -199,8 +200,10 @@
std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
.setPackageId(u"android", 0x01)
.setPackageId(u"com.lib", 0x02)
- .addSimple(u"@android:attr/bar", ResourceId(0x01010000))
- .addSimple(u"@com.lib:attr/bar", ResourceId(0x02010000))
+ .addValue(u"@android:attr/bar", ResourceId(0x01010000),
+ test::AttributeBuilder(false).build())
+ .addValue(u"@com.lib:attr/bar", ResourceId(0x02010000),
+ test::AttributeBuilder(false).build())
.addValue(u"@android:styleable/foo", ResourceId(0x01030000),
test::StyleableBuilder()
.addItem(u"@android:attr/bar", ResourceId(0x01010000))
@@ -239,13 +242,15 @@
ASSERT_TRUE(generator.generate(u"android", &out));
std::string actual = out.str();
- EXPECT_NE(std::string::npos, actual.find(
- R"EOF(/**
+ const char* expectedText =
+R"EOF(/**
* This is a comment
* @deprecated
*/
@Deprecated
- public static final int foo=0x01010000;)EOF"));
+ public static final int foo=0x01010000;)EOF";
+
+ EXPECT_NE(std::string::npos, actual.find(expectedText));
}
TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {
diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp
index a9ec318..d3bca70 100644
--- a/tools/aapt2/java/ManifestClassGenerator_test.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp
@@ -104,28 +104,33 @@
std::string actual;
ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
- EXPECT_NE(std::string::npos, actual.find(
+ const char* expectedAccessInternet =
R"EOF( /**
* Required to access the internet.
* Added in API 1.
*/
- public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF"));
+ public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
- EXPECT_NE(std::string::npos, actual.find(
+ EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
+
+ const char* expectedPlayOutside =
R"EOF( /**
* @deprecated This permission is for playing outside.
*/
@Deprecated
- public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF"));
+ public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
- EXPECT_NE(std::string::npos, actual.find(
+ EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
+
+ const char* expectedSecret =
R"EOF( /**
* This is a private permission for system only!
* @hide
- * @SystemApi
*/
@android.annotation.SystemApi
- public static final String SECRET="android.permission.SECRET";)EOF"));
+ public static final String SECRET="android.permission.SECRET";)EOF";
+
+ EXPECT_NE(std::string::npos, actual.find(expectedSecret));
}
} // namespace aapt
diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h
index 0a6a4a5..e684bb0 100644
--- a/tools/aapt2/process/SymbolTable.h
+++ b/tools/aapt2/process/SymbolTable.h
@@ -51,9 +51,28 @@
class SymbolTable {
public:
struct Symbol {
+ Symbol() : Symbol(Maybe<ResourceId>{}) {
+ }
+
+ Symbol(const Maybe<ResourceId>& i) : Symbol(i, nullptr) {
+ }
+
+ Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr) :
+ Symbol(i, attr, false) {
+ }
+
+ Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr, bool pub) :
+ id(i), attribute(attr), isPublic(pub) {
+ }
+
+ Symbol(const Symbol&) = default;
+ Symbol(Symbol&&) = default;
+ Symbol& operator=(const Symbol&) = default;
+ Symbol& operator=(Symbol&&) = default;
+
Maybe<ResourceId> id;
std::shared_ptr<Attribute> attribute;
- bool isPublic;
+ bool isPublic = false;
};
SymbolTable() : mCache(200), mIdCache(200) {
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index 86883f8..82e4fb0 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -388,6 +388,10 @@
std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
const Source& source,
IDiagnostics* diag) {
+ // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
+ // causes errors when qualifying it with android::
+ using namespace android;
+
std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
if (!pbTable.has_string_pool()) {
@@ -395,29 +399,29 @@
return {};
}
- android::ResStringPool valuePool;
- android::status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
- pbTable.string_pool().data().size());
- if (result != android::NO_ERROR) {
+ ResStringPool valuePool;
+ status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
+ pbTable.string_pool().data().size());
+ if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid string pool");
return {};
}
- android::ResStringPool sourcePool;
+ ResStringPool sourcePool;
if (pbTable.has_source_pool()) {
result = sourcePool.setTo(pbTable.source_pool().data().data(),
pbTable.source_pool().data().size());
- if (result != android::NO_ERROR) {
+ if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid source pool");
return {};
}
}
- android::ResStringPool symbolPool;
+ ResStringPool symbolPool;
if (pbTable.has_symbol_pool()) {
result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
pbTable.symbol_pool().data().size());
- if (result != android::NO_ERROR) {
+ if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid symbol pool");
return {};
}
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 0f7649b..4bfdb12 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -18,6 +18,7 @@
#include "ResourceTable.h"
#include "split/TableSplitter.h"
+#include <algorithm>
#include <map>
#include <set>
#include <unordered_map>
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 33b505e..ec46751 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -26,7 +26,7 @@
#include <androidfw/ResourceTypes.h>
#include <androidfw/TypeWrappers.h>
#include <android-base/macros.h>
-
+#include <algorithm>
#include <map>
#include <string>
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 6428e98..bb093ab 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -17,6 +17,7 @@
#include "util/Files.h"
#include "util/Util.h"
+#include <algorithm>
#include <cerrno>
#include <cstdio>
#include <dirent.h>
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index 10a2803..595db96 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -17,6 +17,8 @@
#ifndef AAPT_MAYBE_H
#define AAPT_MAYBE_H
+#include "util/TypeTraits.h"
+
#include <cassert>
#include <type_traits>
#include <utility>
@@ -276,13 +278,15 @@
}
/**
- * Define the == operator between Maybe<T> and Maybe<U> if the operator T == U is defined.
- * Otherwise this won't be defined and the compiler will yell at the callsite instead of inside
- * Maybe.h.
+ * Define the == operator between Maybe<T> and Maybe<U> only if the operator T == U is defined.
+ * That way the compiler will show an error at the callsite when comparing two Maybe<> objects
+ * whose inner types can't be compared.
*/
template <typename T, typename U>
-auto operator==(const Maybe<T>& a, const Maybe<U>& b)
--> decltype(std::declval<T> == std::declval<U>) {
+typename std::enable_if<
+ has_eq_op<T, U>::value,
+ bool
+>::type operator==(const Maybe<T>& a, const Maybe<U>& b) {
if (a && b) {
return a.value() == b.value();
} else if (!a && !b) {
@@ -295,8 +299,10 @@
* Same as operator== but negated.
*/
template <typename T, typename U>
-auto operator!=(const Maybe<T>& a, const Maybe<U>& b)
--> decltype(std::declval<T> == std::declval<U>) {
+typename std::enable_if<
+ has_eq_op<T, U>::value,
+ bool
+>::type operator!=(const Maybe<T>& a, const Maybe<U>& b) {
return !(a == b);
}
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index d27b62fd..0ce333a 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -228,20 +228,24 @@
std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
const Source& source) {
+ // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
+ // causes errors when qualifying it with android::
+ using namespace android;
+
std::unique_ptr<Node> root;
std::stack<Node*> nodeStack;
- android::ResXMLTree tree;
- if (tree.setTo(data, dataLen) != android::NO_ERROR) {
+ ResXMLTree tree;
+ if (tree.setTo(data, dataLen) != NO_ERROR) {
return {};
}
- android::ResXMLParser::event_code_t code;
- while ((code = tree.next()) != android::ResXMLParser::BAD_DOCUMENT &&
- code != android::ResXMLParser::END_DOCUMENT) {
+ ResXMLParser::event_code_t code;
+ while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT &&
+ code != ResXMLParser::END_DOCUMENT) {
std::unique_ptr<Node> newNode;
switch (code) {
- case android::ResXMLParser::START_NAMESPACE: {
+ case ResXMLParser::START_NAMESPACE: {
std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
size_t len;
const char16_t* str16 = tree.getNamespacePrefix(&len);
@@ -257,7 +261,7 @@
break;
}
- case android::ResXMLParser::START_TAG: {
+ case ResXMLParser::START_TAG: {
std::unique_ptr<Element> node = util::make_unique<Element>();
size_t len;
const char16_t* str16 = tree.getElementNamespace(&len);
@@ -276,7 +280,7 @@
break;
}
- case android::ResXMLParser::TEXT: {
+ case ResXMLParser::TEXT: {
std::unique_ptr<Text> node = util::make_unique<Text>();
size_t len;
const char16_t* str16 = tree.getText(&len);
@@ -287,8 +291,8 @@
break;
}
- case android::ResXMLParser::END_NAMESPACE:
- case android::ResXMLParser::END_TAG:
+ case ResXMLParser::END_NAMESPACE:
+ case ResXMLParser::END_TAG:
assert(!nodeStack.empty());
nodeStack.pop();
break;
diff --git a/tools/aapt2/xml/XmlUtil_test.cpp b/tools/aapt2/xml/XmlUtil_test.cpp
index 7796b3e..319e770 100644
--- a/tools/aapt2/xml/XmlUtil_test.cpp
+++ b/tools/aapt2/xml/XmlUtil_test.cpp
@@ -33,22 +33,22 @@
xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res/a");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"a"), p.value().package);
- EXPECT_EQ(false, p.value().privateNamespace);
+ EXPECT_FALSE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/android");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"android"), p.value().package);
- EXPECT_EQ(true, p.value().privateNamespace);
+ EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/com.test");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"com.test"), p.value().package);
- EXPECT_EQ(true, p.value().privateNamespace);
+ EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res-auto");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(), p.value().package);
- EXPECT_EQ(true, p.value().privateNamespace);
+ EXPECT_TRUE(p.value().privateNamespace);
}
} // namespace aapt
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
index 30512aa..ea9a255 100644
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
@@ -44,6 +44,11 @@
private static final float PERPENDICULAR_ANGLE = 90f;
public static void paintShadow(Outline viewOutline, float elevation, Canvas canvas) {
+ Rect outline = new Rect();
+ if (!viewOutline.getRect(outline)) {
+ throw new IllegalArgumentException("Outline is not a rect shadow");
+ }
+
float shadowSize = elevationToShadow(elevation);
int saved = modifyCanvas(canvas, shadowSize);
if (saved == -1) {
@@ -54,8 +59,7 @@
cornerPaint.setStyle(Style.FILL);
Paint edgePaint = new Paint(cornerPaint);
edgePaint.setAntiAlias(false);
- Rect outline = viewOutline.mRect;
- float radius = viewOutline.mRadius;
+ float radius = viewOutline.getRadius();
float outerArcRadius = radius + shadowSize;
int[] colors = {START_COLOR, START_COLOR, END_COLOR};
cornerPaint.setShader(new RadialGradient(0, 0, outerArcRadius, colors,
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
index 51d32e3..23caaf8 100644
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
@@ -64,7 +64,7 @@
private static void drawShadow(ViewGroup parent, Canvas canvas, View child,
Outline outline) {
float elevation = getElevation(child, parent);
- if(outline.mRect != null) {
+ if(outline.mMode == Outline.MODE_ROUND_RECT && outline.mRect != null) {
RectShadowPainter.paintShadow(outline, elevation, canvas);
return;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 2399b3a..89272fa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -639,7 +639,8 @@
}
// Add value to defaultPropsMap if needed
if (typeArrayAndPropertiesPair.getSecond() != null) {
- Object key = getCurrentParser().getViewCookie();
+ BridgeXmlBlockParser parser = getCurrentParser();
+ Object key = parser != null ? parser.getViewCookie() : null;
if (key != null) {
PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
if (defaultPropMap == null) {
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
index d8ead23..0e788e0c 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
index 65d1dc5..bad296b 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
index 2da2cb9..adb58a3 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
@@ -197,6 +197,14 @@
android:inputType="numberPassword"
android:text="numeric password" />
+ <ToggleButton
+ android:id="@+id/toggleButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@id/editText4"
+ android:layout_toEndOf="@id/editText4"
+ android:text="New ToggleButton" />
+
<EditText
android:id="@id/editText5"
android:layout_width="wrap_content"
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 034c8b2..8f570ae 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -31,8 +31,8 @@
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
@@ -42,8 +42,12 @@
import com.android.utils.ILogger;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -56,9 +60,12 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
+import com.google.android.collect.Lists;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -105,6 +112,21 @@
private static ILogger sLogger;
private static Bridge sBridge;
+ /** List of log messages generated by a render call. It can be used to find specific errors */
+ private static ArrayList<String> sRenderMessages = Lists.newArrayList();
+
+ @Rule
+ public static TestWatcher sRenderMessageWatcher = new TestWatcher() {
+ @Override
+ protected void succeeded(Description description) {
+ // We only check error messages if the rest of the test case was successful.
+ if (!sRenderMessages.isEmpty()) {
+ fail(description.getMethodName() + " render error message: " + sRenderMessages.get
+ (0));
+ }
+ }
+ };
+
static {
// Test that System Properties are properly set.
PLATFORM_DIR = getPlatformDir();
@@ -279,6 +301,11 @@
ConfigGenerator.getEnumMap(attrs), getLayoutLog());
}
+ @Before
+ public void beforeTestCase() {
+ sRenderMessages.clear();
+ }
+
/** Test activity.xml */
@Test
public void testActivity() throws ClassNotFoundException {
@@ -289,6 +316,9 @@
@Test
public void testAllWidgets() throws ClassNotFoundException {
renderAndVerify("allwidgets.xml", "allwidgets.png");
+
+ // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+ sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
}
@Test
@@ -299,6 +329,9 @@
@Test
public void testAllWidgetsTablet() throws ClassNotFoundException {
renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
+
+ // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+ sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
}
private static void gc() {
@@ -649,6 +682,6 @@
}
private static void failWithMsg(@NonNull String msgFormat, Object... args) {
- fail(args == null ? "" : String.format(msgFormat, args));
+ sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args));
}
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 6ca4393..0f84506 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -152,6 +152,8 @@
boolean enableAutoJoinWhenAssociated(boolean enabled);
boolean getEnableAutoJoinWhenAssociated();
+ void enableWifiConnectivityManager(boolean enabled);
+
WifiConnectionStatistics getConnectionStatistics();
void disableEphemeralNetwork(String SSID);
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 9e15d60..394934f 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -719,7 +719,7 @@
* Get CA certificates.
*/
@Nullable public X509Certificate[] getCaCertificates() {
- if (mCaCerts != null || mCaCerts.length > 0) {
+ if (mCaCerts != null && mCaCerts.length > 0) {
return mCaCerts;
} else {
return null;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 6653a8d..6984fe2 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2719,4 +2719,16 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Enable/disable WifiConnectivityManager
+ * @hide
+ */
+ public void enableWifiConnectivityManager(boolean enabled) {
+ try {
+ mService.enableWifiConnectivityManager(enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 73ddbbc..f8c1ea3 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -810,19 +810,17 @@
}
/**
* Stop an ongoing wifi PNO scan
- * @param pnoSettings specifies various parameters for PNO; for more information look at
- * {@link PnoSettings}
* @param listener specifies which scan to cancel; must be same object as passed in {@link
* #startPnoScan}
* TODO(rpius): Check if we can remove pnoSettings param in stop.
* {@hide}
*/
- public void stopPnoScan(PnoSettings pnoSettings, ScanListener listener) {
+ public void stopPnoScan(ScanListener listener) {
Preconditions.checkNotNull(listener, "listener cannot be null");
int key = removeListener(listener);
if (key == INVALID_KEY) return;
validateChannel();
- sAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key, pnoSettings);
+ sAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key);
}
/** specifies information about an access point of interest */