Merge "Refactoring of Program ownership/lifecycle, and WIP Glop rendering path"
diff --git a/api/current.txt b/api/current.txt
index 9c26faa..c8eefea 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1316,6 +1316,8 @@
field public static final int topRightRadius = 16843178; // 0x10101aa
field public static final int touchscreenBlocksFocus = 16843919; // 0x101048f
field public static final int track = 16843631; // 0x101036f
+ field public static final int trackTint = 16843993; // 0x10104d9
+ field public static final int trackTintMode = 16843994; // 0x10104da
field public static final int transcriptMode = 16843008; // 0x1010100
field public static final int transformPivotX = 16843552; // 0x1010320
field public static final int transformPivotY = 16843553; // 0x1010321
@@ -4767,6 +4769,37 @@
method public android.app.Notification.Builder setWhen(long);
}
+ public static final class Notification.CarExtender implements android.app.Notification.Extender {
+ ctor public Notification.CarExtender();
+ ctor public Notification.CarExtender(android.app.Notification);
+ method public android.app.Notification.Builder extend(android.app.Notification.Builder);
+ method public int getColor();
+ method public android.graphics.Bitmap getLargeIcon();
+ method public android.app.Notification.CarExtender.UnreadConversation getUnreadConversation();
+ method public android.app.Notification.CarExtender setColor(int);
+ method public android.app.Notification.CarExtender setLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.CarExtender setUnreadConversation(android.app.Notification.CarExtender.UnreadConversation);
+ }
+
+ public static class Notification.CarExtender.Builder {
+ ctor public Notification.CarExtender.Builder(java.lang.String);
+ method public android.app.Notification.CarExtender.Builder addMessage(java.lang.String);
+ method public android.app.Notification.CarExtender.UnreadConversation build();
+ method public android.app.Notification.CarExtender.Builder setLatestTimestamp(long);
+ method public android.app.Notification.CarExtender.Builder setReadPendingIntent(android.app.PendingIntent);
+ method public android.app.Notification.CarExtender.Builder setReplyAction(android.app.PendingIntent, android.app.RemoteInput);
+ }
+
+ public static class Notification.CarExtender.UnreadConversation {
+ method public long getLatestTimestamp();
+ method public java.lang.String[] getMessages();
+ method public java.lang.String getParticipant();
+ method public java.lang.String[] getParticipants();
+ method public android.app.PendingIntent getReadPendingIntent();
+ method public android.app.RemoteInput getRemoteInput();
+ method public android.app.PendingIntent getReplyPendingIntent();
+ }
+
public static abstract interface Notification.Extender {
method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
}
@@ -5453,6 +5486,7 @@
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
@@ -12684,6 +12718,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> LENS_INFO_MINIMUM_FOCUS_DISTANCE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_RAW;
@@ -12901,13 +12936,16 @@
field public static final int LENS_STATE_STATIONARY = 0; // 0x0
field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
+ field public static final int NOISE_REDUCTION_MODE_MINIMAL = 3; // 0x3
field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
@@ -13013,6 +13051,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Float> LENS_FOCUS_DISTANCE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> LENS_OPTICAL_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> NOISE_REDUCTION_MODE;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
field public static final android.hardware.camera2.CaptureRequest.Key<android.graphics.Rect> SCALER_CROP_REGION;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_FRAME_DURATION;
@@ -13090,6 +13129,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> LENS_OPTICAL_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> LENS_STATE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> NOISE_REDUCTION_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Byte> REQUEST_PIPELINE_DEPTH;
field public static final android.hardware.camera2.CaptureResult.Key<android.graphics.Rect> SCALER_CROP_REGION;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
@@ -14129,6 +14169,7 @@
method public boolean isMicrophoneMute();
method public boolean isMusicActive();
method public boolean isSpeakerphoneOn();
+ method public boolean isStreamMute(int);
method public boolean isVolumeFixed();
method public deprecated boolean isWiredHeadsetOn();
method public void loadSoundEffects();
@@ -14147,8 +14188,8 @@
method public void setRingerMode(int);
method public deprecated void setRouting(int, int, int);
method public void setSpeakerphoneOn(boolean);
- method public void setStreamMute(int, boolean);
- method public void setStreamSolo(int, boolean);
+ method public deprecated void setStreamMute(int, boolean);
+ method public deprecated void setStreamSolo(int, boolean);
method public void setStreamVolume(int, int, int);
method public deprecated void setVibrateSetting(int, int);
method public deprecated void setWiredHeadsetOn(boolean);
@@ -14166,8 +14207,11 @@
field public static final deprecated java.lang.String ACTION_SCO_AUDIO_STATE_CHANGED = "android.media.SCO_AUDIO_STATE_CHANGED";
field public static final java.lang.String ACTION_SCO_AUDIO_STATE_UPDATED = "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
field public static final int ADJUST_LOWER = -1; // 0xffffffff
+ field public static final int ADJUST_MUTE = -100; // 0xffffff9c
field public static final int ADJUST_RAISE = 1; // 0x1
field public static final int ADJUST_SAME = 0; // 0x0
+ field public static final int ADJUST_TOGGLE_MUTE = 101; // 0x65
+ field public static final int ADJUST_UNMUTE = 100; // 0x64
field public static final int AUDIOFOCUS_GAIN = 1; // 0x1
field public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; // 0x2
field public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4; // 0x4
@@ -24617,6 +24661,7 @@
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
+ field public static final java.lang.String QUERY_PARAMETER_VCARD_NO_PHOTO = "no_photo";
}
public static final class ContactsContract.Contacts.AggregationSuggestions implements android.provider.BaseColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns {
@@ -38416,6 +38461,8 @@
method public void setClippingEnabled(boolean);
method public void setContentView(android.view.View);
method public void setElevation(float);
+ method public void setEnterTransition(android.transition.Transition);
+ method public void setExitTransition(android.transition.Transition);
method public void setFocusable(boolean);
method public void setHeight(int);
method public void setIgnoreCheekPress();
@@ -39017,7 +39064,11 @@
method public java.lang.CharSequence getTextOn();
method public android.graphics.drawable.Drawable getThumbDrawable();
method public int getThumbTextPadding();
+ method public android.content.res.ColorStateList getThumbTintList();
+ method public android.graphics.PorterDuff.Mode getThumbTintMode();
method public android.graphics.drawable.Drawable getTrackDrawable();
+ method public android.content.res.ColorStateList getTrackTintList();
+ method public android.graphics.PorterDuff.Mode getTrackTintMode();
method public void onMeasure(int, int);
method public void setShowText(boolean);
method public void setSplitTrack(boolean);
@@ -39031,8 +39082,12 @@
method public void setThumbDrawable(android.graphics.drawable.Drawable);
method public void setThumbResource(int);
method public void setThumbTextPadding(int);
+ method public void setThumbTintList(android.content.res.ColorStateList);
+ method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
method public void setTrackDrawable(android.graphics.drawable.Drawable);
method public void setTrackResource(int);
+ method public void setTrackTintList(android.content.res.ColorStateList);
+ method public void setTrackTintMode(android.graphics.PorterDuff.Mode);
}
public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index 62932fd..9f138e4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1392,6 +1392,8 @@
field public static final int topRightRadius = 16843178; // 0x10101aa
field public static final int touchscreenBlocksFocus = 16843919; // 0x101048f
field public static final int track = 16843631; // 0x101036f
+ field public static final int trackTint = 16843993; // 0x10104d9
+ field public static final int trackTintMode = 16843994; // 0x10104da
field public static final int transcriptMode = 16843008; // 0x1010100
field public static final int transformPivotX = 16843552; // 0x1010320
field public static final int transformPivotY = 16843553; // 0x1010321
@@ -4857,6 +4859,37 @@
method public android.app.Notification.Builder setWhen(long);
}
+ public static final class Notification.CarExtender implements android.app.Notification.Extender {
+ ctor public Notification.CarExtender();
+ ctor public Notification.CarExtender(android.app.Notification);
+ method public android.app.Notification.Builder extend(android.app.Notification.Builder);
+ method public int getColor();
+ method public android.graphics.Bitmap getLargeIcon();
+ method public android.app.Notification.CarExtender.UnreadConversation getUnreadConversation();
+ method public android.app.Notification.CarExtender setColor(int);
+ method public android.app.Notification.CarExtender setLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.CarExtender setUnreadConversation(android.app.Notification.CarExtender.UnreadConversation);
+ }
+
+ public static class Notification.CarExtender.Builder {
+ ctor public Notification.CarExtender.Builder(java.lang.String);
+ method public android.app.Notification.CarExtender.Builder addMessage(java.lang.String);
+ method public android.app.Notification.CarExtender.UnreadConversation build();
+ method public android.app.Notification.CarExtender.Builder setLatestTimestamp(long);
+ method public android.app.Notification.CarExtender.Builder setReadPendingIntent(android.app.PendingIntent);
+ method public android.app.Notification.CarExtender.Builder setReplyAction(android.app.PendingIntent, android.app.RemoteInput);
+ }
+
+ public static class Notification.CarExtender.UnreadConversation {
+ method public long getLatestTimestamp();
+ method public java.lang.String[] getMessages();
+ method public java.lang.String getParticipant();
+ method public java.lang.String[] getParticipants();
+ method public android.app.PendingIntent getReadPendingIntent();
+ method public android.app.RemoteInput getRemoteInput();
+ method public android.app.PendingIntent getReplyPendingIntent();
+ }
+
public static abstract interface Notification.Extender {
method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
}
@@ -5554,6 +5587,7 @@
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
@@ -12952,6 +12986,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> LENS_INFO_MINIMUM_FOCUS_DISTANCE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_RAW;
@@ -13169,13 +13204,16 @@
field public static final int LENS_STATE_STATIONARY = 0; // 0x0
field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
+ field public static final int NOISE_REDUCTION_MODE_MINIMAL = 3; // 0x3
field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
@@ -13281,6 +13319,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Float> LENS_FOCUS_DISTANCE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> LENS_OPTICAL_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> NOISE_REDUCTION_MODE;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
field public static final android.hardware.camera2.CaptureRequest.Key<android.graphics.Rect> SCALER_CROP_REGION;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Long> SENSOR_FRAME_DURATION;
@@ -13358,6 +13397,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> LENS_OPTICAL_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> LENS_STATE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> NOISE_REDUCTION_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Byte> REQUEST_PIPELINE_DEPTH;
field public static final android.hardware.camera2.CaptureResult.Key<android.graphics.Rect> SCALER_CROP_REGION;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
@@ -15107,6 +15147,7 @@
method public boolean isMicrophoneMute();
method public boolean isMusicActive();
method public boolean isSpeakerphoneOn();
+ method public boolean isStreamMute(int);
method public boolean isVolumeFixed();
method public deprecated boolean isWiredHeadsetOn();
method public void loadSoundEffects();
@@ -15128,8 +15169,8 @@
method public void setRingerMode(int);
method public deprecated void setRouting(int, int, int);
method public void setSpeakerphoneOn(boolean);
- method public void setStreamMute(int, boolean);
- method public void setStreamSolo(int, boolean);
+ method public deprecated void setStreamMute(int, boolean);
+ method public deprecated void setStreamSolo(int, boolean);
method public void setStreamVolume(int, int, int);
method public deprecated void setVibrateSetting(int, int);
method public deprecated void setWiredHeadsetOn(boolean);
@@ -15148,8 +15189,11 @@
field public static final deprecated java.lang.String ACTION_SCO_AUDIO_STATE_CHANGED = "android.media.SCO_AUDIO_STATE_CHANGED";
field public static final java.lang.String ACTION_SCO_AUDIO_STATE_UPDATED = "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
field public static final int ADJUST_LOWER = -1; // 0xffffffff
+ field public static final int ADJUST_MUTE = -100; // 0xffffff9c
field public static final int ADJUST_RAISE = 1; // 0x1
field public static final int ADJUST_SAME = 0; // 0x0
+ field public static final int ADJUST_TOGGLE_MUTE = 101; // 0x65
+ field public static final int ADJUST_UNMUTE = 100; // 0x64
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
@@ -26206,6 +26250,7 @@
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
+ field public static final java.lang.String QUERY_PARAMETER_VCARD_NO_PHOTO = "no_photo";
}
public static final class ContactsContract.Contacts.AggregationSuggestions implements android.provider.BaseColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns {
@@ -30398,6 +30443,7 @@
method public final int getState();
method public final android.telecom.StatusHints getStatusHints();
method public final boolean isRingbackRequested();
+ method protected void notifyConferenceStarted();
method public void onAbort();
method public void onAnswer();
method public void onAudioStateChanged(android.telecom.AudioState);
@@ -30423,6 +30469,7 @@
method public final void setDisconnected(android.telecom.DisconnectCause);
method public final void setInitialized();
method public final void setInitializing();
+ method public final void setNextPostDialChar(char);
method public final void setOnHold();
method public final void setPostDialWait(java.lang.String);
method public final void setRingbackRequested(boolean);
@@ -40911,6 +40958,8 @@
method public void setClippingEnabled(boolean);
method public void setContentView(android.view.View);
method public void setElevation(float);
+ method public void setEnterTransition(android.transition.Transition);
+ method public void setExitTransition(android.transition.Transition);
method public void setFocusable(boolean);
method public void setHeight(int);
method public void setIgnoreCheekPress();
@@ -41512,7 +41561,11 @@
method public java.lang.CharSequence getTextOn();
method public android.graphics.drawable.Drawable getThumbDrawable();
method public int getThumbTextPadding();
+ method public android.content.res.ColorStateList getThumbTintList();
+ method public android.graphics.PorterDuff.Mode getThumbTintMode();
method public android.graphics.drawable.Drawable getTrackDrawable();
+ method public android.content.res.ColorStateList getTrackTintList();
+ method public android.graphics.PorterDuff.Mode getTrackTintMode();
method public void onMeasure(int, int);
method public void setShowText(boolean);
method public void setSplitTrack(boolean);
@@ -41526,8 +41579,12 @@
method public void setThumbDrawable(android.graphics.drawable.Drawable);
method public void setThumbResource(int);
method public void setThumbTextPadding(int);
+ method public void setThumbTintList(android.content.res.ColorStateList);
+ method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
method public void setTrackDrawable(android.graphics.drawable.Drawable);
method public void setTrackResource(int);
+ method public void setTrackTintList(android.content.res.ColorStateList);
+ method public void setTrackTintMode(android.graphics.PorterDuff.Mode);
}
public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 2a0ed90..fb3d423 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1735,6 +1735,22 @@
int right = Integer.valueOf(rightStr);
String bottomStr = nextArgRequired();
int bottom = Integer.valueOf(bottomStr);
+ if (left < 0) {
+ System.err.println("Error: bad left arg: " + leftStr);
+ return;
+ }
+ if (top < 0) {
+ System.err.println("Error: bad top arg: " + topStr);
+ return;
+ }
+ if (right <= 0) {
+ System.err.println("Error: bad right arg: " + rightStr);
+ return;
+ }
+ if (bottom <= 0) {
+ System.err.println("Error: bad bottom arg: " + bottomStr);
+ return;
+ }
try {
mAm.resizeStack(stackId, new Rect(left, top, right, bottom));
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 379fe11..97b9f4c 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -766,6 +766,14 @@
return true;
}
+ case GET_FOCUSED_STACK_ID_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int focusedStackId = getFocusedStackId();
+ reply.writeNoException();
+ reply.writeInt(focusedStackId);
+ return true;
+ }
+
case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -3290,6 +3298,18 @@
reply.recycle();
}
@Override
+ public int getFocusedStackId() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(GET_FOCUSED_STACK_ID_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int focusedStackId = reply.readInt();
+ data.recycle();
+ reply.recycle();
+ return focusedStackId;
+ }
+ @Override
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index 52884f7..ff1175f 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -32,6 +32,7 @@
void checkEmbeddedAllowed(in Intent intent);
void checkEmbeddedAllowedIntentSender(in IIntentSender intentSender);
int getDisplayId();
+ int getStackId();
boolean injectEvent(in InputEvent event);
void release();
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index f152c6f..efc4543 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -139,6 +139,7 @@
public StackInfo getStackInfo(int stackId) throws RemoteException;
public boolean isInHomeStack(int taskId) throws RemoteException;
public void setFocusedStack(int stackId) throws RemoteException;
+ public int getFocusedStackId() throws RemoteException;
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
@@ -800,4 +801,5 @@
// Start of M transactions
int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+280;
int CREATE_STACK_ON_DISPLAY = IBinder.FIRST_CALL_TRANSACTION+281;
+ int GET_FOCUSED_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+282;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 860b9cc..87e744c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5065,6 +5065,403 @@
}
/**
+ * <p>Helper class to add Android Auto extensions to notifications. To create a notification
+ * with car extensions:
+ *
+ * <ol>
+ * <li>Create an {@link Notification.Builder}, setting any desired
+ * properties.
+ * <li>Create a {@link CarExtender}.
+ * <li>Set car-specific properties using the {@code add} and {@code set} methods of
+ * {@link CarExtender}.
+ * <li>Call {@link Notification.Builder#extend(Notification.Extender)}
+ * to apply the extensions to a notification.
+ * </ol>
+ *
+ * <pre class="prettyprint">
+ * Notification notification = new Notification.Builder(context)
+ * ...
+ * .extend(new CarExtender()
+ * .set*(...))
+ * .build();
+ * </pre>
+ *
+ * <p>Car extensions can be accessed on an existing notification by using the
+ * {@code CarExtender(Notification)} constructor, and then using the {@code get} methods
+ * to access values.
+ */
+ public static final class CarExtender implements Extender {
+ private static final String TAG = "CarExtender";
+
+ private static final String EXTRA_CAR_EXTENDER = "android.car.EXTENSIONS";
+ private static final String EXTRA_LARGE_ICON = "large_icon";
+ private static final String EXTRA_CONVERSATION = "car_conversation";
+ private static final String EXTRA_COLOR = "app_color";
+
+ private Bitmap mLargeIcon;
+ private UnreadConversation mUnreadConversation;
+ private int mColor = Notification.COLOR_DEFAULT;
+
+ /**
+ * Create a {@link CarExtender} with default options.
+ */
+ public CarExtender() {
+ }
+
+ /**
+ * Create a {@link CarExtender} from the CarExtender options of an existing Notification.
+ *
+ * @param notif The notification from which to copy options.
+ */
+ public CarExtender(Notification notif) {
+ Bundle carBundle = notif.extras == null ?
+ null : notif.extras.getBundle(EXTRA_CAR_EXTENDER);
+ if (carBundle != null) {
+ mLargeIcon = carBundle.getParcelable(EXTRA_LARGE_ICON);
+ mColor = carBundle.getInt(EXTRA_COLOR, Notification.COLOR_DEFAULT);
+
+ Bundle b = carBundle.getBundle(EXTRA_CONVERSATION);
+ mUnreadConversation = UnreadConversation.getUnreadConversationFromBundle(b);
+ }
+ }
+
+ /**
+ * Apply car extensions to a notification that is being built. This is typically called by
+ * the {@link Notification.Builder#extend(Notification.Extender)}
+ * method of {@link Notification.Builder}.
+ */
+ @Override
+ public Notification.Builder extend(Notification.Builder builder) {
+ Bundle carExtensions = new Bundle();
+
+ if (mLargeIcon != null) {
+ carExtensions.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
+ }
+ if (mColor != Notification.COLOR_DEFAULT) {
+ carExtensions.putInt(EXTRA_COLOR, mColor);
+ }
+
+ if (mUnreadConversation != null) {
+ Bundle b = mUnreadConversation.getBundleForUnreadConversation();
+ carExtensions.putBundle(EXTRA_CONVERSATION, b);
+ }
+
+ builder.getExtras().putBundle(EXTRA_CAR_EXTENDER, carExtensions);
+ return builder;
+ }
+
+ /**
+ * Sets the accent color to use when Android Auto presents the notification.
+ *
+ * Android Auto uses the color set with {@link Notification.Builder#setColor(int)}
+ * to accent the displayed notification. However, not all colors are acceptable in an
+ * automotive setting. This method can be used to override the color provided in the
+ * notification in such a situation.
+ */
+ public CarExtender setColor(int color) {
+ mColor = color;
+ return this;
+ }
+
+ /**
+ * Gets the accent color.
+ *
+ * @see setColor
+ */
+ public int getColor() {
+ return mColor;
+ }
+
+ /**
+ * Sets the large icon of the car notification.
+ *
+ * If no large icon is set in the extender, Android Auto will display the icon
+ * specified by {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap)}
+ *
+ * @param largeIcon The large icon to use in the car notification.
+ * @return This object for method chaining.
+ */
+ public CarExtender setLargeIcon(Bitmap largeIcon) {
+ mLargeIcon = largeIcon;
+ return this;
+ }
+
+ /**
+ * Gets the large icon used in this car notification, or null if no icon has been set.
+ *
+ * @return The large icon for the car notification.
+ * @see CarExtender#setLargeIcon
+ */
+ public Bitmap getLargeIcon() {
+ return mLargeIcon;
+ }
+
+ /**
+ * Sets the unread conversation in a message notification.
+ *
+ * @param unreadConversation The unread part of the conversation this notification conveys.
+ * @return This object for method chaining.
+ */
+ public CarExtender setUnreadConversation(UnreadConversation unreadConversation) {
+ mUnreadConversation = unreadConversation;
+ return this;
+ }
+
+ /**
+ * Returns the unread conversation conveyed by this notification.
+ * @see #setUnreadConversation(UnreadConversation)
+ */
+ public UnreadConversation getUnreadConversation() {
+ return mUnreadConversation;
+ }
+
+ /**
+ * A class which holds the unread messages from a conversation.
+ */
+ public static class UnreadConversation {
+ private static final String KEY_AUTHOR = "author";
+ private static final String KEY_TEXT = "text";
+ private static final String KEY_MESSAGES = "messages";
+ private static final String KEY_REMOTE_INPUT = "remote_input";
+ private static final String KEY_ON_REPLY = "on_reply";
+ private static final String KEY_ON_READ = "on_read";
+ private static final String KEY_PARTICIPANTS = "participants";
+ private static final String KEY_TIMESTAMP = "timestamp";
+
+ private final String[] mMessages;
+ private final RemoteInput mRemoteInput;
+ private final PendingIntent mReplyPendingIntent;
+ private final PendingIntent mReadPendingIntent;
+ private final String[] mParticipants;
+ private final long mLatestTimestamp;
+
+ UnreadConversation(String[] messages, RemoteInput remoteInput,
+ PendingIntent replyPendingIntent, PendingIntent readPendingIntent,
+ String[] participants, long latestTimestamp) {
+ mMessages = messages;
+ mRemoteInput = remoteInput;
+ mReadPendingIntent = readPendingIntent;
+ mReplyPendingIntent = replyPendingIntent;
+ mParticipants = participants;
+ mLatestTimestamp = latestTimestamp;
+ }
+
+ /**
+ * Gets the list of messages conveyed by this notification.
+ */
+ public String[] getMessages() {
+ return mMessages;
+ }
+
+ /**
+ * Gets the remote input that will be used to convey the response to a message list, or
+ * null if no such remote input exists.
+ */
+ public RemoteInput getRemoteInput() {
+ return mRemoteInput;
+ }
+
+ /**
+ * Gets the pending intent that will be triggered when the user replies to this
+ * notification.
+ */
+ public PendingIntent getReplyPendingIntent() {
+ return mReplyPendingIntent;
+ }
+
+ /**
+ * Gets the pending intent that Android Auto will send after it reads aloud all messages
+ * in this object's message list.
+ */
+ public PendingIntent getReadPendingIntent() {
+ return mReadPendingIntent;
+ }
+
+ /**
+ * Gets the participants in the conversation.
+ */
+ public String[] getParticipants() {
+ return mParticipants;
+ }
+
+ /**
+ * Gets the firs participant in the conversation.
+ */
+ public String getParticipant() {
+ return mParticipants.length > 0 ? mParticipants[0] : null;
+ }
+
+ /**
+ * Gets the timestamp of the conversation.
+ */
+ public long getLatestTimestamp() {
+ return mLatestTimestamp;
+ }
+
+ Bundle getBundleForUnreadConversation() {
+ Bundle b = new Bundle();
+ String author = null;
+ if (mParticipants != null && mParticipants.length > 1) {
+ author = mParticipants[0];
+ }
+ Parcelable[] messages = new Parcelable[mMessages.length];
+ for (int i = 0; i < messages.length; i++) {
+ Bundle m = new Bundle();
+ m.putString(KEY_TEXT, mMessages[i]);
+ m.putString(KEY_AUTHOR, author);
+ messages[i] = m;
+ }
+ b.putParcelableArray(KEY_MESSAGES, messages);
+ if (mRemoteInput != null) {
+ b.putParcelable(KEY_REMOTE_INPUT, mRemoteInput);
+ }
+ b.putParcelable(KEY_ON_REPLY, mReplyPendingIntent);
+ b.putParcelable(KEY_ON_READ, mReadPendingIntent);
+ b.putStringArray(KEY_PARTICIPANTS, mParticipants);
+ b.putLong(KEY_TIMESTAMP, mLatestTimestamp);
+ return b;
+ }
+
+ static UnreadConversation getUnreadConversationFromBundle(Bundle b) {
+ if (b == null) {
+ return null;
+ }
+ Parcelable[] parcelableMessages = b.getParcelableArray(KEY_MESSAGES);
+ String[] messages = null;
+ if (parcelableMessages != null) {
+ String[] tmp = new String[parcelableMessages.length];
+ boolean success = true;
+ for (int i = 0; i < tmp.length; i++) {
+ if (!(parcelableMessages[i] instanceof Bundle)) {
+ success = false;
+ break;
+ }
+ tmp[i] = ((Bundle) parcelableMessages[i]).getString(KEY_TEXT);
+ if (tmp[i] == null) {
+ success = false;
+ break;
+ }
+ }
+ if (success) {
+ messages = tmp;
+ } else {
+ return null;
+ }
+ }
+
+ PendingIntent onRead = b.getParcelable(KEY_ON_READ);
+ PendingIntent onReply = b.getParcelable(KEY_ON_REPLY);
+
+ RemoteInput remoteInput = b.getParcelable(KEY_REMOTE_INPUT);
+
+ String[] participants = b.getStringArray(KEY_PARTICIPANTS);
+ if (participants == null || participants.length != 1) {
+ return null;
+ }
+
+ return new UnreadConversation(messages,
+ remoteInput,
+ onReply,
+ onRead,
+ participants, b.getLong(KEY_TIMESTAMP));
+ }
+ };
+
+ /**
+ * Builder class for {@link CarExtender.UnreadConversation} objects.
+ */
+ public static class Builder {
+ private final List<String> mMessages = new ArrayList<String>();
+ private final String mParticipant;
+ private RemoteInput mRemoteInput;
+ private PendingIntent mReadPendingIntent;
+ private PendingIntent mReplyPendingIntent;
+ private long mLatestTimestamp;
+
+ /**
+ * Constructs a new builder for {@link CarExtender.UnreadConversation}.
+ *
+ * @param name The name of the other participant in the conversation.
+ */
+ public Builder(String name) {
+ mParticipant = name;
+ }
+
+ /**
+ * Appends a new unread message to the list of messages for this conversation.
+ *
+ * The messages should be added from oldest to newest.
+ *
+ * @param message The text of the new unread message.
+ * @return This object for method chaining.
+ */
+ public Builder addMessage(String message) {
+ mMessages.add(message);
+ return this;
+ }
+
+ /**
+ * Sets the pending intent and remote input which will convey the reply to this
+ * notification.
+ *
+ * @param pendingIntent The pending intent which will be triggered on a reply.
+ * @param remoteInput The remote input parcelable which will carry the reply.
+ * @return This object for method chaining.
+ *
+ * @see CarExtender.UnreadConversation#getRemoteInput
+ * @see CarExtender.UnreadConversation#getReplyPendingIntent
+ */
+ public Builder setReplyAction(
+ PendingIntent pendingIntent, RemoteInput remoteInput) {
+ mRemoteInput = remoteInput;
+ mReplyPendingIntent = pendingIntent;
+
+ return this;
+ }
+
+ /**
+ * Sets the pending intent that will be sent once the messages in this notification
+ * are read.
+ *
+ * @param pendingIntent The pending intent to use.
+ * @return This object for method chaining.
+ */
+ public Builder setReadPendingIntent(PendingIntent pendingIntent) {
+ mReadPendingIntent = pendingIntent;
+ return this;
+ }
+
+ /**
+ * Sets the timestamp of the most recent message in an unread conversation.
+ *
+ * If a messaging notification has been posted by your application and has not
+ * yet been cancelled, posting a later notification with the same id and tag
+ * but without a newer timestamp may result in Android Auto not displaying a
+ * heads up notification for the later notification.
+ *
+ * @param timestamp The timestamp of the most recent message in the conversation.
+ * @return This object for method chaining.
+ */
+ public Builder setLatestTimestamp(long timestamp) {
+ mLatestTimestamp = timestamp;
+ return this;
+ }
+
+ /**
+ * Builds a new unread conversation object.
+ *
+ * @return The new unread conversation object.
+ */
+ public UnreadConversation build() {
+ String[] messages = mMessages.toArray(new String[mMessages.size()]);
+ String[] participants = { mParticipant };
+ return new UnreadConversation(messages, mRemoteInput, mReplyPendingIntent,
+ mReadPendingIntent, participants, mLatestTimestamp);
+ }
+ }
+ }
+
+ /**
* Get an array of Notification objects from a parcelable array bundle field.
* Update the bundle to have a typed array so fetches in the future don't need
* to do an array copy.
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 4427ce1..e617553 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.Nullable;
import android.content.SharedPreferences;
import android.os.FileUtils;
import android.os.Looper;
@@ -217,7 +218,8 @@
}
}
- public String getString(String key, String defValue) {
+ @Nullable
+ public String getString(String key, @Nullable String defValue) {
synchronized (this) {
awaitLoadedLocked();
String v = (String)mMap.get(key);
@@ -225,7 +227,8 @@
}
}
- public Set<String> getStringSet(String key, Set<String> defValues) {
+ @Nullable
+ public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
synchronized (this) {
awaitLoadedLocked();
Set<String> v = (Set<String>) mMap.get(key);
@@ -303,13 +306,13 @@
private final Map<String, Object> mModified = Maps.newHashMap();
private boolean mClear = false;
- public Editor putString(String key, String value) {
+ public Editor putString(String key, @Nullable String value) {
synchronized (this) {
mModified.put(key, value);
return this;
}
}
- public Editor putStringSet(String key, Set<String> values) {
+ public Editor putStringSet(String key, @Nullable Set<String> values) {
synchronized (this) {
mModified.put(key,
(values == null) ? null : new HashSet<String>(values));
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 55c3960..ecf25fc 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -332,6 +332,16 @@
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
/**
+ * A boolean extra indicating whether device encryption is required as part of Device Owner
+ * provisioning.
+ *
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
+ */
+ public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION =
+ "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
+
+ /**
* This MIME type is used for starting the Device Owner provisioning.
*
* <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -361,7 +371,8 @@
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
+ * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li></ul>
*
* <p> When device owner provisioning has completed, an intent of the type
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
@@ -694,7 +705,7 @@
public void setPasswordQuality(ComponentName admin, int quality) {
if (mService != null) {
try {
- mService.setPasswordQuality(admin, quality, UserHandle.myUserId());
+ mService.setPasswordQuality(admin, quality);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -747,7 +758,7 @@
public void setPasswordMinimumLength(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumLength(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumLength(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -801,7 +812,7 @@
public void setPasswordMinimumUpperCase(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumUpperCase(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumUpperCase(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -862,7 +873,7 @@
public void setPasswordMinimumLowerCase(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumLowerCase(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumLowerCase(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -922,7 +933,7 @@
public void setPasswordMinimumLetters(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumLetters(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumLetters(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -980,7 +991,7 @@
public void setPasswordMinimumNumeric(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumNumeric(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumNumeric(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1039,7 +1050,7 @@
public void setPasswordMinimumSymbols(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumSymbols(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumSymbols(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1097,7 +1108,7 @@
public void setPasswordMinimumNonLetter(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordMinimumNonLetter(admin, length, UserHandle.myUserId());
+ mService.setPasswordMinimumNonLetter(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1157,7 +1168,7 @@
public void setPasswordHistoryLength(ComponentName admin, int length) {
if (mService != null) {
try {
- mService.setPasswordHistoryLength(admin, length, UserHandle.myUserId());
+ mService.setPasswordHistoryLength(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1189,7 +1200,7 @@
public void setPasswordExpirationTimeout(ComponentName admin, long timeout) {
if (mService != null) {
try {
- mService.setPasswordExpirationTimeout(admin, timeout, UserHandle.myUserId());
+ mService.setPasswordExpirationTimeout(admin, timeout);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1334,7 +1345,7 @@
public void setMaximumFailedPasswordsForWipe(ComponentName admin, int num) {
if (mService != null) {
try {
- mService.setMaximumFailedPasswordsForWipe(admin, num, UserHandle.myUserId());
+ mService.setMaximumFailedPasswordsForWipe(admin, num);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1418,7 +1429,7 @@
public boolean resetPassword(String password, int flags) {
if (mService != null) {
try {
- return mService.resetPassword(password, flags, UserHandle.myUserId());
+ return mService.resetPassword(password, flags);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1442,7 +1453,7 @@
public void setMaximumTimeToLock(ComponentName admin, long timeMs) {
if (mService != null) {
try {
- mService.setMaximumTimeToLock(admin, timeMs, UserHandle.myUserId());
+ mService.setMaximumTimeToLock(admin, timeMs);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1592,7 +1603,7 @@
!= android.net.Proxy.PROXY_VALID)
throw new IllegalArgumentException();
}
- return mService.setGlobalProxy(admin, hostSpec, exclSpec, UserHandle.myUserId());
+ return mService.setGlobalProxy(admin, hostSpec, exclSpec);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1758,7 +1769,7 @@
public int setStorageEncryption(ComponentName admin, boolean encrypt) {
if (mService != null) {
try {
- return mService.setStorageEncryption(admin, encrypt, UserHandle.myUserId());
+ return mService.setStorageEncryption(admin, encrypt);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1977,7 +1988,7 @@
public void setCameraDisabled(ComponentName admin, boolean disabled) {
if (mService != null) {
try {
- mService.setCameraDisabled(admin, disabled, UserHandle.myUserId());
+ mService.setCameraDisabled(admin, disabled);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2021,7 +2032,7 @@
public void setScreenCaptureDisabled(ComponentName admin, boolean disabled) {
if (mService != null) {
try {
- mService.setScreenCaptureDisabled(admin, UserHandle.myUserId(), disabled);
+ mService.setScreenCaptureDisabled(admin, disabled);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2065,7 +2076,7 @@
public void setAutoTimeRequired(ComponentName admin, boolean required) {
if (mService != null) {
try {
- mService.setAutoTimeRequired(admin, UserHandle.myUserId(), required);
+ mService.setAutoTimeRequired(admin, required);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2106,7 +2117,7 @@
public void setKeyguardDisabledFeatures(ComponentName admin, int which) {
if (mService != null) {
try {
- mService.setKeyguardDisabledFeatures(admin, which, UserHandle.myUserId());
+ mService.setKeyguardDisabledFeatures(admin, which);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2688,8 +2699,7 @@
PersistableBundle configuration) {
if (mService != null) {
try {
- mService.setTrustAgentConfiguration(admin, target, configuration,
- UserHandle.myUserId());
+ mService.setTrustAgentConfiguration(admin, target, configuration);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 0ca60c0..67bca4e 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -32,34 +32,34 @@
* {@hide}
*/
interface IDevicePolicyManager {
- void setPasswordQuality(in ComponentName who, int quality, int userHandle);
+ void setPasswordQuality(in ComponentName who, int quality);
int getPasswordQuality(in ComponentName who, int userHandle);
- void setPasswordMinimumLength(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumLength(in ComponentName who, int length);
int getPasswordMinimumLength(in ComponentName who, int userHandle);
- void setPasswordMinimumUpperCase(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumUpperCase(in ComponentName who, int length);
int getPasswordMinimumUpperCase(in ComponentName who, int userHandle);
- void setPasswordMinimumLowerCase(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumLowerCase(in ComponentName who, int length);
int getPasswordMinimumLowerCase(in ComponentName who, int userHandle);
- void setPasswordMinimumLetters(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumLetters(in ComponentName who, int length);
int getPasswordMinimumLetters(in ComponentName who, int userHandle);
- void setPasswordMinimumNumeric(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumNumeric(in ComponentName who, int length);
int getPasswordMinimumNumeric(in ComponentName who, int userHandle);
- void setPasswordMinimumSymbols(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumSymbols(in ComponentName who, int length);
int getPasswordMinimumSymbols(in ComponentName who, int userHandle);
- void setPasswordMinimumNonLetter(in ComponentName who, int length, int userHandle);
+ void setPasswordMinimumNonLetter(in ComponentName who, int length);
int getPasswordMinimumNonLetter(in ComponentName who, int userHandle);
- void setPasswordHistoryLength(in ComponentName who, int length, int userHandle);
+ void setPasswordHistoryLength(in ComponentName who, int length);
int getPasswordHistoryLength(in ComponentName who, int userHandle);
- void setPasswordExpirationTimeout(in ComponentName who, long expiration, int userHandle);
+ void setPasswordExpirationTimeout(in ComponentName who, long expiration);
long getPasswordExpirationTimeout(in ComponentName who, int userHandle);
long getPasswordExpiration(in ComponentName who, int userHandle);
@@ -68,33 +68,33 @@
int getCurrentFailedPasswordAttempts(int userHandle);
int getProfileWithMinimumFailedPasswordsForWipe(int userHandle);
- void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, int userHandle);
+ void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num);
int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle);
- boolean resetPassword(String password, int flags, int userHandle);
+ boolean resetPassword(String password, int flags);
- void setMaximumTimeToLock(in ComponentName who, long timeMs, int userHandle);
+ void setMaximumTimeToLock(in ComponentName who, long timeMs);
long getMaximumTimeToLock(in ComponentName who, int userHandle);
void lockNow();
void wipeData(int flags, int userHandle);
- ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList, int userHandle);
+ ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList);
ComponentName getGlobalProxyAdmin(int userHandle);
void setRecommendedGlobalProxy(in ComponentName admin, in ProxyInfo proxyInfo);
- int setStorageEncryption(in ComponentName who, boolean encrypt, int userHandle);
+ int setStorageEncryption(in ComponentName who, boolean encrypt);
boolean getStorageEncryption(in ComponentName who, int userHandle);
int getStorageEncryptionStatus(int userHandle);
- void setCameraDisabled(in ComponentName who, boolean disabled, int userHandle);
+ void setCameraDisabled(in ComponentName who, boolean disabled);
boolean getCameraDisabled(in ComponentName who, int userHandle);
- void setScreenCaptureDisabled(in ComponentName who, int userHandle, boolean disabled);
+ void setScreenCaptureDisabled(in ComponentName who, boolean disabled);
boolean getScreenCaptureDisabled(in ComponentName who, int userHandle);
- void setKeyguardDisabledFeatures(in ComponentName who, int which, int userHandle);
+ void setKeyguardDisabledFeatures(in ComponentName who, int which);
int getKeyguardDisabledFeatures(in ComponentName who, int userHandle);
void setActiveAdmin(in ComponentName policyReceiver, boolean refreshing, int userHandle);
@@ -186,7 +186,7 @@
boolean getCrossProfileCallerIdDisabledForUser(int userId);
void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent,
- in PersistableBundle args, int userId);
+ in PersistableBundle args);
List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin,
in ComponentName agent, int userId);
@@ -194,7 +194,7 @@
boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
List<String> getCrossProfileWidgetProviders(in ComponentName admin);
- void setAutoTimeRequired(in ComponentName who, int userHandle, boolean required);
+ void setAutoTimeRequired(in ComponentName who, boolean required);
boolean getAutoTimeRequired();
boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 0450150..767f59e 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.media.AudioManager;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -415,9 +416,16 @@
}
/**
- * Tells remote device to adjust volume. Only if absolute volume is supported.
+ * Tells remote device to adjust volume. Only if absolute volume is
+ * supported. Uses the following values:
+ * <ul>
+ * <li>{@link AudioManager#ADJUST_LOWER}</li>
+ * <li>{@link AudioManager#ADJUST_RAISE}</li>
+ * <li>{@link AudioManager#ADJUST_MUTE}</li>
+ * <li>{@link AudioManager#ADJUST_UNMUTE}</li>
+ * </ul>
*
- * @param direction 1 to increase volume, or -1 to decrease volume
+ * @param direction One of the supported adjust values.
* @hide
*/
public void adjustAvrcpAbsoluteVolume(int direction) {
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 46c9234..cd32dae 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -16,6 +16,8 @@
package android.content;
+import android.annotation.Nullable;
+
import java.util.Map;
import java.util.Set;
@@ -78,7 +80,7 @@
* @return Returns a reference to the same Editor object, so you can
* chain put calls together.
*/
- Editor putString(String key, String value);
+ Editor putString(String key, @Nullable String value);
/**
* Set a set of String values in the preferences editor, to be written
@@ -91,7 +93,7 @@
* @return Returns a reference to the same Editor object, so you can
* chain put calls together.
*/
- Editor putStringSet(String key, Set<String> values);
+ Editor putStringSet(String key, @Nullable Set<String> values);
/**
* Set an int value in the preferences editor, to be written back once
@@ -254,7 +256,8 @@
*
* @throws ClassCastException
*/
- String getString(String key, String defValue);
+ @Nullable
+ String getString(String key, @Nullable String defValue);
/**
* Retrieve a set of String values from the preferences.
@@ -272,7 +275,8 @@
*
* @throws ClassCastException
*/
- Set<String> getStringSet(String key, Set<String> defValues);
+ @Nullable
+ Set<String> getStringSet(String key, @Nullable Set<String> defValues);
/**
* Retrieve an int value from the preferences.
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index eace1c4..5310071 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1069,8 +1069,11 @@
* android.scaler.availableInputOutputFormatsMap. When using an
* input stream, there must be at least one output stream
* configured to to receive the reprocessed images.</p>
+ * <p>When an input stream and some output streams are used in a reprocessing request,
+ * only the input buffer will be used to produce these output stream buffers, and a
+ * new sensor image will not be captured.</p>
* <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
- * stream image format will be RAW_OPAQUE, the associated output stream image format
+ * stream image format will be OPAQUE, the associated output stream image format
* should be JPEG.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>0 or 1.</p>
@@ -1080,8 +1083,8 @@
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
- * @hide
*/
+ @PublicKey
public static final Key<Integer> REQUEST_MAX_NUM_INPUT_STREAMS =
new Key<Integer>("android.request.maxNumInputStreams", int.class);
@@ -1157,8 +1160,10 @@
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING MANUAL_POST_PROCESSING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}</li>
+ * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS READ_SENSOR_SETTINGS}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}</li>
+ * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}</li>
* </ul></p>
* <p>This key is available on all devices.</p>
*
@@ -1167,8 +1172,10 @@
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_RAW
+ * @see #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS
* @see #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE
+ * @see #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING
*/
@PublicKey
public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
@@ -1345,10 +1352,10 @@
* <p>The mapping of image formats that are supported by this
* camera device for input streams, to their corresponding output formats.</p>
* <p>All camera devices with at least 1
- * android.request.maxNumInputStreams will have at least one
+ * {@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} will have at least one
* available input format.</p>
* <p>The camera device will support the following map of formats,
- * if its dependent capability is supported:</p>
+ * if its dependent capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}) is supported:</p>
* <table>
* <thead>
* <tr>
@@ -1359,45 +1366,42 @@
* </thead>
* <tbody>
* <tr>
- * <td align="left">RAW_OPAQUE</td>
+ * <td align="left">OPAQUE</td>
* <td align="left">JPEG</td>
- * <td align="left">ZSL</td>
+ * <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">RAW_OPAQUE</td>
+ * <td align="left">OPAQUE</td>
* <td align="left">YUV_420_888</td>
- * <td align="left">ZSL</td>
+ * <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">RAW_OPAQUE</td>
- * <td align="left">RAW16</td>
- * <td align="left">RAW</td>
- * </tr>
- * <tr>
- * <td align="left">RAW16</td>
* <td align="left">YUV_420_888</td>
- * <td align="left">RAW</td>
- * </tr>
- * <tr>
- * <td align="left">RAW16</td>
* <td align="left">JPEG</td>
- * <td align="left">RAW</td>
+ * <td align="left">YUV_REPROCESSING</td>
+ * </tr>
+ * <tr>
+ * <td align="left">YUV_420_888</td>
+ * <td align="left">YUV_420_888</td>
+ * <td align="left">YUV_REPROCESSING</td>
* </tr>
* </tbody>
* </table>
- * <p>For ZSL-capable camera devices, using the RAW_OPAQUE format
+ * <p>OPAQUE refers to a device-internal format that is not directly application-visible.
+ * An OPAQUE input or output surface can be acquired by
+ * OpaqueImageRingBufferQueue#getInputSurface() or
+ * OpaqueImageRingBufferQueue#getOutputSurface().
+ * For a OPAQUE_REPROCESSING-capable camera device, using the OPAQUE format
* as either input or output will never hurt maximum frame rate (i.e.
- * StreamConfigurationMap#getOutputStallDuration(int,Size)
- * for a <code>format =</code> RAW_OPAQUE is always 0).</p>
+ * StreamConfigurationMap#getOutputStallDuration(klass,Size) is always 0),
+ * where klass is android.media.OpaqueImageRingBufferQueue.class.</p>
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
* <p>TODO: typedef to ReprocessFormatMap</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
- * <p><b>Full capability</b> -
- * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
- * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
- * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @hide
*/
public static final Key<int[]> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index f6df302..af7d365 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -439,23 +439,40 @@
public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3;
/**
- * <p>The camera device supports the Zero Shutter Lag use case.</p>
+ * <p>The camera device supports the Zero Shutter Lag reprocessing use case.</p>
* <ul>
- * <li>At least one input stream can be used.</li>
- * <li>RAW_OPAQUE is supported as an output/input format</li>
- * <li>Using RAW_OPAQUE does not cause a frame rate drop
+ * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
+ * <li>OPAQUE is supported as an output/input format, that is,
+ * StreamConfigurationMap#getOutputSizes(klass) and
+ * StreamConfigurationMap#getInputSizes(klass) return non empty Size[] and have common
+ * sizes, where klass is android.media.OpaqueImageRingBufferQueue.class. See
+ * android.scaler.availableInputOutputFormatsMap for detailed information about
+ * OPAQUE format.</li>
+ * <li>android.scaler.availableInputOutputFormatsMap has the required map entries.</li>
+ * <li>Using OPAQUE does not cause a frame rate drop
* relative to the sensor's maximum capture rate (at that
- * resolution).</li>
- * <li>RAW_OPAQUE will be reprocessable into both YUV_420_888
+ * resolution), see android.scaler.availableInputOutputFormatsMap for more details.</li>
+ * <li>OPAQUE will be reprocessable into both YUV_420_888
* and JPEG formats.</li>
- * <li>The maximum available resolution for RAW_OPAQUE streams
+ * <li>The maximum available resolution for OPAQUE streams
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
+ * <li>Only below controls are effective for reprocessing requests and
+ * will be present in capture results, other controls in reprocess
+ * requests will be ignored by the camera device.<ul>
+ * <li>android.jpeg.*</li>
+ * <li>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}</li>
+ * <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li>
* </ul>
+ * </li>
+ * </ul>
+ *
+ * @see CaptureRequest#EDGE_MODE
+ * @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
- * @hide
*/
- public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
+ public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4;
/**
* <p>The camera device supports accurately reporting the sensor settings for many of
@@ -515,6 +532,45 @@
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6;
+ /**
+ * <p>The camera device supports the YUV420_888 reprocessing use case, similar as
+ * OPAQUE_REPROCESSING, This capability requires the camera device to support the
+ * following:</p>
+ * <ul>
+ * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
+ * <li>YUV420_888 is supported as a common format for both input and output, that is,
+ * StreamConfigurationMap#getOutputSizes(YUV420_888) and
+ * StreamConfigurationMap#getInputSizes(YUV420_888) return non empty Size[] and have
+ * common sizes.</li>
+ * <li>android.scaler.availableInputOutputFormatsMap has the required map entries.</li>
+ * <li>Using YUV420_888 does not cause a frame rate drop
+ * relative to the sensor's maximum capture rate (at that
+ * resolution), see android.scaler.availableInputOutputFormatsMap for more details.</li>
+ * <li>YUV420_888 will be reprocessable into both YUV_420_888
+ * and JPEG formats.</li>
+ * <li>The maximum available resolution for YUV420_888 streams
+ * (both input/output) will match the maximum available
+ * resolution of JPEG streams.</li>
+ * <li>Only the below controls are effective for reprocessing requests and will be
+ * present in capture results. The reprocess requests are from the original capture
+ * results that are assocaited with the intermidate YUV420_888 output buffers.
+ * All other controls in the reprocess requests will be ignored by the camera device.<ul>
+ * <li>android.jpeg.*</li>
+ * <li>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}</li>
+ * <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li>
+ * <li>{@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @see CaptureRequest#EDGE_MODE
+ * @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
+ * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7;
+
//
// Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE
//
@@ -1830,6 +1886,13 @@
*/
public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2;
+ /**
+ * <p>MINIMAL noise reduction is applied without reducing frame rate relative to
+ * sensor output. </p>
+ * @see CaptureRequest#NOISE_REDUCTION_MODE
+ */
+ public static final int NOISE_REDUCTION_MODE_MINIMAL = 3;
+
//
// Enumeration values for CaptureRequest#SENSOR_TEST_PATTERN_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0849df8..fb37ae5 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1154,7 +1154,7 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
* contains MANUAL_SENSOR. Other intent values are always supported.</p>
* <p><b>Possible values:</b>
* <ul>
@@ -1372,6 +1372,10 @@
* camera device will use the highest-quality enhancement algorithms,
* even if it slows down capture rate. FAST means the camera device will
* not slow down capture rate when applying edge enhancement.</p>
+ * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera
+ * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
+ * The camera device may adjust its internal noise reduction parameters for best
+ * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #EDGE_MODE_OFF OFF}</li>
@@ -1387,6 +1391,7 @@
*
* @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
* @see #EDGE_MODE_OFF
* @see #EDGE_MODE_FAST
* @see #EDGE_MODE_HIGH_QUALITY
@@ -1751,18 +1756,28 @@
/**
* <p>Mode of operation for the noise reduction algorithm.</p>
* <p>The noise reduction algorithm attempts to improve image quality by removing
- * excessive noise added by the capture process, especially in dark conditions.
- * OFF means no noise reduction will be applied by the camera device.</p>
+ * excessive noise added by the capture process, especially in dark conditions.</p>
+ * <p>OFF means no noise reduction will be applied by the camera device, for both raw and
+ * YUV domain.</p>
+ * <p>MINIMAL means that only sensor raw domain basic noise reduction is enabled ,to remove
+ * demosaicing or other processing artifacts. For YUV_REPROCESSING, MINIMAL is same as OFF.
+ * This mode is optional, may not be support by all devices. The application should check
+ * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes} before using it.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
* even if it slows down capture rate. FAST means the camera device will not
* slow down capture rate when applying noise filtering.</p>
+ * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera device
+ * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device
+ * may adjust the noise reduction parameters for best image quality based on the
+ * {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor} if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #NOISE_REDUCTION_MODE_OFF OFF}</li>
* <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li>
* <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
+ * <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li>
* </ul></p>
* <p><b>Available values for this device:</b><br>
* {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p>
@@ -1773,9 +1788,11 @@
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
+ * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
* @see #NOISE_REDUCTION_MODE_OFF
* @see #NOISE_REDUCTION_MODE_FAST
* @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
+ * @see #NOISE_REDUCTION_MODE_MINIMAL
*/
@PublicKey
public static final Key<Integer> NOISE_REDUCTION_MODE =
@@ -2416,6 +2433,52 @@
public static final Key<Boolean> BLACK_LEVEL_LOCK =
new Key<Boolean>("android.blackLevel.lock", boolean.class);
+ /**
+ * <p>The amount of exposure time increase factor applied to the original output
+ * frame by the application processing before sending for reprocessing.</p>
+ * <p>This is optional, and will be supported if the camera device supports YUV_REPROCESSING
+ * capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains YUV_REPROCESSING).</p>
+ * <p>For some YUV reprocessing use cases, the application may choose to filter the original
+ * output frames to effectively reduce the noise to the same level as a frame that was
+ * captured with longer exposure time. To be more specific, assuming the original captured
+ * images were captured with a sensitivity of S and an exposure time of T, the model in
+ * the camera device is that the amount of noise in the image would be approximately what
+ * would be expected if the original capture parameters had been a sensitivity of
+ * S/effectiveExposureFactor and an exposure time of T*effectiveExposureFactor, rather
+ * than S and T respectively. If the captured images were processed by the application
+ * before being sent for reprocessing, then the application may have used image processing
+ * algorithms and/or multi-frame image fusion to reduce the noise in the
+ * application-processed images (input images). By using the effectiveExposureFactor
+ * control, the application can communicate to the camera device the actual noise level
+ * improvement in the application-processed image. With this information, the camera
+ * device can select appropriate noise reduction and edge enhancement parameters to avoid
+ * excessive noise reduction ({@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}) and insufficient edge
+ * enhancement ({@link CaptureRequest#EDGE_MODE android.edge.mode}) being applied to the reprocessed frames.</p>
+ * <p>For example, for multi-frame image fusion use case, the application may fuse
+ * multiple output frames together to a final frame for reprocessing. When N image are
+ * fused into 1 image for reprocessing, the exposure time increase factor could be up to
+ * square root of N (based on a simple photon shot noise model). The camera device will
+ * adjust the reprocessing noise reduction and edge enhancement parameters accordingly to
+ * produce the best quality images.</p>
+ * <p>This is relative factor, 1.0 indicates the application hasn't processed the input
+ * buffer in a way that affects its effective exposure time.</p>
+ * <p>This control is only effective for YUV reprocessing capture request. For noise
+ * reduction reprocessing, it is only effective when <code>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode} != OFF</code>.
+ * Similarly, for edge enhancement reprocessing, it is only effective when
+ * <code>{@link CaptureRequest#EDGE_MODE android.edge.mode} != OFF</code>.</p>
+ * <p><b>Units</b>: Relative exposure time increase factor.</p>
+ * <p><b>Range of valid values:</b><br>
+ * >= 1.0</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#EDGE_MODE
+ * @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ @PublicKey
+ public static final Key<Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR =
+ new Key<Float>("android.reprocess.effectiveExposureFactor", float.class);
+
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1396940..5642f6f 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1627,7 +1627,7 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
* contains MANUAL_SENSOR. Other intent values are always supported.</p>
* <p><b>Possible values:</b>
* <ul>
@@ -1988,6 +1988,10 @@
* camera device will use the highest-quality enhancement algorithms,
* even if it slows down capture rate. FAST means the camera device will
* not slow down capture rate when applying edge enhancement.</p>
+ * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera
+ * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
+ * The camera device may adjust its internal noise reduction parameters for best
+ * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #EDGE_MODE_OFF OFF}</li>
@@ -2003,6 +2007,7 @@
*
* @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
* @see #EDGE_MODE_OFF
* @see #EDGE_MODE_FAST
* @see #EDGE_MODE_HIGH_QUALITY
@@ -2465,18 +2470,28 @@
/**
* <p>Mode of operation for the noise reduction algorithm.</p>
* <p>The noise reduction algorithm attempts to improve image quality by removing
- * excessive noise added by the capture process, especially in dark conditions.
- * OFF means no noise reduction will be applied by the camera device.</p>
+ * excessive noise added by the capture process, especially in dark conditions.</p>
+ * <p>OFF means no noise reduction will be applied by the camera device, for both raw and
+ * YUV domain.</p>
+ * <p>MINIMAL means that only sensor raw domain basic noise reduction is enabled ,to remove
+ * demosaicing or other processing artifacts. For YUV_REPROCESSING, MINIMAL is same as OFF.
+ * This mode is optional, may not be support by all devices. The application should check
+ * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes} before using it.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
* even if it slows down capture rate. FAST means the camera device will not
* slow down capture rate when applying noise filtering.</p>
+ * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera device
+ * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device
+ * may adjust the noise reduction parameters for best image quality based on the
+ * {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor} if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #NOISE_REDUCTION_MODE_OFF OFF}</li>
* <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li>
* <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
+ * <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li>
* </ul></p>
* <p><b>Available values for this device:</b><br>
* {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p>
@@ -2487,9 +2502,11 @@
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
+ * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
* @see #NOISE_REDUCTION_MODE_OFF
* @see #NOISE_REDUCTION_MODE_FAST
* @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
+ * @see #NOISE_REDUCTION_MODE_MINIMAL
*/
@PublicKey
public static final Key<Integer> NOISE_REDUCTION_MODE =
@@ -3647,6 +3664,52 @@
public static final Key<Long> SYNC_FRAME_NUMBER =
new Key<Long>("android.sync.frameNumber", long.class);
+ /**
+ * <p>The amount of exposure time increase factor applied to the original output
+ * frame by the application processing before sending for reprocessing.</p>
+ * <p>This is optional, and will be supported if the camera device supports YUV_REPROCESSING
+ * capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains YUV_REPROCESSING).</p>
+ * <p>For some YUV reprocessing use cases, the application may choose to filter the original
+ * output frames to effectively reduce the noise to the same level as a frame that was
+ * captured with longer exposure time. To be more specific, assuming the original captured
+ * images were captured with a sensitivity of S and an exposure time of T, the model in
+ * the camera device is that the amount of noise in the image would be approximately what
+ * would be expected if the original capture parameters had been a sensitivity of
+ * S/effectiveExposureFactor and an exposure time of T*effectiveExposureFactor, rather
+ * than S and T respectively. If the captured images were processed by the application
+ * before being sent for reprocessing, then the application may have used image processing
+ * algorithms and/or multi-frame image fusion to reduce the noise in the
+ * application-processed images (input images). By using the effectiveExposureFactor
+ * control, the application can communicate to the camera device the actual noise level
+ * improvement in the application-processed image. With this information, the camera
+ * device can select appropriate noise reduction and edge enhancement parameters to avoid
+ * excessive noise reduction ({@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}) and insufficient edge
+ * enhancement ({@link CaptureRequest#EDGE_MODE android.edge.mode}) being applied to the reprocessed frames.</p>
+ * <p>For example, for multi-frame image fusion use case, the application may fuse
+ * multiple output frames together to a final frame for reprocessing. When N image are
+ * fused into 1 image for reprocessing, the exposure time increase factor could be up to
+ * square root of N (based on a simple photon shot noise model). The camera device will
+ * adjust the reprocessing noise reduction and edge enhancement parameters accordingly to
+ * produce the best quality images.</p>
+ * <p>This is relative factor, 1.0 indicates the application hasn't processed the input
+ * buffer in a way that affects its effective exposure time.</p>
+ * <p>This control is only effective for YUV reprocessing capture request. For noise
+ * reduction reprocessing, it is only effective when <code>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode} != OFF</code>.
+ * Similarly, for edge enhancement reprocessing, it is only effective when
+ * <code>{@link CaptureRequest#EDGE_MODE android.edge.mode} != OFF</code>.</p>
+ * <p><b>Units</b>: Relative exposure time increase factor.</p>
+ * <p><b>Range of valid values:</b><br>
+ * >= 1.0</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#EDGE_MODE
+ * @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ @PublicKey
+ public static final Key<Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR =
+ new Key<Float>("android.reprocess.effectiveExposureFactor", float.class);
+
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/midi/MidiDevice.java b/core/java/android/midi/MidiDevice.java
index 8aaa86d..b91aedf 100644
--- a/core/java/android/midi/MidiDevice.java
+++ b/core/java/android/midi/MidiDevice.java
@@ -30,6 +30,7 @@
* This class is used for sending and receiving data to and from an MIDI device
* Instances of this class are created by {@link MidiManager#openDevice}.
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public final class MidiDevice {
diff --git a/core/java/android/midi/MidiDeviceInfo.java b/core/java/android/midi/MidiDeviceInfo.java
index 5cf62b5..dde2669 100644
--- a/core/java/android/midi/MidiDeviceInfo.java
+++ b/core/java/android/midi/MidiDeviceInfo.java
@@ -28,6 +28,7 @@
* This class is just an immutable object to encapsulate the MIDI device description.
* Use the MidiDevice class to actually communicate with devices.
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public class MidiDeviceInfo implements Parcelable {
@@ -45,7 +46,7 @@
public static final int TYPE_VIRTUAL = 2;
private final int mType; // USB or virtual
- private final int mId; // unique ID generated by MidiService
+ private final int mId; // unique ID generated by MidiService
private final int mInputPortCount;
private final int mOutputPortCount;
private final Bundle mProperties;
diff --git a/core/java/android/midi/MidiDeviceServer.java b/core/java/android/midi/MidiDeviceServer.java
index ccb2e0c..7499934 100644
--- a/core/java/android/midi/MidiDeviceServer.java
+++ b/core/java/android/midi/MidiDeviceServer.java
@@ -25,7 +25,14 @@
import java.io.IOException;
import java.util.ArrayList;
-/** @hide */
+/**
+ * This class is used to provide the implemention of MIDI device.
+ * Applications may call {@link MidiManager#createDeviceServer}
+ * to create an instance of this class to implement a virtual MIDI device.
+ *
+ * CANDIDATE FOR PUBLIC API
+ * @hide
+ */
public final class MidiDeviceServer implements Closeable {
private static final String TAG = "MidiDeviceServer";
diff --git a/core/java/android/midi/MidiInputPort.java b/core/java/android/midi/MidiInputPort.java
index 88ace5f..51c47dd 100644
--- a/core/java/android/midi/MidiInputPort.java
+++ b/core/java/android/midi/MidiInputPort.java
@@ -26,6 +26,7 @@
/**
* This class is used for sending data to a port on a MIDI device
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public class MidiInputPort extends MidiPort implements MidiReceiver {
diff --git a/core/java/android/midi/MidiManager.java b/core/java/android/midi/MidiManager.java
index 2c1c7bf..8aa8395 100644
--- a/core/java/android/midi/MidiManager.java
+++ b/core/java/android/midi/MidiManager.java
@@ -35,6 +35,7 @@
* {@samplecode
* MidiManager manager = (MidiManager) getSystemService(Context.MIDI_SERVICE);}
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public class MidiManager {
@@ -184,7 +185,7 @@
* @param properties a {@link android.os.Bundle} containing properties describing the device
* @param isPrivate true if this device should only be visible and accessible to apps
* with the same UID as the caller
- * @return a {@link MidiVirtualDevice} object to locally represent the device
+ * @return a {@link MidiDeviceServer} object to locally represent the device
*/
public MidiDeviceServer createDeviceServer(int numInputPorts, int numOutputPorts,
Bundle properties, boolean isPrivate) {
diff --git a/core/java/android/midi/MidiOutputPort.java b/core/java/android/midi/MidiOutputPort.java
index 00b7bad..332b431 100644
--- a/core/java/android/midi/MidiOutputPort.java
+++ b/core/java/android/midi/MidiOutputPort.java
@@ -26,8 +26,9 @@
import java.util.ArrayList;
/**
- * This class is used for receiving data to a port on a MIDI device
+ * This class is used for receiving data from a port on a MIDI device
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public class MidiOutputPort extends MidiPort implements MidiSender {
@@ -85,8 +86,9 @@
}
}
} catch (IOException e) {
- Log.e(TAG, "read failed");
// report I/O failure
+ Log.e(TAG, "read failed");
+ } finally {
IoUtils.closeQuietly(mInputStream);
onIOException();
}
diff --git a/core/java/android/midi/MidiPort.java b/core/java/android/midi/MidiPort.java
index 44d1a88..7512a90 100644
--- a/core/java/android/midi/MidiPort.java
+++ b/core/java/android/midi/MidiPort.java
@@ -24,6 +24,7 @@
* This class represents a MIDI input or output port.
* Base class for {@link MidiInputPort} and {@link MidiOutputPort}
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
abstract public class MidiPort implements Closeable {
diff --git a/core/java/android/midi/MidiReceiver.java b/core/java/android/midi/MidiReceiver.java
index a4e1a10..fdfe51a 100644
--- a/core/java/android/midi/MidiReceiver.java
+++ b/core/java/android/midi/MidiReceiver.java
@@ -19,13 +19,14 @@
import java.io.IOException;
/**
- * Interface for receiving events from a MIDI device.
+ * Interface for receiving data from a MIDI device.
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public interface MidiReceiver {
/**
- * Called to pass a MIDI event to the receiver.
+ * Called to pass MIDI data to the receiver.
*
* NOTE: the msg array parameter is only valid within the context of this call.
* The msg bytes should be copied by the receiver rather than retaining a reference
@@ -33,9 +34,9 @@
* Also, modifying the contents of the msg array parameter may result in other receivers
* in the same application receiving incorrect values in their onPost() method.
*
- * @param msg a byte array containing the MIDI message
- * @param offset the offset of the first byte of the message in the byte array
- * @param count the number of bytes in the message
+ * @param msg a byte array containing the MIDI data
+ * @param offset the offset of the first byte of the data in the byte array
+ * @param count the number of bytes of MIDI data in the array
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
* @throws IOException
*/
diff --git a/core/java/android/midi/MidiSender.java b/core/java/android/midi/MidiSender.java
index 7958a06..2b7afad 100644
--- a/core/java/android/midi/MidiSender.java
+++ b/core/java/android/midi/MidiSender.java
@@ -20,6 +20,7 @@
* Interface provided by a device to allow attaching
* MidiReceivers to a MIDI device.
*
+ * CANDIDATE FOR PUBLIC API
* @hide
*/
public interface MidiSender {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 365f2b6..37ee961 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -188,6 +188,7 @@
for (InetAddress dnsServer : dnsServers) {
NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
}
+ dest.writeString(domains);
}
protected static void readFromParcel(StaticIpConfiguration s, Parcel in) {
@@ -198,5 +199,6 @@
for (int i = 0; i < size; i++) {
s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
}
+ s.domains = in.readString();
}
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 7dd559c..051273d 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1434,9 +1434,9 @@
* and {@link #CONTENT_MULTI_VCARD_URI} to indicate that the returned
* vcard should not contain a photo.
*
- * @hide
+ * This is useful for obtaining a space efficient vcard.
*/
- public static final String QUERY_PARAMETER_VCARD_NO_PHOTO = "nophoto";
+ public static final String QUERY_PARAMETER_VCARD_NO_PHOTO = "no_photo";
/**
* Base {@link Uri} for referencing multiple {@link Contacts} entry,
@@ -2194,6 +2194,16 @@
public static final String CONTACT_ID = "contact_id";
/**
+ * Persistent unique id for each raw_contact within its account.
+ * This id is provided by its own data source, and can be used to backup metadata
+ * to the server.
+ * This should be unique within each set of account_name/account_type/data_set
+ *
+ * @hide
+ */
+ public static final String BACKUP_ID = "backup_id";
+
+ /**
* The data set within the account that this row belongs to. This allows
* multiple sync adapters for the same account type to distinguish between
* each others' data.
@@ -2238,33 +2248,6 @@
public static final String DELETED = "deleted";
/**
- * The "name_verified" flag: "1" means that the name fields on this raw
- * contact can be trusted and therefore should be used for the entire
- * aggregated contact.
- * <p>
- * If an aggregated contact contains more than one raw contact with a
- * verified name, one of those verified names is chosen at random.
- * If an aggregated contact contains no verified names, the
- * name is chosen randomly from the constituent raw contacts.
- * </p>
- * <p>
- * Updating this flag from "0" to "1" automatically resets it to "0" on
- * all other raw contacts in the same aggregated contact.
- * </p>
- * <p>
- * Sync adapters should only specify a value for this column when
- * inserting a raw contact and leave it out when doing an update.
- * </p>
- * <p>
- * The default value is "0"
- * </p>
- * <p>Type: INTEGER</p>
- *
- * @hide
- */
- public static final String NAME_VERIFIED = "name_verified";
-
- /**
* The "read-only" flag: "0" by default, "1" if the row cannot be modified or
* deleted except by a sync adapter. See {@link ContactsContract#CALLER_IS_SYNCADAPTER}.
* <P>Type: INTEGER</P>
@@ -2960,7 +2943,6 @@
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DELETED);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, CONTACT_ID);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, STARRED);
- DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, NAME_VERIFIED);
android.content.Entity contact = new android.content.Entity(cv);
// read data rows until the contact id changes
@@ -3986,6 +3968,13 @@
public static final String MIMETYPE = "mimetype";
/**
+ * Hash id on the data fields, used for backup and restore.
+ *
+ * @hide
+ */
+ public static final String HASH_ID = "hash_id";
+
+ /**
* A reference to the {@link RawContacts#_ID}
* that this data belongs to.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 259367e..5b26ebb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6780,7 +6780,6 @@
@RemotableViewMethod
public void setVisibility(@Visibility int visibility) {
setFlags(visibility, VISIBILITY_MASK);
- if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
}
/**
@@ -8806,20 +8805,28 @@
}
/**
- * Called when the visibility of the view or an ancestor of the view is changed.
- * @param changedView The view whose visibility changed. Could be 'this' or
- * an ancestor view.
- * @param visibility The new visibility of changedView: {@link #VISIBLE},
- * {@link #INVISIBLE} or {@link #GONE}.
+ * Called when the visibility of the view or an ancestor of the view has
+ * changed.
+ *
+ * @param changedView The view whose visibility changed. May be
+ * {@code this} or an ancestor view.
+ * @param visibility The new visibility, one of {@link #VISIBLE},
+ * {@link #INVISIBLE} or {@link #GONE}.
*/
protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
- if (visibility == VISIBLE) {
+ final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
+ if (visible) {
if (mAttachInfo != null) {
initialAwakenScrollBars();
} else {
mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
}
}
+
+ final Drawable dr = mBackground;
+ if (dr != null && visible != dr.isVisible()) {
+ dr.setVisible(visible, false);
+ }
}
/**
@@ -14885,10 +14892,9 @@
void setDisplayListProperties(RenderNode renderNode) {
if (renderNode != null) {
renderNode.setHasOverlappingRendering(hasOverlappingRendering());
- if (mParent instanceof ViewGroup) {
- renderNode.setClipToBounds(
- (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
- }
+ renderNode.setClipToBounds(mParent instanceof ViewGroup
+ && ((ViewGroup) mParent).getClipChildren());
+
float alpha = 1;
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 151ff83..15e7060 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -472,8 +472,10 @@
// Compute surface insets required to draw at specified Z value.
// TODO: Use real shadow insets for a constant max Z.
- final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
- attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
+ if (!attrs.hasManualSurfaceInsets) {
+ final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
+ attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
+ }
CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator();
@@ -760,6 +762,7 @@
final int oldInsetRight = mWindowAttributes.surfaceInsets.right;
final int oldInsetBottom = mWindowAttributes.surfaceInsets.bottom;
final int oldSoftInputMode = mWindowAttributes.softInputMode;
+ final boolean oldHasManualSurfaceInsets = mWindowAttributes.hasManualSurfaceInsets;
// Keep track of the actual window flags supplied by the client.
mClientWindowLayoutFlags = attrs.flags;
@@ -786,6 +789,7 @@
// Restore old surface insets.
mWindowAttributes.surfaceInsets.set(
oldInsetLeft, oldInsetTop, oldInsetRight, oldInsetBottom);
+ mWindowAttributes.hasManualSurfaceInsets = oldHasManualSurfaceInsets;
applyKeepScreenOnFlag(mWindowAttributes);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 12b310f..740cb5d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1325,6 +1325,16 @@
* @hide
*/
public final Rect surfaceInsets = new Rect();
+
+ /**
+ * Whether the surface insets have been manually set. When set to
+ * {@code false}, the view root will automatically determine the
+ * appropriate surface insets.
+ *
+ * @see #surfaceInsets
+ * @hide
+ */
+ public boolean hasManualSurfaceInsets;
/**
* The desired bitmap format. May be one of the constants in
@@ -1621,6 +1631,7 @@
out.writeInt(surfaceInsets.top);
out.writeInt(surfaceInsets.right);
out.writeInt(surfaceInsets.bottom);
+ out.writeInt(hasManualSurfaceInsets ? 1 : 0);
out.writeInt(needsMenuKey);
}
@@ -1669,6 +1680,7 @@
surfaceInsets.top = in.readInt();
surfaceInsets.right = in.readInt();
surfaceInsets.bottom = in.readInt();
+ hasManualSurfaceInsets = in.readInt() != 0;
needsMenuKey = in.readInt();
}
@@ -1851,6 +1863,11 @@
changes |= SURFACE_INSETS_CHANGED;
}
+ if (hasManualSurfaceInsets != o.hasManualSurfaceInsets) {
+ hasManualSurfaceInsets = o.hasManualSurfaceInsets;
+ changes |= SURFACE_INSETS_CHANGED;
+ }
+
if (needsMenuKey != o.needsMenuKey) {
needsMenuKey = o.needsMenuKey;
changes |= NEEDS_MENU_KEY_CHANGED;
@@ -1959,8 +1976,11 @@
if (userActivityTimeout >= 0) {
sb.append(" userActivityTimeout=").append(userActivityTimeout);
}
- if (!surfaceInsets.equals(Insets.NONE)) {
+ if (!surfaceInsets.equals(Insets.NONE) || hasManualSurfaceInsets) {
sb.append(" surfaceInsets=").append(surfaceInsets);
+ if (hasManualSurfaceInsets) {
+ sb.append(" (manual)");
+ }
}
if (needsMenuKey != NEEDS_MENU_UNSET) {
sb.append(" needsMenuKey=");
diff --git a/core/java/android/webkit/WebResourceRequest.java b/core/java/android/webkit/WebResourceRequest.java
index 2185658de3..07402b3 100644
--- a/core/java/android/webkit/WebResourceRequest.java
+++ b/core/java/android/webkit/WebResourceRequest.java
@@ -42,6 +42,8 @@
/**
* Gets whether a gesture (such as a click) was associated with the request.
+ * For security reasons in certain situations this method may return false even though the
+ * sequence of events which caused the request to be created was initiated by a user gesture.
*
* @return whether a gesture was associated with the request.
*/
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index d52dd60..1cc899d 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -50,7 +50,9 @@
* is called once for each main frame load so a page with iframes or
* framesets will call onPageStarted one time for the main frame. This also
* means that onPageStarted will not be called when the contents of an
- * embedded frame changes, i.e. clicking a link whose target is an iframe.
+ * embedded frame changes, i.e. clicking a link whose target is an iframe,
+ * it will also not be called for fragment navigations (navigations to
+ * #fragment_id).
*
* @param view The WebView that is initiating the callback.
* @param url The url to be loaded.
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index f208fff..b5782fc 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -18,6 +18,7 @@
import java.util.ArrayList;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -203,11 +204,15 @@
}
@Override
- @RemotableViewMethod
- public void setVisibility(@Visibility int visibility) {
- super.setVisibility(visibility);
- if (mForeground != null) {
- mForeground.setVisible(visibility == VISIBLE, false);
+ protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+
+ final Drawable dr = mForeground;
+ if (dr != null) {
+ final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
+ if (visible != dr.isVisible()) {
+ dr.setVisible(visible, false);
+ }
}
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index f5cd915..7cf3eed 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -27,6 +27,11 @@
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.IBinder;
+import android.transition.Transition;
+import android.transition.Transition.EpicenterCallback;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -39,12 +44,13 @@
import android.view.WindowManager;
import java.lang.ref.WeakReference;
+import java.util.List;
/**
* <p>A popup window that can be used to display an arbitrary view. The popup
* window is a floating container that appears on top of the current
* activity.</p>
- *
+ *
* @see android.widget.AutoCompleteTextView
* @see android.widget.Spinner
*/
@@ -56,7 +62,7 @@
* it doesn't.
*/
public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
-
+
/**
* Mode for {@link #setInputMethodMode(int)}: this popup always needs to
* work with an input method, regardless of whether it is focusable. This
@@ -64,7 +70,7 @@
* the input method while it is shown.
*/
public static final int INPUT_METHOD_NEEDED = 1;
-
+
/**
* Mode for {@link #setInputMethodMode(int)}: this popup never needs to
* work with an input method, regardless of whether it is focusable. This
@@ -75,14 +81,32 @@
private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START;
+ /**
+ * Default animation style indicating that separate animations should be
+ * used for top/bottom anchoring states.
+ */
+ private static final int ANIMATION_STYLE_DEFAULT = -1;
+
+ private final int[] mDrawingLocation = new int[2];
+ private final int[] mScreenLocation = new int[2];
+ private final Rect mTempRect = new Rect();
+ private final Rect mAnchorBounds = new Rect();
+
private Context mContext;
private WindowManager mWindowManager;
-
+
private boolean mIsShowing;
private boolean mIsDropdown;
+ /** View that handles event dispatch and content transitions. */
+ private PopupDecorView mDecorView;
+
+ /** View that holds the popup background. May be the content view. */
+ private View mBackgroundView;
+
+ /** The contents of the popup. */
private View mContentView;
- private View mPopupView;
+
private boolean mFocusable;
private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
@@ -112,49 +136,52 @@
private float mElevation;
- private int[] mDrawingLocation = new int[2];
- private int[] mScreenLocation = new int[2];
- private Rect mTempRect = new Rect();
-
private Drawable mBackground;
private Drawable mAboveAnchorBackgroundDrawable;
private Drawable mBelowAnchorBackgroundDrawable;
- // Temporary animation centers. Should be moved into window params?
- private int mAnchorRelativeX;
- private int mAnchorRelativeY;
+ private Transition mEnterTransition;
+ private Transition mExitTransition;
private boolean mAboveAnchor;
private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-
+
private OnDismissListener mOnDismissListener;
private boolean mIgnoreCheekPress = false;
- private int mAnimationStyle = -1;
-
+ private int mAnimationStyle = ANIMATION_STYLE_DEFAULT;
+
private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
com.android.internal.R.attr.state_above_anchor
};
private WeakReference<View> mAnchor;
- private final OnScrollChangedListener mOnScrollChangedListener =
- new OnScrollChangedListener() {
- @Override
- public void onScrollChanged() {
- final View anchor = mAnchor != null ? mAnchor.get() : null;
- if (anchor != null && mPopupView != null) {
- final WindowManager.LayoutParams p = (WindowManager.LayoutParams)
- mPopupView.getLayoutParams();
+ private final EpicenterCallback mEpicenterCallback = new EpicenterCallback() {
+ @Override
+ public Rect onGetEpicenter(Transition transition) {
+ return mAnchorBounds;
+ }
+ };
- updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
- mAnchoredGravity));
- update(p.x, p.y, -1, -1, true);
- }
+ private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() {
+ @Override
+ public void onScrollChanged() {
+ final View anchor = mAnchor != null ? mAnchor.get() : null;
+ if (anchor != null && mDecorView != null) {
+ final WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mDecorView.getLayoutParams();
+
+ updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
+ mAnchoredGravity));
+ update(p.x, p.y, -1, -1, true);
}
- };
+ }
+ };
- private int mAnchorXoff, mAnchorYoff, mAnchoredGravity;
+ private int mAnchorXoff;
+ private int mAnchorYoff;
+ private int mAnchoredGravity;
private boolean mOverlapAnchor;
private boolean mPopupViewInitialLayoutDirectionInherited;
@@ -185,10 +212,10 @@
public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
-
+
/**
* <p>Create a new, empty, non focusable popup window of dimension (0,0).</p>
- *
+ *
* <p>The popup does not provide a background.</p>
*/
public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
@@ -201,11 +228,34 @@
mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
- final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, -1);
- mAnimationStyle = animStyle == R.style.Animation_PopupWindow ? -1 : animStyle;
+ // Preserve default behavior from Gingerbread. If the animation is
+ // undefined or explicitly specifies the Gingerbread animation style,
+ // use a sentinel value.
+ if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) {
+ final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0);
+ if (animStyle == R.style.Animation_PopupWindow) {
+ mAnimationStyle = ANIMATION_STYLE_DEFAULT;
+ } else {
+ mAnimationStyle = animStyle;
+ }
+ } else {
+ mAnimationStyle = ANIMATION_STYLE_DEFAULT;
+ }
+
+ final Transition enterTransition = getTransition(a.getResourceId(
+ R.styleable.PopupWindow_popupEnterTransition, 0));
+ final Transition exitTransition;
+ if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) {
+ exitTransition = getTransition(a.getResourceId(
+ R.styleable.PopupWindow_popupExitTransition, 0));
+ } else {
+ exitTransition = enterTransition == null ? null : enterTransition.clone();
+ }
a.recycle();
+ setEnterTransition(enterTransition);
+ setExitTransition(exitTransition);
setBackgroundDrawable(bg);
}
@@ -286,6 +336,37 @@
setFocusable(focusable);
}
+ public void setEnterTransition(Transition enterTransition) {
+ mEnterTransition = enterTransition;
+
+ if (mEnterTransition != null) {
+ mEnterTransition.setEpicenterCallback(mEpicenterCallback);
+ }
+ }
+
+ public void setExitTransition(Transition exitTransition) {
+ mExitTransition = exitTransition;
+
+ if (mExitTransition != null) {
+ mExitTransition.setEpicenterCallback(mEpicenterCallback);
+ }
+ }
+
+ private Transition getTransition(int resId) {
+ if (resId != 0 && resId != R.transition.no_transition) {
+ final TransitionInflater inflater = TransitionInflater.from(mContext);
+ final Transition transition = inflater.inflateTransition(resId);
+ if (transition != null) {
+ final boolean isEmpty = transition instanceof TransitionSet
+ && ((TransitionSet) transition).getTransitionCount() == 0;
+ if (!isEmpty) {
+ return transition;
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Return the drawable used as the popup window's background.
*
@@ -379,7 +460,7 @@
* Set the flag on popup to ignore cheek press events; by default this flag
* is set to false
* which means the popup will not ignore cheek press dispatch events.
- *
+ *
* <p>If the popup is showing, calling this method will take effect only
* the next time the popup is shown or through a manual call to one of
* the {@link #update()} methods.</p>
@@ -389,7 +470,7 @@
public void setIgnoreCheekPress() {
mIgnoreCheekPress = true;
}
-
+
/**
* <p>Change the animation style resource for this popup.</p>
@@ -401,13 +482,13 @@
* @param animationStyle animation style to use when the popup appears
* and disappears. Set to -1 for the default animation, 0 for no
* animation, or a resource identifier for an explicit animation.
- *
+ *
* @see #update()
*/
public void setAnimationStyle(int animationStyle) {
mAnimationStyle = animationStyle;
}
-
+
/**
* <p>Return the view used as the content of the popup window.</p>
*
@@ -491,7 +572,7 @@
* @param focusable true if the popup should grab focus, false otherwise.
*
* @see #isFocusable()
- * @see #isShowing()
+ * @see #isShowing()
* @see #update()
*/
public void setFocusable(boolean focusable) {
@@ -500,23 +581,23 @@
/**
* Return the current value in {@link #setInputMethodMode(int)}.
- *
+ *
* @see #setInputMethodMode(int)
*/
public int getInputMethodMode() {
return mInputMethodMode;
-
+
}
-
+
/**
* Control how the popup operates with an input method: one of
* {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
* or {@link #INPUT_METHOD_NOT_NEEDED}.
- *
+ *
* <p>If the popup is showing, calling this method will take effect only
* the next time the popup is shown or through a manual call to one of
* the {@link #update()} methods.</p>
- *
+ *
* @see #getInputMethodMode()
* @see #update()
*/
@@ -547,12 +628,12 @@
public int getSoftInputMode() {
return mSoftInputMode;
}
-
+
/**
* <p>Indicates whether the popup window receives touch events.</p>
- *
+ *
* @return true if the popup is touchable, false otherwise
- *
+ *
* @see #setTouchable(boolean)
*/
public boolean isTouchable() {
@@ -571,7 +652,7 @@
* @param touchable true if the popup should receive touch events, false otherwise
*
* @see #isTouchable()
- * @see #isShowing()
+ * @see #isShowing()
* @see #update()
*/
public void setTouchable(boolean touchable) {
@@ -581,9 +662,9 @@
/**
* <p>Indicates whether the popup window will be informed of touch events
* outside of its window.</p>
- *
+ *
* @return true if the popup is outside touchable, false otherwise
- *
+ *
* @see #setOutsideTouchable(boolean)
*/
public boolean isOutsideTouchable() {
@@ -604,7 +685,7 @@
* touch events, false otherwise
*
* @see #isOutsideTouchable()
- * @see #isShowing()
+ * @see #isShowing()
* @see #update()
*/
public void setOutsideTouchable(boolean touchable) {
@@ -613,9 +694,9 @@
/**
* <p>Indicates whether clipping of the popup window is enabled.</p>
- *
+ *
* @return true if the clipping is enabled, false otherwise
- *
+ *
* @see #setClippingEnabled(boolean)
*/
public boolean isClippingEnabled() {
@@ -626,13 +707,13 @@
* <p>Allows the popup window to extend beyond the bounds of the screen. By default the
* window is clipped to the screen boundaries. Setting this to false will allow windows to be
* accurately positioned.</p>
- *
+ *
* <p>If the popup is showing, calling this method will take effect only
* the next time the popup is shown or through a manual call to one of
* the {@link #update()} methods.</p>
*
* @param enabled false if the window should be allowed to extend outside of the screen
- * @see #isShowing()
+ * @see #isShowing()
* @see #isClippingEnabled()
* @see #update()
*/
@@ -660,12 +741,12 @@
void setAllowScrollingAnchorParent(boolean enabled) {
mAllowScrollingAnchorParent = enabled;
}
-
+
/**
* <p>Indicates whether the popup window supports splitting touches.</p>
- *
+ *
* @return true if the touch splitting is enabled, false otherwise
- *
+ *
* @see #setSplitTouchEnabled(boolean)
*/
public boolean isSplitTouchEnabled() {
@@ -794,7 +875,7 @@
* window manager by the popup. By default these are 0, meaning that
* the current width or height is requested as an explicit size from
* the window manager. You can supply
- * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
+ * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
* {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
* spec supplied instead, replacing the absolute width and height that
* has been set in the popup.</p>
@@ -815,7 +896,7 @@
mWidthMode = widthSpec;
mHeightMode = heightSpec;
}
-
+
/**
* <p>Return this popup's height MeasureSpec</p>
*
@@ -836,7 +917,7 @@
* @param height the height MeasureSpec of the popup
*
* @see #getHeight()
- * @see #isShowing()
+ * @see #isShowing()
*/
public void setHeight(int height) {
mHeight = height;
@@ -847,7 +928,7 @@
*
* @return the width MeasureSpec of the popup
*
- * @see #setWidth(int)
+ * @see #setWidth(int)
*/
public int getWidth() {
return mWidth;
@@ -913,7 +994,7 @@
* a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
* <code>Gravity.LEFT | Gravity.TOP</code>.
* </p>
- *
+ *
* @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
* @param gravity the gravity which controls the placement of the popup window
* @param x the popup's x location offset
@@ -946,7 +1027,7 @@
WindowManager.LayoutParams p = createPopupLayout(token);
p.windowAnimations = computeAnimationResource();
-
+
preparePopup(p);
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.START;
@@ -1049,12 +1130,12 @@
// do the job.
if (mAboveAnchorBackgroundDrawable != null) {
if (mAboveAnchor) {
- mPopupView.setBackground(mAboveAnchorBackgroundDrawable);
+ mDecorView.setBackground(mAboveAnchorBackgroundDrawable);
} else {
- mPopupView.setBackground(mBelowAnchorBackgroundDrawable);
+ mDecorView.setBackground(mBelowAnchorBackgroundDrawable);
}
} else {
- mPopupView.refreshDrawableState();
+ mDecorView.refreshDrawableState();
}
}
}
@@ -1089,36 +1170,79 @@
+ "calling setContentView() before attempting to show the popup.");
}
+ // When a background is available, we embed the content view within
+ // another view that owns the background drawable.
if (mBackground != null) {
- final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
- int height = ViewGroup.LayoutParams.MATCH_PARENT;
- if (layoutParams != null &&
- layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
- height = ViewGroup.LayoutParams.WRAP_CONTENT;
- }
-
- // when a background is available, we embed the content view
- // within another view that owns the background drawable
- PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
- PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, height
- );
- popupViewContainer.setBackground(mBackground);
- popupViewContainer.addView(mContentView, listParams);
-
- mPopupView = popupViewContainer;
+ mBackgroundView = createBackgroundView(mContentView);
+ mBackgroundView.setBackground(mBackground);
} else {
- mPopupView = mContentView;
+ mBackgroundView = mContentView;
}
- mPopupView.setElevation(mElevation);
+ mDecorView = createDecorView(mBackgroundView);
+
+ // The background owner should be elevated so that it casts a shadow.
+ mBackgroundView.setElevation(mElevation);
+
+ // We may wrap that in another view, so we'll need to manually specify
+ // the surface insets.
+ final int surfaceInset = (int) Math.ceil(mBackgroundView.getZ() * 2);
+ p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
+ p.hasManualSurfaceInsets = true;
+
mPopupViewInitialLayoutDirectionInherited =
- (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
+ (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
mPopupWidth = p.width;
mPopupHeight = p.height;
}
/**
+ * Wraps a content view in a PopupViewContainer.
+ *
+ * @param contentView the content view to wrap
+ * @return a PopupViewContainer that wraps the content view
+ */
+ private PopupBackgroundView createBackgroundView(View contentView) {
+ final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
+ final int height;
+ if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
+ height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ } else {
+ height = ViewGroup.LayoutParams.MATCH_PARENT;
+ }
+
+ final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext);
+ final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, height);
+ backgroundView.addView(contentView, listParams);
+
+ return backgroundView;
+ }
+
+ /**
+ * Wraps a content view in a FrameLayout.
+ *
+ * @param contentView the content view to wrap
+ * @return a FrameLayout that wraps the content view
+ */
+ private PopupDecorView createDecorView(View contentView) {
+ final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
+ final int height;
+ if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
+ height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ } else {
+ height = ViewGroup.LayoutParams.MATCH_PARENT;
+ }
+
+ final PopupDecorView decorView = new PopupDecorView(mContext);
+ decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height);
+ decorView.setClipChildren(false);
+ decorView.setClipToPadding(false);
+
+ return decorView;
+ }
+
+ /**
* <p>Invoke the popup window by adding the content view to the window
* manager.</p>
*
@@ -1130,16 +1254,34 @@
if (mContext != null) {
p.packageName = mContext.getPackageName();
}
- mPopupView.setFitsSystemWindows(mLayoutInsetDecor);
+
+ final View rootView = mContentView.getRootView();
+ rootView.setFitsSystemWindows(mLayoutInsetDecor);
setLayoutDirectionFromAnchor();
- mWindowManager.addView(mPopupView, p);
+
+ mWindowManager.addView(rootView, p);
+
+ // Postpone enter transition until the scene root has been laid out.
+ if (mEnterTransition != null) {
+ mEnterTransition.addTarget(mBackgroundView);
+ mEnterTransition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transition.removeListener(this);
+ transition.removeTarget(mBackgroundView);
+ }
+ });
+
+ mDecorView.getViewTreeObserver().addOnGlobalLayoutListener(
+ new PostLayoutTransitionListener(mDecorView, mEnterTransition));
+ }
}
private void setLayoutDirectionFromAnchor() {
if (mAnchor != null) {
View anchor = mAnchor.get();
if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
- mPopupView.setLayoutDirection(anchor.getLayoutDirection());
+ mDecorView.setLayoutDirection(anchor.getLayoutDirection());
}
}
}
@@ -1224,7 +1366,7 @@
}
private int computeAnimationResource() {
- if (mAnimationStyle == -1) {
+ if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) {
if (mIsDropdown) {
return mAboveAnchor
? com.android.internal.R.style.Animation_DropDownUp
@@ -1243,7 +1385,7 @@
* <p>
* The height must have been set on the layout parameters prior to calling
* this method.
- *
+ *
* @param anchor the view on which the popup window must be anchored
* @param p the layout parameters used to display the drop down
* @param xoff horizontal offset used to adjust for background padding
@@ -1342,18 +1484,18 @@
p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
// Compute the position of the anchor relative to the popup.
- mAnchorRelativeX = mDrawingLocation[0] - p.x + anchorHeight / 2;
- mAnchorRelativeY = mDrawingLocation[1] - p.y + anchorWidth / 2;
+ mAnchorBounds.set(0, 0, anchorWidth, anchorHeight);
+ mAnchorBounds.offset(mDrawingLocation[0] - p.x, mDrawingLocation[1] - p.y);
return onTop;
}
-
+
/**
* Returns the maximum height that is available for the popup to be
* completely shown. It is recommended that this height be the maximum for
* the popup's height, otherwise it is possible that the popup will be
* clipped.
- *
+ *
* @param anchor The view on which the popup window must be anchored.
* @return The maximum available height for the popup to be completely
* shown.
@@ -1376,14 +1518,14 @@
public int getMaxAvailableHeight(View anchor, int yOffset) {
return getMaxAvailableHeight(anchor, yOffset, false);
}
-
+
/**
* Returns the maximum height that is available for the popup to be
* completely shown, optionally ignoring any bottom decorations such as
* the input method. It is recommended that this height be the maximum for
* the popup's height, otherwise it is possible that the popup will be
* clipped.
- *
+ *
* @param anchor The view on which the popup window must be anchored.
* @param yOffset y offset from the view's bottom edge
* @param ignoreBottomDecorations if true, the height returned will be
@@ -1391,7 +1533,7 @@
* bottom decorations
* @return The maximum available height for the popup to be completely
* shown.
- *
+ *
* @hide Pending API council approval.
*/
public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
@@ -1400,7 +1542,7 @@
final int[] anchorPos = mDrawingLocation;
anchor.getLocationOnScreen(anchorPos);
-
+
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
Resources res = anchor.getContext().getResources();
@@ -1413,49 +1555,78 @@
int returnedHeight = Math.max(distanceToBottom, distanceToTop);
if (mBackground != null) {
mBackground.getPadding(mTempRect);
- returnedHeight -= mTempRect.top + mTempRect.bottom;
+ returnedHeight -= mTempRect.top + mTempRect.bottom;
}
-
+
return returnedHeight;
}
-
+
/**
* <p>Dispose of the popup window. This method can be invoked only after
* {@link #showAsDropDown(android.view.View)} has been executed. Failing that, calling
* this method will have no effect.</p>
*
- * @see #showAsDropDown(android.view.View)
+ * @see #showAsDropDown(android.view.View)
*/
public void dismiss() {
- if (isShowing() && mPopupView != null) {
+ if (isShowing() && mDecorView != null) {
mIsShowing = false;
unregisterForScrollChanged();
- try {
- mWindowManager.removeViewImmediate(mPopupView);
- } finally {
- if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
- ((ViewGroup) mPopupView).removeView(mContentView);
- }
- mPopupView = null;
+ if (mExitTransition != null) {
+ mExitTransition.addTarget(mBackgroundView);
+ mExitTransition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transition.removeListener(this);
+ transition.removeTarget(mBackgroundView);
- if (mOnDismissListener != null) {
- mOnDismissListener.onDismiss();
- }
+ dismissImmediate();
+ }
+ });
+
+ TransitionManager.beginDelayedTransition(mDecorView, mExitTransition);
+
+ // Transition to invisible.
+ mBackgroundView.setVisibility(View.INVISIBLE);
+ } else {
+ dismissImmediate();
+ }
+ }
+ }
+
+ /**
+ * Removes the popup from the window manager and tears down the supporting
+ * view hierarchy, if necessary.
+ */
+ private void dismissImmediate() {
+ try {
+ mWindowManager.removeViewImmediate(mDecorView);
+ } finally {
+ mDecorView.removeView(mBackgroundView);
+ mDecorView = null;
+
+ if (mBackgroundView != mContentView) {
+ ((ViewGroup) mBackgroundView).removeView(mContentView);
+ }
+ mBackgroundView = null;
+
+ if (mOnDismissListener != null) {
+ mOnDismissListener.onDismiss();
}
}
}
/**
* Sets the listener to be called when the window is dismissed.
- *
+ *
* @param onDismissListener The listener.
*/
public void setOnDismissListener(OnDismissListener onDismissListener) {
mOnDismissListener = onDismissListener;
}
-
+
/**
* Updates the state of the popup window, if it is currently being displayed,
* from the currently set state. This includes:
@@ -1467,12 +1638,12 @@
if (!isShowing() || mContentView == null) {
return;
}
-
- WindowManager.LayoutParams p = (WindowManager.LayoutParams)
- mPopupView.getLayoutParams();
-
+
+ final WindowManager.LayoutParams p =
+ (WindowManager.LayoutParams) mDecorView.getLayoutParams();
+
boolean update = false;
-
+
final int newAnim = computeAnimationResource();
if (newAnim != p.windowAnimations) {
p.windowAnimations = newAnim;
@@ -1487,7 +1658,7 @@
if (update) {
setLayoutDirectionFromAnchor();
- mWindowManager.updateViewLayout(mPopupView, p);
+ mWindowManager.updateViewLayout(mDecorView, p);
}
}
@@ -1500,11 +1671,11 @@
* @param height the new height
*/
public void update(int width, int height) {
- WindowManager.LayoutParams p = (WindowManager.LayoutParams)
- mPopupView.getLayoutParams();
+ final WindowManager.LayoutParams p =
+ (WindowManager.LayoutParams) mDecorView.getLayoutParams();
update(p.x, p.y, width, height, false);
}
-
+
/**
* <p>Updates the position and the dimension of the popup window. Width and
* height can be set to -1 to update location only. Calling this function
@@ -1548,7 +1719,8 @@
return;
}
- WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
+ final WindowManager.LayoutParams p =
+ (WindowManager.LayoutParams) mDecorView.getLayoutParams();
boolean update = force;
@@ -1588,7 +1760,7 @@
if (update) {
setLayoutDirectionFromAnchor();
- mWindowManager.updateViewLayout(mPopupView, p);
+ mWindowManager.updateViewLayout(mDecorView, p);
}
}
@@ -1655,7 +1827,7 @@
}
final WindowManager.LayoutParams p =
- (WindowManager.LayoutParams) mPopupView.getLayoutParams();
+ (WindowManager.LayoutParams) mDecorView.getLayoutParams();
final int x = p.x;
final int y = p.y;
if (updateLocation) {
@@ -1694,7 +1866,7 @@
private void registerForScrollChanged(View anchor, int xoff, int yoff, int gravity) {
unregisterForScrollChanged();
- mAnchor = new WeakReference<View>(anchor);
+ mAnchor = new WeakReference<>(anchor);
ViewTreeObserver vto = anchor.getViewTreeObserver();
if (vto != null) {
vto.addOnScrollChangedListener(mOnScrollChangedListener);
@@ -1705,23 +1877,49 @@
mAnchoredGravity = gravity;
}
- private class PopupViewContainer extends FrameLayout {
- private static final String TAG = "PopupWindow.PopupViewContainer";
+ /**
+ * Layout listener used to run a transition immediately after a view is
+ * laid out. Forces the view to transition from invisible to visible.
+ */
+ private static class PostLayoutTransitionListener implements
+ ViewTreeObserver.OnGlobalLayoutListener {
+ private final ViewGroup mSceneRoot;
+ private final Transition mTransition;
- public PopupViewContainer(Context context) {
- super(context);
+ public PostLayoutTransitionListener(ViewGroup sceneRoot, Transition transition) {
+ mSceneRoot = sceneRoot;
+ mTransition = transition;
}
@Override
- protected int[] onCreateDrawableState(int extraSpace) {
- if (mAboveAnchor) {
- // 1 more needed for the above anchor state
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
- View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
- return drawableState;
- } else {
- return super.onCreateDrawableState(extraSpace);
+ public void onGlobalLayout() {
+ final ViewTreeObserver observer = mSceneRoot.getViewTreeObserver();
+ if (observer == null) {
+ // View has been detached.
+ return;
}
+
+ observer.removeOnGlobalLayoutListener(this);
+
+ // Set all targets to be initially invisible.
+ final List<View> targets = mTransition.getTargets();
+ final int N = targets.size();
+ for (int i = 0; i < N; i++) {
+ targets.get(i).setVisibility(View.INVISIBLE);
+ }
+
+ TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+
+ // Transition targets to visible.
+ for (int i = 0; i < N; i++) {
+ targets.get(i).setVisibility(View.VISIBLE);
+ }
+ }
+ }
+
+ private class PopupDecorView extends FrameLayout {
+ public PopupDecorView(Context context) {
+ super(context);
}
@Override
@@ -1731,15 +1929,14 @@
return super.dispatchKeyEvent(event);
}
- if (event.getAction() == KeyEvent.ACTION_DOWN
- && event.getRepeatCount() == 0) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ final KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null) {
state.startTracking(event, this);
}
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
+ final KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null && state.isTracking(event) && !event.isCanceled()) {
dismiss();
return true;
@@ -1763,7 +1960,7 @@
public boolean onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
-
+
if ((event.getAction() == MotionEvent.ACTION_DOWN)
&& ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
dismiss();
@@ -1775,17 +1972,22 @@
return super.onTouchEvent(event);
}
}
+ }
- /** @hide */
+ private class PopupBackgroundView extends FrameLayout {
+ public PopupBackgroundView(Context context) {
+ super(context);
+ }
+
@Override
- public void sendAccessibilityEventInternal(int eventType) {
- // clinets are interested in the content not the container, make it event source
- if (mContentView != null) {
- mContentView.sendAccessibilityEvent(eventType);
+ protected int[] onCreateDrawableState(int extraSpace) {
+ if (mAboveAnchor) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
+ return drawableState;
} else {
- super.sendAccessibilityEventInternal(eventType);
+ return super.onCreateDrawableState(extraSpace);
}
}
}
-
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 13d6b42..a282cf5 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -17,6 +17,7 @@
package android.widget;
import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -24,6 +25,7 @@
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Region.Op;
@@ -84,7 +86,17 @@
private static final int MONOSPACE = 3;
private Drawable mThumbDrawable;
+ private ColorStateList mThumbTintList = null;
+ private PorterDuff.Mode mThumbTintMode = null;
+ private boolean mHasThumbTint = false;
+ private boolean mHasThumbTintMode = false;
+
private Drawable mTrackDrawable;
+ private ColorStateList mTrackTintList = null;
+ private PorterDuff.Mode mTrackTintMode = null;
+ private boolean mHasTrackTint = false;
+ private boolean mHasTrackTintMode = false;
+
private int mThumbTextPadding;
private int mSwitchMinWidth;
private int mSwitchPadding;
@@ -473,6 +485,86 @@
}
/**
+ * Applies a tint to the track drawable. Does not modify the current
+ * tint mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setTrackDrawable(Drawable)} will
+ * automatically mutate the drawable and apply the specified tint and tint
+ * mode using {@link Drawable#setTintList(ColorStateList)}.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Switch_trackTint
+ * @see #getTrackTintList()
+ * @see Drawable#setTintList(ColorStateList)
+ */
+ public void setTrackTintList(@Nullable ColorStateList tint) {
+ mTrackTintList = tint;
+ mHasTrackTint = true;
+
+ applyTrackTint();
+ }
+
+ /**
+ * @return the tint applied to the track drawable
+ * @attr ref android.R.styleable#Switch_trackTint
+ * @see #setTrackTintList(ColorStateList)
+ */
+ @Nullable
+ public ColorStateList getTrackTintList() {
+ return mTrackTintList;
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by
+ * {@link #setTrackTintList(ColorStateList)}} to the track drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be
+ * {@code null} to clear tint
+ * @attr ref android.R.styleable#Switch_trackTintMode
+ * @see #getTrackTintMode()
+ * @see Drawable#setTintMode(PorterDuff.Mode)
+ */
+ public void setTrackTintMode(@Nullable PorterDuff.Mode tintMode) {
+ mTrackTintMode = tintMode;
+ mHasTrackTintMode = true;
+
+ applyTrackTint();
+ }
+
+ /**
+ * @return the blending mode used to apply the tint to the track
+ * drawable
+ * @attr ref android.R.styleable#Switch_trackTintMode
+ * @see #setTrackTintMode(PorterDuff.Mode)
+ */
+ @Nullable
+ public PorterDuff.Mode getTrackTintMode() {
+ return mTrackTintMode;
+ }
+
+ private void applyTrackTint() {
+ if (mTrackDrawable != null && (mHasTrackTint || mHasTrackTintMode)) {
+ mTrackDrawable = mTrackDrawable.mutate();
+
+ if (mHasTrackTint) {
+ mTrackDrawable.setTintList(mTrackTintList);
+ }
+
+ if (mHasTrackTintMode) {
+ mTrackDrawable.setTintMode(mTrackTintMode);
+ }
+
+ // The drawable (or one of its children) may not have been
+ // stateful before applying the tint, so let's try again.
+ if (mTrackDrawable.isStateful()) {
+ mTrackDrawable.setState(getDrawableState());
+ }
+ }
+ }
+
+ /**
* Set the drawable used for the switch "thumb" - the piece that the user
* can physically touch and drag along the track.
*
@@ -516,6 +608,86 @@
}
/**
+ * Applies a tint to the thumb drawable. Does not modify the current
+ * tint mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setThumbDrawable(Drawable)} will
+ * automatically mutate the drawable and apply the specified tint and tint
+ * mode using {@link Drawable#setTintList(ColorStateList)}.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Switch_thumbTint
+ * @see #getThumbTintList()
+ * @see Drawable#setTintList(ColorStateList)
+ */
+ public void setThumbTintList(@Nullable ColorStateList tint) {
+ mThumbTintList = tint;
+ mHasThumbTint = true;
+
+ applyThumbTint();
+ }
+
+ /**
+ * @return the tint applied to the thumb drawable
+ * @attr ref android.R.styleable#Switch_thumbTint
+ * @see #setThumbTintList(ColorStateList)
+ */
+ @Nullable
+ public ColorStateList getThumbTintList() {
+ return mThumbTintList;
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by
+ * {@link #setThumbTintList(ColorStateList)}} to the thumb drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be
+ * {@code null} to clear tint
+ * @attr ref android.R.styleable#Switch_thumbTintMode
+ * @see #getThumbTintMode()
+ * @see Drawable#setTintMode(PorterDuff.Mode)
+ */
+ public void setThumbTintMode(@Nullable PorterDuff.Mode tintMode) {
+ mThumbTintMode = tintMode;
+ mHasThumbTintMode = true;
+
+ applyThumbTint();
+ }
+
+ /**
+ * @return the blending mode used to apply the tint to the thumb
+ * drawable
+ * @attr ref android.R.styleable#Switch_thumbTintMode
+ * @see #setThumbTintMode(PorterDuff.Mode)
+ */
+ @Nullable
+ public PorterDuff.Mode getThumbTintMode() {
+ return mThumbTintMode;
+ }
+
+ private void applyThumbTint() {
+ if (mThumbDrawable != null && (mHasThumbTint || mHasThumbTintMode)) {
+ mThumbDrawable = mThumbDrawable.mutate();
+
+ if (mHasThumbTint) {
+ mThumbDrawable.setTintList(mThumbTintList);
+ }
+
+ if (mHasThumbTintMode) {
+ mThumbDrawable.setTintMode(mThumbTintMode);
+ }
+
+ // The drawable (or one of its children) may not have been
+ // stateful before applying the tint, so let's try again.
+ if (mThumbDrawable.isStateful()) {
+ mThumbDrawable.setState(getDrawableState());
+ }
+ }
+ }
+
+ /**
* Specifies whether the track should be split by the thumb. When true,
* the thumb's optical bounds will be clipped out of the track drawable,
* then the thumb will be drawn into the resulting gap.
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index aba4bd0..0eb52cb 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -800,7 +800,12 @@
if (args.niceName != null) {
String property = "wrap." + args.niceName;
if (property.length() > 31) {
- property = property.substring(0, 31);
+ // Avoid creating an illegal property name when truncating.
+ if (property.charAt(30) != '.') {
+ property = property.substring(0, 31);
+ } else {
+ property = property.substring(0, 30);
+ }
}
args.invokeWith = SystemProperties.get(property);
if (args.invokeWith != null && args.invokeWith.length() == 0) {
diff --git a/core/java/com/android/internal/transition/EpicenterClipReveal.java b/core/java/com/android/internal/transition/EpicenterClipReveal.java
new file mode 100644
index 0000000..d8a7f16
--- /dev/null
+++ b/core/java/com/android/internal/transition/EpicenterClipReveal.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.RectEvaluator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * EpicenterClipReveal captures the {@link View#getClipBounds()} before and
+ * after the scene change and animates between those and the epicenter bounds
+ * during a visibility transition.
+ */
+public class EpicenterClipReveal extends Visibility {
+ private static final String PROPNAME_CLIP = "android:epicenterReveal:clip";
+ private static final String PROPNAME_BOUNDS = "android:epicenterReveal:bounds";
+
+ public EpicenterClipReveal() {}
+
+ public EpicenterClipReveal(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ super.captureStartValues(transitionValues);
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ super.captureEndValues(transitionValues);
+ captureValues(transitionValues);
+ }
+
+ private void captureValues(TransitionValues values) {
+ final View view = values.view;
+ if (view.getVisibility() == View.GONE) {
+ return;
+ }
+
+ final Rect clip = view.getClipBounds();
+ values.values.put(PROPNAME_CLIP, clip);
+
+ if (clip == null) {
+ final Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
+ values.values.put(PROPNAME_BOUNDS, bounds);
+ }
+ }
+
+ @Override
+ public Animator onAppear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (endValues == null) {
+ return null;
+ }
+
+ final Rect start = getEpicenter();
+ final Rect end = getBestRect(endValues);
+
+ // Prepare the view.
+ view.setClipBounds(start);
+
+ return createRectAnimator(view, start, end);
+ }
+
+ @Override
+ public Animator onDisappear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (startValues == null) {
+ return null;
+ }
+
+ final Rect start = getBestRect(startValues);
+ final Rect end = getEpicenter();
+
+ // Prepare the view.
+ view.setClipBounds(start);
+
+ return createRectAnimator(view, start, end);
+ }
+
+ private Rect getBestRect(TransitionValues values) {
+ final Rect clipRect = (Rect) values.values.get(PROPNAME_CLIP);
+ if (clipRect == null) {
+ return (Rect) values.values.get(PROPNAME_BOUNDS);
+ }
+ return clipRect;
+ }
+
+ private Animator createRectAnimator(View view, Rect start, Rect end) {
+ final RectEvaluator evaluator = new RectEvaluator(new Rect());
+ return ObjectAnimator.ofObject(view, "clipBounds", evaluator, start, end);
+ }
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index cb9b421..1dd10e1 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -87,6 +87,7 @@
android_graphics_Canvas.cpp \
android_graphics_Picture.cpp \
android/graphics/AutoDecodeCancel.cpp \
+ android/graphics/AvoidXfermode.cpp \
android/graphics/Bitmap.cpp \
android/graphics/BitmapFactory.cpp \
android/graphics/Camera.cpp \
diff --git a/core/jni/android/graphics/AvoidXfermode.cpp b/core/jni/android/graphics/AvoidXfermode.cpp
new file mode 100644
index 0000000..9ca1f26
--- /dev/null
+++ b/core/jni/android/graphics/AvoidXfermode.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "AvoidXfermode.h"
+#include "SkColorPriv.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+#include "SkString.h"
+
+AvoidXfermode::AvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) {
+ if (tolerance > 255) {
+ tolerance = 255;
+ }
+ fTolerance = SkToU8(tolerance);
+ fOpColor = opColor;
+ fDistMul = (256 << 14) / (tolerance + 1);
+ fMode = mode;
+}
+
+SkFlattenable* AvoidXfermode::CreateProc(SkReadBuffer& buffer) {
+ const SkColor color = buffer.readColor();
+ const unsigned tolerance = buffer.readUInt();
+ const unsigned mode = buffer.readUInt();
+ return Create(color, tolerance, (Mode)mode);
+}
+
+void AvoidXfermode::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColor(fOpColor);
+ buffer.writeUInt(fTolerance);
+ buffer.writeUInt(fMode);
+}
+
+// returns 0..31
+static unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) {
+ SkASSERT(r <= SK_R16_MASK);
+ SkASSERT(g <= SK_G16_MASK);
+ SkASSERT(b <= SK_B16_MASK);
+
+ unsigned dr = SkAbs32(SkGetPackedR16(c) - r);
+ unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS);
+ unsigned db = SkAbs32(SkGetPackedB16(c) - b);
+
+ return SkMax32(dr, SkMax32(dg, db));
+}
+
+// returns 0..255
+static unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) {
+ SkASSERT(r <= 0xFF);
+ SkASSERT(g <= 0xFF);
+ SkASSERT(b <= 0xFF);
+
+ unsigned dr = SkAbs32(SkGetPackedR32(c) - r);
+ unsigned dg = SkAbs32(SkGetPackedG32(c) - g);
+ unsigned db = SkAbs32(SkGetPackedB32(c) - b);
+
+ return SkMax32(dr, SkMax32(dg, db));
+}
+
+static int scale_dist_14(int dist, uint32_t mul, uint32_t sub) {
+ int tmp = dist * mul - sub;
+ int result = (tmp + (1 << 13)) >> 14;
+
+ return result;
+}
+
+static inline unsigned Accurate255To256(unsigned x) {
+ return x + (x >> 7);
+}
+
+void AvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const {
+ unsigned opR = SkColorGetR(fOpColor);
+ unsigned opG = SkColorGetG(fOpColor);
+ unsigned opB = SkColorGetB(fOpColor);
+ uint32_t mul = fDistMul;
+ uint32_t sub = (fDistMul - (1 << 14)) << 8;
+
+ int MAX, mask;
+
+ if (kTargetColor_Mode == fMode) {
+ mask = -1;
+ MAX = 255;
+ } else {
+ mask = 0;
+ MAX = 0;
+ }
+
+ for (int i = 0; i < count; i++) {
+ int d = color_dist32(dst[i], opR, opG, opB);
+ // now reverse d if we need to
+ d = MAX + (d ^ mask) - mask;
+ SkASSERT((unsigned)d <= 255);
+ d = Accurate255To256(d);
+
+ d = scale_dist_14(d, mul, sub);
+ SkASSERT(d <= 256);
+
+ if (d > 0) {
+ if (aa) {
+ d = SkAlphaMul(d, Accurate255To256(*aa++));
+ if (0 == d) {
+ continue;
+ }
+ }
+ dst[i] = SkFourByteInterp256(src[i], dst[i], d);
+ }
+ }
+}
+
+static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) {
+ SkASSERT(scale <= 32);
+ scale <<= 3;
+
+ return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale),
+ SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale),
+ SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale));
+}
+
+void AvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const {
+ unsigned opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS);
+ unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
+ unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS);
+ uint32_t mul = fDistMul;
+ uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
+
+ int MAX, mask;
+
+ if (kTargetColor_Mode == fMode) {
+ mask = -1;
+ MAX = 31;
+ } else {
+ mask = 0;
+ MAX = 0;
+ }
+
+ for (int i = 0; i < count; i++) {
+ int d = color_dist16(dst[i], opR, opG, opB);
+ // now reverse d if we need to
+ d = MAX + (d ^ mask) - mask;
+ SkASSERT((unsigned)d <= 31);
+ // convert from 0..31 to 0..32
+ d += d >> 4;
+ d = scale_dist_14(d, mul, sub);
+ SkASSERT(d <= 32);
+
+ if (d > 0) {
+ if (aa) {
+ d = SkAlphaMul(d, Accurate255To256(*aa++));
+ if (0 == d) {
+ continue;
+ }
+ }
+ dst[i] = SkBlend3216(src[i], dst[i], d);
+ }
+ }
+}
+
+void AvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const {
+}
+
+#ifndef SK_IGNORE_TO_STRING
+void AvoidXfermode::toString(SkString* str) const {
+ str->append("AvoidXfermode: opColor: ");
+ str->appendHex(fOpColor);
+ str->appendf("distMul: %d ", fDistMul);
+
+ static const char* gModeStrings[] = { "Avoid", "Target" };
+
+ str->appendf("mode: %s", gModeStrings[fMode]);
+}
+#endif
diff --git a/core/jni/android/graphics/AvoidXfermode.h b/core/jni/android/graphics/AvoidXfermode.h
new file mode 100644
index 0000000..318d7be
--- /dev/null
+++ b/core/jni/android/graphics/AvoidXfermode.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef AvoidXfermode_DEFINED
+#define AvoidXfermode_DEFINED
+
+#include "SkColor.h"
+#include "SkTypes.h"
+#include "SkXfermode.h"
+
+/** \class AvoidXfermode
+
+ This xfermode will draw the src everywhere except on top of the specified
+ color.
+*/
+class AvoidXfermode : public SkXfermode {
+public:
+ enum Mode {
+ kAvoidColor_Mode, //!< draw everywhere except on the opColor
+ kTargetColor_Mode //!< draw only on top of the opColor
+ };
+
+ /** This xfermode draws, or doesn't draw, based on the destination's
+ distance from an op-color.
+
+ There are two modes, and each mode interprets a tolerance value.
+
+ Avoid: In this mode, drawing is allowed only on destination pixels that
+ are different from the op-color.
+ Tolerance near 0: avoid any colors even remotely similar to the op-color
+ Tolerance near 255: avoid only colors nearly identical to the op-color
+
+ Target: In this mode, drawing only occurs on destination pixels that
+ are similar to the op-color
+ Tolerance near 0: draw only on colors that are nearly identical to the op-color
+ Tolerance near 255: draw on any colors even remotely similar to the op-color
+ */
+ static AvoidXfermode* Create(SkColor opColor, U8CPU tolerance, Mode mode) {
+ return SkNEW_ARGS(AvoidXfermode, (opColor, tolerance, mode));
+ }
+
+ // overrides from SkXfermode
+ void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const override;
+ void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const override;
+ void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const override;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(AvoidXfermode)
+
+protected:
+ AvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
+ void flatten(SkWriteBuffer&) const override;
+
+private:
+ SkColor fOpColor;
+ uint32_t fDistMul; // x.14 cached from fTolerance
+ uint8_t fTolerance;
+ Mode fMode;
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
diff --git a/core/jni/android/graphics/Camera.cpp b/core/jni/android/graphics/Camera.cpp
index b572604..036ece1 100644
--- a/core/jni/android/graphics/Camera.cpp
+++ b/core/jni/android/graphics/Camera.cpp
@@ -96,7 +96,7 @@
}
static void Camera_applyToCanvas(JNIEnv* env, jobject obj, jlong canvasHandle) {
- SkCanvas* canvas = reinterpret_cast<android::Canvas*>(canvasHandle)->getSkCanvas();
+ SkCanvas* canvas = reinterpret_cast<android::Canvas*>(canvasHandle)->asSkCanvas();
jlong viewHandle = env->GetLongField(obj, gNativeInstanceFieldID);
Sk3DView* v = reinterpret_cast<Sk3DView*>(viewHandle);
v->applyToCanvas(canvas);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 9ea63aa..dde1393 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -366,7 +366,7 @@
if (!canvasHandle) {
return NULL;
}
- SkCanvas* c = reinterpret_cast<android::Canvas*>(canvasHandle)->getSkCanvas();
+ SkCanvas* c = reinterpret_cast<android::Canvas*>(canvasHandle)->asSkCanvas();
SkASSERT(c);
return c;
}
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 543323c..3f8bfe2 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -120,7 +120,7 @@
static void drawF(JNIEnv* env, jobject, jlong canvasHandle, jobject boundsRectF,
jlong bitmapHandle, jlong chunkHandle, jlong paintHandle,
jint destDensity, jint srcDensity) {
- SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->getSkCanvas();
+ SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->asSkCanvas();
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
@@ -139,7 +139,7 @@
static void drawI(JNIEnv* env, jobject, jlong canvasHandle, jobject boundsRect,
jlong bitmapHandle, jlong chunkHandle, jlong paintHandle,
jint destDensity, jint srcDensity) {
- SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->getSkCanvas();
+ SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->asSkCanvas();
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index c249012..12bfaa2 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -101,7 +101,7 @@
}
validate();
if (NULL != mPicture.get()) {
- mPicture.get()->playback(canvas->getSkCanvas());
+ mPicture.get()->playback(canvas->asSkCanvas());
}
}
diff --git a/core/jni/android/graphics/Xfermode.cpp b/core/jni/android/graphics/Xfermode.cpp
index 5a3883a..4a424ae 100644
--- a/core/jni/android/graphics/Xfermode.cpp
+++ b/core/jni/android/graphics/Xfermode.cpp
@@ -18,7 +18,7 @@
#include "GraphicsJNI.h"
#include "core_jni_helpers.h"
-#include "SkAvoidXfermode.h"
+#include "AvoidXfermode.h"
#include "SkPixelXorXfermode.h"
namespace android {
@@ -35,8 +35,8 @@
static jlong avoid_create(JNIEnv* env, jobject, jint opColor,
jint tolerance, jint modeHandle)
{
- SkAvoidXfermode::Mode mode = static_cast<SkAvoidXfermode::Mode>(modeHandle);
- return reinterpret_cast<jlong>(SkAvoidXfermode::Create(opColor, tolerance, mode));
+ AvoidXfermode::Mode mode = static_cast<AvoidXfermode::Mode>(modeHandle);
+ return reinterpret_cast<jlong>(AvoidXfermode::Create(opColor, tolerance, mode));
}
static jlong pixelxor_create(JNIEnv* env, jobject, jint opColor)
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 248a05e..50ed910 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -27,6 +27,8 @@
android:layout_weight="0"
android:gravity="center_vertical|start"
style="?attr/windowTitleBackgroundStyle" />
+ <View android:layout_width="match_parent"
+ android:layout_height="0dp" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/dialog_title_icons_material.xml b/core/res/res/layout/dialog_title_icons_material.xml
index 62af096..3866ca7 100644
--- a/core/res/res/layout/dialog_title_icons_material.xml
+++ b/core/res/res/layout/dialog_title_icons_material.xml
@@ -48,6 +48,9 @@
android:layout_marginStart="8dip" />
</LinearLayout>
+ <View android:layout_width="match_parent"
+ android:layout_height="0dp" />
+
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index 339d569..1ea7f6e 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -32,6 +32,8 @@
android:paddingStart="?attr/dialogPreferredPadding"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="@dimen/dialog_padding_top_material" />
+ <View android:layout_width="match_parent"
+ android:layout_height="0dp" />
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
diff --git a/core/res/res/transition/popup_window_enter.xml b/core/res/res/transition/popup_window_enter.xml
new file mode 100644
index 0000000..92d4c1e
--- /dev/null
+++ b/core/res/res/transition/popup_window_enter.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ android:transitionOrdering="together">
+ <transition class="com.android.internal.transition.EpicenterClipReveal"
+ android:interpolator="@android:interpolator/accelerate_cubic"
+ android:startDelay="50"
+ android:duration="300" />
+ <fade
+ android:interpolator="@android:interpolator/linear"
+ android:duration="100" />
+</transitionSet>
diff --git a/core/res/res/transition/popup_window_exit.xml b/core/res/res/transition/popup_window_exit.xml
new file mode 100644
index 0000000..5cb9f0b
--- /dev/null
+++ b/core/res/res/transition/popup_window_exit.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<fade xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/linear" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 415e6d5..7bc3390 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 uur gelede"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> uur gelede"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Afgelope <xliff:g id="COUNT">%d</xliff:g> dae"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Verlede maand"</string>
<string name="older" msgid="5211975022815554840">"Ouer"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android begin tans …"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimeer tans berging."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimeer program <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Begin programme."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Voltooi herlaai."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> loop"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-versoek is gewysig tot DIAL-versoek."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-versoek is gewysig tot USSD-versoek."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-versoek is gewysig tot nuwe SS-versoek."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index aafffe8..d8fef9b 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"ከ1 ሰዓት በፊት"</item>
<item quantity="other" msgid="2467273239587587569">"ከ <xliff:g id="COUNT">%d</xliff:g> ሰዓት በፊት"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"ቀኖች <xliff:g id="COUNT">%d</xliff:g> ያልቃል"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">" ያለፈው ወር"</string>
<string name="older" msgid="5211975022815554840">"የድሮ"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android በመጀመር ላይ ነው…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"ማከማቻን በማመቻቸት ላይ።"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"መተግበሪያዎች በአግባቡ በመጠቀም ላይ <xliff:g id="NUMBER_0">%1$d</xliff:g> ከ <xliff:g id="NUMBER_1">%2$d</xliff:g> ፡፡"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"አጨራረስ ማስነሻ፡፡"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> አሂድ"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ጥያቄ ወደ ደውል ጥያቄ ተሻሽሎዋል።"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ጥያቄ ወደ USSD ጥያቄ ተሻሽሎዋል።"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ጥያቄ ወደ አዲስ SS ጥያቄ ተሻሽሎዋል።"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 63340fc..f8c1bdb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"قبل ساعة واحدة"</item>
<item quantity="other" msgid="2467273239587587569">"قبل <xliff:g id="COUNT">%d</xliff:g> ساعات"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"آخر <xliff:g id="COUNT">%d</xliff:g> من الأيام"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"الشهر الماضي"</string>
<string name="older" msgid="5211975022815554840">"أقدم"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"جارٍ تشغيل Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"جارٍ تحسين السعة التخزينية."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"جارٍ تحسين التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"بدء التطبيقات."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"جارٍ إعادة التشغيل."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> يعمل"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"يتم تعديل الطلب SS لطلب الاتصال."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"يتم تعديل طلب SS إلى طلب USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"يتم تعديل طلب SS إلى طلب SS الجديد."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 2112d8a..c7fd56a 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Преди 1 час"</item>
<item quantity="other" msgid="2467273239587587569">"Преди <xliff:g id="COUNT">%d</xliff:g> часа"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Последните <xliff:g id="COUNT">%d</xliff:g> дни"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Последният месец"</string>
<string name="older" msgid="5211975022815554840">"По-стари"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android се стартира…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хранилището се оптимизира."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизира се приложение <xliff:g id="NUMBER_0">%1$d</xliff:g> от <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Приложенията се стартират."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Зареждането завършва."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> се изпълнява"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS заявката е променена на DIAL заявка."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS заявката е променена на USSD заявка."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS заявката е променена на нова SS заявка."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index f37b7fb..871453e 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"১ ঘন্টা আগে"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ঘন্টা আগে"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"গত <xliff:g id="COUNT">%d</xliff:g> দিনে"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"গত মাস"</string>
<string name="older" msgid="5211975022815554840">"পুরোনো"</string>
<plurals name="num_days_ago">
@@ -1259,7 +1257,7 @@
<string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
<string name="yes" msgid="5362982303337969312">"ঠিক আছে"</string>
<string name="no" msgid="5141531044935541497">"বাতিল করুন"</string>
- <string name="dialog_alert_title" msgid="2049658708609043103">"মনোযোগ"</string>
+ <string name="dialog_alert_title" msgid="2049658708609043103">"খেয়াল করুন"</string>
<string name="loading" msgid="7933681260296021180">"লোড হচ্ছে..."</string>
<string name="capital_on" msgid="1544682755514494298">"চালু করুন"</string>
<string name="capital_off" msgid="6815870386972805832">"বন্ধ করুন"</string>
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android চালু হচ্ছে…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"সঞ্চয়স্থান অপ্টিমাইজ করা হচ্ছে৷"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান অপ্টিমাইজ করা হচ্ছে৷"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> চলছে"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS অনুরোধটিকে ডায়াল অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS অনুরোধটিকে নতুন USSD অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS অনুরোধটিকে নতুন SS অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a2235fd..9b7b623 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Fa 1 hora"</item>
<item quantity="other" msgid="2467273239587587569">"Fa <xliff:g id="COUNT">%d</xliff:g> hores"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Els darrers <xliff:g id="COUNT">%d</xliff:g> dies"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"El mes passat"</string>
<string name="older" msgid="5211975022815554840">"Més antigues"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"S\'està iniciant Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"S\'està optimitzant l\'emmagatzematge."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"S\'està optimitzant l\'aplicació <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"S\'estan iniciant les aplicacions."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"S\'està finalitzant l\'actualització."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La sol·licitud SS s\'ha transformat en una sol·licitud DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La sol·licitud SS s\'ha transformat en una sol·licitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La sol·licitud SS s\'ha transformat en una sol·licitud SS nova."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index dc9eda2..4bf382b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"před 1 h"</item>
<item quantity="other" msgid="2467273239587587569">"před <xliff:g id="COUNT">%d</xliff:g> h"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Posledních <xliff:g id="COUNT">%d</xliff:g> dnů"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Poslední měsíc"</string>
<string name="older" msgid="5211975022815554840">"Starší"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Spouštění systému Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Probíhá optimalizace úložiště."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimalizování aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Spouštění aplikací."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončování inicializace."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Běží aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Požadavek SS byl změněn na požadavek DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Požadavek SS byl změněn na požadavek USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Požadavek SS byl změněn na nový požadavek SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 1a412c1..dbdbfa4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"for 1 time siden"</item>
<item quantity="other" msgid="2467273239587587569">"for <xliff:g id="COUNT">%d</xliff:g> timer siden"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Seneste <xliff:g id="COUNT">%d</xliff:g> dage"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Seneste måned"</string>
<string name="older" msgid="5211975022815554840">"Ældre"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android starter..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lageret optimeres."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerer app <xliff:g id="NUMBER_0">%1$d</xliff:g> ud af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Åbner dine apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Gennemfører start."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> er i gang"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-anmodningen er ændret til en DIAL-anmodning."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-anmodningen er ændret til en USSD-anmodning."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-anmodningen er ændret til en ny SS-anmodning."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 56dd21e..50aedee 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"vor 1 Stunde"</item>
<item quantity="other" msgid="2467273239587587569">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Letzte <xliff:g id="COUNT">%d</xliff:g> Tage"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Letzter Monat"</string>
<string name="older" msgid="5211975022815554840">"Älter"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android wird gestartet…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Speicher wird optimiert"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-Anfrage wird in DIAL-Anfrage geändert."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-Anfrage wird in USSD-Anfrage geändert."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-Anfrage wird in neue SS-Anfrage geändert."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 737cc1f..943a862 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -45,7 +45,7 @@
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Αυτόματος τηλεφωνητής"</string>
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"Πρόβλημα σύνδεσης ή μη έγκυρος κώδικας MMI."</string>
- <string name="mmiFdnError" msgid="5224398216385316471">"Η λειτουργία περιορίζεται μόνο σε καθορισμένους αριθμούς κλήσης."</string>
+ <string name="mmiFdnError" msgid="5224398216385316471">"Η λειτουργία περιορίζεται μόνο σε προκαθορισμένους αριθμούς κλήσης."</string>
<string name="serviceEnabled" msgid="8147278346414714315">"Η υπηρεσία ενεργοποιήθηκε."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Η υπηρεσία ενεργοποιήθηκε για:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Η υπηρεσία έχει απενεργοποιηθεί."</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"πριν από 1 ώρα"</item>
<item quantity="other" msgid="2467273239587587569">"πριν από <xliff:g id="COUNT">%d</xliff:g> ώρες"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Τελευταίες <xliff:g id="COUNT">%d</xliff:g> ημέρες"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Τελευταίος μήνας"</string>
<string name="older" msgid="5211975022815554840">"Παλαιότερα"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Εκκίνηση Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Βελτιστοποίηση αποθηκευτικού χώρου."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Βελτιστοποίηση της εφαρμογής <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Έναρξη εφαρμογών."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Ολοκλήρωση εκκίνησης."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Το αίτημα SS τροποποιήθηκε σε αίτημα DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Το αίτημα SS τροποποιήθηκε σε αίτημα USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Το αίτημα SS τροποποιήθηκε σε νέο αίτημα SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index df8b41f..ef70c92 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 hour ago"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> hours ago"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Last <xliff:g id="COUNT">%d</xliff:g> days"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Last month"</string>
<string name="older" msgid="5211975022815554840">"Older"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index df8b41f..ef70c92 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 hour ago"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> hours ago"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Last <xliff:g id="COUNT">%d</xliff:g> days"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Last month"</string>
<string name="older" msgid="5211975022815554840">"Older"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a9353db..ca1a30b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Hace 1 hora."</item>
<item quantity="other" msgid="2467273239587587569">"Hace <xliff:g id="COUNT">%d</xliff:g> horas."</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Últimos <xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Último mes"</string>
<string name="older" msgid="5211975022815554840">"Antiguos"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Iniciando Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando la aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando el inicio"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La solicitud SS cambió por una solicitud DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La solicitud SS cambió por una solicitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La solicitud SS cambió por una nueva solicitud SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 96856c0..141b9ea 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Hace 1 hora"</item>
<item quantity="other" msgid="2467273239587587569">"Hace <xliff:g id="COUNT">%d</xliff:g> horas"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Últimos <xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"El mes pasado"</string>
<string name="older" msgid="5211975022815554840">"Anterior"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android se está iniciando…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio..."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La solicitud SS se ha modificado para la solicitud DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La solicitud SS se ha modificado para la solicitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La solicitud SS se ha modificado para la nueva solicitud SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index ccb7b9f..55bb0fb 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 tund tagasi"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> tundi tagasi"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Viimased <xliff:g id="COUNT">%d</xliff:g> päeva"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Eelmisel kuul"</string>
<string name="older" msgid="5211975022815554840">"Vanem"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android käivitub ..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Salvestusruumi optimeerimine."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. rakenduse <xliff:g id="NUMBER_1">%2$d</xliff:g>-st optimeerimine."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Rakenduste käivitamine."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Käivitamise lõpuleviimine."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> töötab"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-päring muudeti DIAL-päringuks."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-päring muudeti USSD-päringuks."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-päring muudeti uueks SS-päringuks."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 51e9fee..2b1029b 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Duela ordubete"</item>
<item quantity="other" msgid="2467273239587587569">"duela <xliff:g id="COUNT">%d</xliff:g> ordu"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"azken <xliff:g id="COUNT">%d</xliff:g> egunak"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Azken hilabetea"</string>
<string name="older" msgid="5211975022815554840">"Zaharragoa"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android abiarazten ari da…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Memoria optimizatzen."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> aplikazio optimizatzen."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Bertsio-berritzea amaitzen."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS eskaera DIAL eskaerara aldatu da."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS eskaera USSD eskaerara aldatu da."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS eskaera SS eskaera berrira aldatu da."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b04d53c..e5ca49a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"۱ ساعت قبل"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ساعت قبل"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> روز گذشته"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"ماه گذشته"</string>
<string name="older" msgid="5211975022815554840">"قدیمی تر"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android در حال راهاندازی است..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"بهینهسازی فضای ذخیرهسازی."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"در حال بهینهسازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامهها."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"در حال اتمام راهاندازی."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"درخواست SS به درخواست DIAL اصلاح میشود."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"درخواست SS به درخواست USSD اصلاح میشود."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"درخواست SS به درخواست SS جدید اصلاح میشود."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 49dd96f..af70269 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 tunti sitten"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> tuntia sitten"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Viimeisen <xliff:g id="COUNT">%d</xliff:g> päivän aikana"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Viime kuussa"</string>
<string name="older" msgid="5211975022815554840">"Vanhemmat"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android käynnistyy…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimoidaan tallennustilaa."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimoidaan sovellusta <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Käynnistetään sovelluksia."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Viimeistellään päivitystä."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> käynnissä"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-pyyntö muutettiin DIAL-pyynnöksi."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-pyyntö muutettiin USSD-pyynnöksi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-pyyntö muutettiin uudeksi SS-pyynnöksi."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index df8d9c1..43c9c51 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Il y a 1 heure"</item>
<item quantity="other" msgid="2467273239587587569">"il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Les <xliff:g id="COUNT">%d</xliff:g> derniers jours"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Le mois dernier"</string>
<string name="older" msgid="5211975022815554840">"Précédent"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android en cours de démarrage..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La demande SS a été modifiée et est maintenant une demande DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La demande SS a été modifiée et est maintenant une demande USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La demande SS a été modifiée et est maintenant une nouvelle demande SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1945e78..aa488a3 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"il y a 1 heure"</item>
<item quantity="other" msgid="2467273239587587569">"Il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Les <xliff:g id="COUNT">%d</xliff:g> derniers jours"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Le mois dernier"</string>
<string name="older" msgid="5211975022815554840">"Préc."</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Démarrage d\'Android en cours"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage en cours…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La requête SS a été remplacée par une requête DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La requête SS a été remplacée par une requête USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La requête SS a été remplacée par une autre requête SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 78d223c..c9da201 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Hai 1 hora"</item>
<item quantity="other" msgid="2467273239587587569">"hai <xliff:g id="COUNT">%d</xliff:g> horas"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Últimos <xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"O mes pasado"</string>
<string name="older" msgid="5211975022815554840">"Antes"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Estase iniciando Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamento."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicacións."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Está finalizando o arranque"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> está en execución"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"A solicitude SS transformouse nunha solicitude DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitude SS transformouse nunha solicitude USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitude SS transformouse nunha nova solicitude SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d17a5cb..626680c 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -71,7 +71,7 @@
<string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर ID"</string>
<string name="ColpMmi" msgid="3065121483740183974">"कनेक्ट किया गया लाइन आईडी"</string>
<string name="ColrMmi" msgid="4996540314421889589">"कनेक्ट किया गया लाइन आईडी प्रतिबंध"</string>
- <string name="CfMmi" msgid="5123218989141573515">"कॉल अग्रेषण"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"कॉल आगे भेजना"</string>
<string name="CwMmi" msgid="9129678056795016867">"कॉल प्रतीक्षा"</string>
<string name="BaMmi" msgid="455193067926770581">"कॉल बाधित करना"</string>
<string name="PwdMmi" msgid="7043715687905254199">"पासवर्ड बदलें"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 घंटे पहले"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> घंटे पहले"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"अंतिम <xliff:g id="COUNT">%d</xliff:g> दिन"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"पिछला माह"</string>
<string name="older" msgid="5211975022815554840">"इससे पुराना"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android प्रारंभ हो रहा है…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"मेमोरी ऑप्टिमाइज़ हो रही है."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप्स अनुकूलित हो रहा है."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ऐप्स प्रारंभ होने वाले हैं"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त हो रहा है."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चल रही है"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS अनुरोध को DIAL अनुरोध में बदल दिया गया है."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध को USSD अनुरोध में बदल दिया गया है."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध को नए SS अनुरोध में बदल दिया गया है."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 21c9938a..b550029 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Prije 1 sata"</item>
<item quantity="other" msgid="2467273239587587569">"Prije <xliff:g id="COUNT">%d</xliff:g> h"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Posljednjih ovoliko dana: <xliff:g id="COUNT">%d</xliff:g>"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Prošli mjesec"</string>
<string name="older" msgid="5211975022815554840">"Starije"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Pokretanje Androida..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje pohrane."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Završetak inicijalizacije."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Izvodi se <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS zahtjev izmijenjen je u DIAL zahtjev."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS zahtjev izmijenjen je u USSD zahtjev."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS zahtjev izmijenjen je u novi SS zahtjev."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 978d115..ab9391a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -56,7 +56,7 @@
<string name="badPin" msgid="9015277645546710014">"A megadott régi PIN kód helytelen."</string>
<string name="badPuk" msgid="5487257647081132201">"A megadott PUK kód helytelen."</string>
<string name="mismatchPin" msgid="609379054496863419">"A beírt PIN kódok nem egyeznek."</string>
- <string name="invalidPin" msgid="3850018445187475377">"Írjon be egy 4-8 számjegyű PIN-kódot."</string>
+ <string name="invalidPin" msgid="3850018445187475377">"Írjon be egy 4-8 számjegyű PIN kódot."</string>
<string name="invalidPuk" msgid="8761456210898036513">"8 számjegyű vagy hosszabb PUK kódot írjon be."</string>
<string name="needPuk" msgid="919668385956251611">"A SIM kártya le van zárva a PUK kóddal. A feloldáshoz adja meg a PUK kódot."</string>
<string name="needPuk2" msgid="4526033371987193070">"A SIM kártya feloldásához adja meg a PUK2 kódot."</string>
@@ -75,7 +75,7 @@
<string name="CwMmi" msgid="9129678056795016867">"Hívásvárakoztatás"</string>
<string name="BaMmi" msgid="455193067926770581">"Hívásletiltás"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Jelszómódosítás"</string>
- <string name="PinMmi" msgid="3113117780361190304">"PIN-kód módosítása"</string>
+ <string name="PinMmi" msgid="3113117780361190304">"PIN kód módosítása"</string>
<string name="CnipMmi" msgid="3110534680557857162">"Szám hívása"</string>
<string name="CnirMmi" msgid="3062102121430548731">"Hívószám korlátozva"</string>
<string name="ThreeWCMmi" msgid="9051047170321190368">"Háromutas hívás"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 órája"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> órája"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Elmúlt <xliff:g id="COUNT">%d</xliff:g> napban"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Múlt hónapban"</string>
<string name="older" msgid="5211975022815554840">"Régebbi"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Az Android indítása…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tárhely-optimalizálás."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Alkalmazás optimalizálása: <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Kezdő alkalmazások."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Rendszerindítás befejezése."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Az SS-kérés módosítva DIAL-kérésre."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Az SS-kérés módosítva USSD-kérésre."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Az SS-kérés módosítva új SS-kérésre."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 101a726..a511a15 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -22,8 +22,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Բ"</string>
<string name="kilobyteShort" msgid="5973789783504771878">"Կբ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Մբ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Գբ"</string>
+ <string name="megabyteShort" msgid="6355851576770428922">"ՄԲ"</string>
+ <string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string>
<string name="terabyteShort" msgid="231613018159186962">"Տբ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
<string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ժամ առաջ"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ժամ առաջ"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Վերջին <xliff:g id="COUNT">%d</xliff:g> օրերին"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Անցյալ ամիս"</string>
<string name="older" msgid="5211975022815554840">"Ավելի հին"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android-ը մեկնարկում է…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Պահեստի օպտիմալացում:"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Օպտիմալացվում է հավելված <xliff:g id="NUMBER_0">%1$d</xliff:g>-ը <xliff:g id="NUMBER_1">%2$d</xliff:g>-ից:"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Հավելվածները մեկնարկում են:"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Բեռնումն ավարտվում է:"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>-ն աշխատում է"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS հարցումը փոխվել է DIAL հարցման:"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS հարցումը փոխվել է USSD հարցման:"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS հարցումը փոխվել է նոր SS հարցման:"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 085939a..7044187 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 jam yang lalu"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> jam yang lalu"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> hari terakhir"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Bulan lalu"</string>
<string name="older" msgid="5211975022815554840">"Lawas"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Memulai Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimalkan penyimpanan."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimalkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Menyelesaikan boot."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Permintaan SS diubah menjadi permintaan DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Permintaan SS diubah menjadi permintaan USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Permintaan SS diubah menjadi permintaan SS baru."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 2839911..e95735c 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"fyrir klukkustund"</item>
<item quantity="other" msgid="2467273239587587569">"fyrir <xliff:g id="COUNT">%d</xliff:g> klukkustundum"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Síðustu <xliff:g id="COUNT">%d</xliff:g> daga"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Í síðasta mánuði"</string>
<string name="older" msgid="5211975022815554840">"Eldra"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android er að ræsast…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Fínstillir geymslu."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Fínstillir forrit <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ræsir forrit."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Lýkur ræsingu."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> er í gangi"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-beiðni er breytt í DIAL-beiðni."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-beiðni er breytt í USSD-beiðni."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-beiðni er breytt í nýja SS-beiðni."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e1f1d7c..cdff278 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ora fa"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ore fa"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Ultimi <xliff:g id="COUNT">%d</xliff:g> giorni"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Ultimo mese"</string>
<string name="older" msgid="5211975022815554840">"Precedente"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Avvio di Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ottimizzazione archiviazione."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ottimizzazione applicazione <xliff:g id="NUMBER_0">%1$d</xliff:g> di <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Avvio applicazioni."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Conclusione dell\'avvio."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> in esecuzione"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"La richiesta SS è stata modificata in richiesta DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La richiesta SS è stata modificata in richiesta USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La richiesta SS è stata modificata in nuova richiesta SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 196a774..b1e2aba1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"לפני שעה"</item>
<item quantity="other" msgid="2467273239587587569">"לפני <xliff:g id="COUNT">%d</xliff:g> שעות"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> הימים האחרונים"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"בחודש שעבר"</string>
<string name="older" msgid="5211975022815554840">"ישן יותר"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"הפעלת Android מתחילה…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"מתבצעת אופטימיזציה של האחסון."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"מבצע אופטימיזציה של אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"מפעיל אפליקציות."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"מסיים אתחול."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> פועל"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"בקשת SS שונתה לבקשת DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"בקשת SS שונתה לבקשת USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"בקשת SS שונתה לבקשת SS חדשה."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 67b72d4..7e22f2e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1時間前"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g>時間前"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"過去<xliff:g id="COUNT">%d</xliff:g>日間"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"先月"</string>
<string name="older" msgid="5211975022815554840">"もっと前"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Androidの起動中…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"ストレージを最適化しています。"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>個中<xliff:g id="NUMBER_0">%1$d</xliff:g>個のアプリを最適化しています。"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"アプリを起動しています。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ブートを終了しています。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>を実行中"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SSリクエストはDIALリクエストに変更されました。"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SSリクエストはUSSDリクエストに変更されました。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SSリクエストは新しいSSリクエストに変更されました。"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 9ab84bef4..919d263 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 საათის წინ"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> საათის წინ"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"ბოლო <xliff:g id="COUNT">%d</xliff:g> დღე"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"გასული თვე"</string>
<string name="older" msgid="5211975022815554840">"უფრო ძველი"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android იწყება…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"მეხსიერების ოპტიმიზირება."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"მიმდინარეობს აპლიკაციების ოპტიმიზაცია. დასრულებულია <xliff:g id="NUMBER_0">%1$d</xliff:g>, სულ <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"აპების ჩართვა"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ჩატვირთვის დასასრული."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> გაშვებულია"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS მოთხოვნა შეიცვალა DIAL მოთხოვნით."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS მოთხოვნა შეიცვალა USSD მოთხოვნით."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS მოთხოვნა შეიცვალა ახალი SS მოთხოვნით."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 255fedc..432f98c 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 сағат бұрын"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> сағат бұрын"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Соңғы <xliff:g id="COUNT">%d</xliff:g> күнде"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Соңғы ай"</string>
<string name="older" msgid="5211975022815554840">"Ескілеу"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android іске қосылуда…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Қойманы оңтайландыру."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ішінен <xliff:g id="NUMBER_0">%1$d</xliff:g> қолданба оңтайландырылуда."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Қолданбалар іске қосылуда."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Қосуды аяқтауда."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> қосылған"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS сұрауы DIAL сұрауына өзгертілді."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS сұрауы USSD сұрауына өзгертілді."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS сұрауы жаңа SS сұрауына өзгертілді."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index f8e88f5..a320a22 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"១ ម៉ោងមុន"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ម៉ោងមុន"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃចុងក្រោយ"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"ខែមុន"</string>
<string name="older" msgid="5211975022815554840">"ចាស់ជាង"</string>
<plurals name="num_days_ago">
@@ -1305,6 +1303,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android កំពុងចាប់ផ្ដើម…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"កំពុងធ្វើឲ្យឧបករណ៍ផ្ទុកមានប្រសិទ្ធភាព។"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"ធ្វើឲ្យកម្មវិធីប្រសើរឡើង <xliff:g id="NUMBER_0">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_1">%2$d</xliff:g> ។"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ចាប់ផ្ដើមកម្មវិធី។"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"បញ្ចប់ការចាប់ផ្ដើម។"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> កំពុងដំណើរការ"</string>
@@ -1881,4 +1881,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរការហៅទូរស័ព្ទ។"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ USSD។"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ SS ថ្មី។"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 0d18fce..02fdbd0 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ಗಂಟೆ ಹಿಂದೆ"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ಗಂಟೆಗಳ ಹಿಂದೆ"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"ಕಳೆದ <xliff:g id="COUNT">%d</xliff:g> ದಿನಗಳಲ್ಲಿ"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"ಕಳೆದ ತಿಂಗಳು"</string>
<string name="older" msgid="5211975022815554840">"ಹಳೆಯದು"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"ಸಂಗ್ರಹಣೆಯನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ಬೂಟ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ವಿನಂತಿಯನ್ನು DIAL ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ವಿನಂತಿಯನ್ನು USSD ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ವಿನಂತಿಯನ್ನು ಹೊಸ SS ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c52c351..b36f943 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1시간 전"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g>시간 전"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"지난 <xliff:g id="COUNT">%d</xliff:g>일"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"지난 달"</string>
<string name="older" msgid="5211975022815554840">"이전"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android가 시작되는 중…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"저장소 최적화 중"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"앱 <xliff:g id="NUMBER_1">%2$d</xliff:g>개 중 <xliff:g id="NUMBER_0">%1$d</xliff:g>개 최적화 중"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"앱을 시작하는 중입니다."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"부팅 완료"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> 실행 중"</string>
@@ -1881,4 +1881,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS 요청이 DIAL 요청으로 수정됩니다."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 요청이 USSD 요청으로 수정됩니다."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 요청이 새로운 SS 요청으로 수정됩니다."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 2b45690..aaf4c88 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1479,6 +1479,7 @@
<!-- no translation found for num_minutes_ago:other (2176942008915455116) -->
<!-- no translation found for num_hours_ago:one (9150797944610821849) -->
<!-- no translation found for num_hours_ago:other (2467273239587587569) -->
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<!-- no translation found for last_num_days:other (3069992808164318268) -->
<!-- no translation found for last_month (3959346739979055432) -->
<skip />
@@ -1661,6 +1662,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android жүргүзүлүүдө…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Сактагыч ыңгайлаштырылууда."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Колдонмолорду иштетип баштоо"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Жүктөө аякталууда."</string>
<!-- no translation found for heavy_weight_notification (9087063985776626166) -->
@@ -2357,4 +2360,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS сурамы DIAL сурамына өзгөртүлдү."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS сурамы USSD сурамына өзгөртүлдү."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS сурамы жаңы SS сурамына өзгөртүлдү."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index ed47bbb..7b20179 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ຊົ່ວໂມງກ່ອນໜ້ານີ້"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງທີ່ຜ່ານມາ"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ມື້ທີ່ຜ່ານມາ"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"ເດືອນແລ້ວ"</string>
<string name="older" msgid="5211975022815554840">"ເກົ່າກວ່າ"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"ກຳລັງເລີ່ມລະບົບ Android …"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"ການປັບບ່ອນເກັບຂໍ້ມູນໃຫ້ເໝາະສົມ."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"ກຳລັງປັບປຸງປະສິດທິພາບແອັບຯທີ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="NUMBER_1">%2$d</xliff:g> ແອັບຯ."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ກຳລັງເປີດແອັບຯ."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກ"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"ການຂໍ SS ຖືກດັດແປງເປັນການຂໍ DIAL ແລ້ວ."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"ການຂໍ SS ຖືກດັດແປງເປັນການຂໍ USSD ແລ້ວ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"ການຂໍ SS ຖືກດັດແປງເປັນການຂໍ SS ໃໝ່ແລ້ວ."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f22ddea..99595ec 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Prieš 1 valandą"</item>
<item quantity="other" msgid="2467273239587587569">"Prieš <xliff:g id="COUNT">%d</xliff:g> val."</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Paskutinės <xliff:g id="COUNT">%d</xliff:g> dienos (-ų)"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Paskutinį mėnesį"</string>
<string name="older" msgid="5211975022815554840">"Senesni"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Paleidžiama „Android“…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizuojama saugykla."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizuojama <xliff:g id="NUMBER_0">%1$d</xliff:g> progr. iš <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Paleidžiamos programos."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Užbaigiamas paleidimas."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Vykdoma „<xliff:g id="APP">%1$s</xliff:g>“"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS užklausa pakeista į DIAL užklausą."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS užklausa pakeista į USSD užklausą."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS užklausa pakeista į naują SS užklausą."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1c1f0c5..05837d6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Pirms 1 stundas"</item>
<item quantity="other" msgid="2467273239587587569">"Pirms <xliff:g id="COUNT">%d</xliff:g> stundas(-ām)"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Pēdējās <xliff:g id="COUNT">%d</xliff:g> dienās"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Iepriekšējā mēnesī"</string>
<string name="older" msgid="5211975022815554840">"Vecāks"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Notiek Android palaišana…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Notiek krātuves optimizēšana."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Tiek optimizēta <xliff:g id="NUMBER_0">%1$d</xliff:g>. lietotne no <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Notiek lietotņu palaišana."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Tiek pabeigta sāknēšana."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> darbojas"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS pieprasījums ir mainīts uz DIAL pieprasījumu."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS pieprasījums ir mainīts uz USSD pieprasījumu."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS pieprasījums ir mainīts uz jaunu SS pieprasījumu."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index df4b13b..b77d0de 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Пред 1 час"</item>
<item quantity="other" msgid="2467273239587587569">"пред <xliff:g id="COUNT">%d</xliff:g> часа"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Последните <xliff:g id="COUNT">%d</xliff:g> дена"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Минатиот месец"</string>
<string name="older" msgid="5211975022815554840">"Постари"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android стартува…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизирање на складирањето."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Се оптимизира апликација <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Се стартуваат апликациите."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Подигањето завршува."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> работи"</string>
@@ -1881,4 +1881,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Барањето SS е изменето во барање DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Барањето SS е изменето во барање USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Барањето SS е изменето во ново барање SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index b9bfa99..862b1b9 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 മണിക്കൂര് മുമ്പ്"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> മണിക്കൂർ മുമ്പ്"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"കഴിഞ്ഞ <xliff:g id="COUNT">%d</xliff:g> ദിവസം"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"കഴിഞ്ഞ മാസം"</string>
<string name="older" msgid="5211975022815554840">"പഴയത്"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android ആരംഭിക്കുന്നു…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"സംഭരണം ഒപ്റ്റിമൈസ് ചെയ്യുന്നു."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> അപ്ലിക്കേഷൻ ഓപ്റ്റിമൈസ് ചെയ്യുന്നു."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ബൂട്ട് ചെയ്യൽ പൂർത്തിയാകുന്നു."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> പ്രവർത്തിക്കുന്നു"</string>
@@ -1877,4 +1877,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS അഭ്യർത്ഥന, DIAL അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS അഭ്യർത്ഥന, USSD അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS അഭ്യർത്ഥന, പുതിയ SS അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index a14588d..3db7b83 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 цагийн өмнө"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> цагийн өмнө"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Сүүлийн <xliff:g id="COUNT">%d</xliff:g> өдөр"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Сүүлийн сар"</string>
<string name="older" msgid="5211975022815554840">"Хуучин"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Андройд эхэлж байна..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хадгалалтыг сайжруулж байна."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>-н <xliff:g id="NUMBER_0">%1$d</xliff:g> апп-г тохируулж байна."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Апп-г эхлүүлж байна."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Эхлэлийг дуусгаж байна."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ажиллаж байна"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS хүсэлтийг DIAL хүсэлт болгон өөрчилсөн байна"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS хүсэлтийг USSD хүсэлт болгон өөрчилсөн байна."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS хүсэлтийг шинэ SS хүсэлт болгон өөрчилсөн байна."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 55daa3a..58f80de 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -218,7 +218,7 @@
<string name="permgroupdesc_location" msgid="5704679763124170100">"आपल्या प्रत्यक्ष स्थानाचे परीक्षण करेल."</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"नेटवर्क संप्रेषण"</string>
<string name="permgroupdesc_network" msgid="4478299413241861987">"विविध नेटवर्क वैशिष्ट्यांवर प्रवेश करेल."</string>
- <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ब"</string>
+ <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ब्लूटुथ"</string>
<string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ब द्वारे डिव्हाइसेसवर आणि नेटवर्कवर प्रवेश करेल."</string>
<string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ऑडिओ सेटिंग्ज"</string>
<string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ऑडिओ सेटिंग्ज बदला."</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 तासापूर्वी"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> तासांपूर्वी"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"अंतिम <xliff:g id="COUNT">%d</xliff:g> दिवस"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"अंतिम महिना"</string>
<string name="older" msgid="5211975022815554840">"अधिक जुने"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android प्रारंभ करत आहे…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"संचयन ऑप्टिमाइझ करत आहे."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप ऑप्टिमाइझ करत आहे."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त होत आहे."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चालत आहे"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS विनंती डायल विनंतीवर सुधारित केली आहे."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS विनंती USSD विनंतीवर सुधारित केली आहे."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS विनंती नवीन SS विनंतीवर सुधारित केली आहे."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 7ec40c4..eb92846 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 jam yang lalu"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> jam yang lalu"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> hari terakhir"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Bulan lepas"</string>
<string name="older" msgid="5211975022815554840">"Lebih lama"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android sedang dimulakan…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimumkan storan."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"But akhir."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> dijalankan"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Permintaan SS diubah kepada permintaan DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Permintaan SS diubah kepada permintaan USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Permintaan SS diubah kepada permintaan SS baharu."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 6e0b5ad..94d080d 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"လွနခဲ့သော ၁နာရီက"</item>
<item quantity="other" msgid="2467273239587587569">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> နာရီက"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"ပြီးခဲ့သော<xliff:g id="COUNT">%d</xliff:g>ရက်က"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"ပြီးခဲ့သောလ"</string>
<string name="older" msgid="5211975022815554840">"ယခင်က"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android စတင်နေ…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"သိုလှောင်မှုအား ပြုပြင်ခြင်း။"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> ထဲက app<xliff:g id="NUMBER_1">%2$d</xliff:g>ကို ဆီလျော်အောင် လုပ်နေ"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"appများကို စတင်နေ"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> က အလုပ်လုပ်နေသည်"</string>
@@ -1877,4 +1877,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"DIAL တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"USSD တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index dc38563..d6288e4 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"for en time siden"</item>
<item quantity="other" msgid="2467273239587587569">"for <xliff:g id="COUNT">%d</xliff:g> timer siden"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Siste <xliff:g id="COUNT">%d</xliff:g> dager"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Forrige måned"</string>
<string name="older" msgid="5211975022815554840">"Eldre"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android starter …"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimaliser lagring."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimaliserer app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starter apper."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Ferdigstiller oppstart."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> kjører"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-forespørselen er endret til en RINGE-forespørsel."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-forespørselen er endret til en USSD-forespørsel."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-forespørselen er endret til en ny SS-forespørsel."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index fb8e1c2..76c2642 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"१ घन्टा अघि"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> घन्टा अघि"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"अन्तिम <xliff:g id="COUNT">%d</xliff:g> दिन"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"अन्तिम महिना"</string>
<string name="older" msgid="5211975022815554840">"पुरानो"</string>
<plurals name="num_days_ago">
@@ -1309,6 +1307,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android शुरू हुँदैछ..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"भण्डारण अनुकूलन गर्दै।"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"अनुप्रयोग अनुकुल हुँदै <xliff:g id="NUMBER_0">%1$d</xliff:g> को <xliff:g id="NUMBER_1">%2$d</xliff:g>।"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"सुरुवात अनुप्रयोगहरू।"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बुट पुरा हुँदै।"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चलिरहेको छ"</string>
@@ -1885,4 +1885,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS अनुरोध DIAL अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध USSD अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध नयाँ SS अनुरोधमा परिमार्जन गरिएको छ।"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 75f4a74..1c02a40 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 uur geleden"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> uur geleden"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Afgelopen <xliff:g id="COUNT">%d</xliff:g> dagen"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Afgelopen maand"</string>
<string name="older" msgid="5211975022815554840">"Ouder"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android wordt gestart…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Opslagruimte wordt geoptimaliseerd."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps starten."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Opstarten afronden."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-verzoek is gewijzigd in DIAL-verzoek."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-verzoek is gewijzigd in USSD-verzoek."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-verzoek is gewijzigd in nieuw SS-verzoek."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2482b0a..0c53ca8 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -269,13 +269,13 @@
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Dostęp do karty SD."</string>
<string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Funkcje ułatwień dostępu"</string>
<string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Funkcje, których może zażądać technologia ułatwień dostępu."</string>
- <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobierz zawartość okna"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobieranie zawartości okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włącz czytanie dotykiem"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włączenie czytania dotykiem"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Klikane elementy będą wymawiane na głos, a ekran można przeglądać, używając gestów."</string>
- <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Włącz ułatwienia dostępu w internecie"</string>
+ <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Włączenie ułatwień dostępu w internecie"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Można zainstalować skrypty, by zawartość aplikacji była łatwiej dostępna."</string>
- <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Obserwuj wpisywany tekst"</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Obserwowanie wpisywanego tekstu"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obejmuje informacje osobiste, takie jak numery kart kredytowych i hasła."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"wyłączanie lub zmienianie paska stanu"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"godzinę temu"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> godz. temu"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Ostatnie (<xliff:g id="COUNT">%d</xliff:g>) dni"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Ostatni miesiąc"</string>
<string name="older" msgid="5211975022815554840">"Starsze"</string>
<plurals name="num_days_ago">
@@ -1200,7 +1198,7 @@
<item quantity="other" msgid="2973062968038355991">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item>
</plurals>
<string name="preposition_for_date" msgid="9093949757757445117">"w dniu <xliff:g id="DATE">%s</xliff:g>"</string>
- <string name="preposition_for_time" msgid="5506831244263083793">"o godzinie <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="preposition_for_time" msgid="5506831244263083793">"o godzinie <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"w <xliff:g id="YEAR">%s</xliff:g> r."</string>
<string name="day" msgid="8144195776058119424">"dzień"</string>
<string name="days" msgid="4774547661021344602">"dni"</string>
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android się uruchamia…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optymalizacja pamięci."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optymalizowanie aplikacji <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uruchamianie aplikacji."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Kończenie uruchamiania."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Działa <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Żądanie SS zostało zmienione na żądanie DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Żądanie SS zostało zmienione na żądanie USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Żądanie SS zostało zmienione na nowe żądanie SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 40e9313..85160d9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Há 1 hora"</item>
<item quantity="other" msgid="2467273239587587569">"Há <xliff:g id="COUNT">%d</xliff:g> horas"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Últimos <xliff:g id="COUNT">%d</xliff:g> dias"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Último mês"</string>
<string name="older" msgid="5211975022815554840">"Mais antiga"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"O Android está a iniciar…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"A otimizar o armazenamento."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"A otimizar a aplicação <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"A iniciar aplicações"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"A concluir o arranque."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"O pedido SS foi modificado para um pedido DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"O pedido SS foi modificado para um pedido USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"O pedido SS foi modificado para um novo pedido SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a11ba9d..866884a 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 hora atrás"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> horas atrás"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Últimos <xliff:g id="COUNT">%d</xliff:g> dias"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Mês passado"</string>
<string name="older" msgid="5211975022815554840">"Mais antigos"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"O Android está iniciando..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"A solicitação SS foi modificada para a solicitação DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitação SS foi modificada para a solicitação USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitação SS foi modificada para a nova solicitação SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 625f720..6f14718 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"cu 1 oră în urmă"</item>
<item quantity="other" msgid="2467273239587587569">"cu <xliff:g id="COUNT">%d</xliff:g> (de) ore în urmă"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Ultimele <xliff:g id="COUNT">%d</xliff:g> de zile"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Luna trecută"</string>
<string name="older" msgid="5211975022815554840">"Mai vechi"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android pornește..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Se optimizează stocarea."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Se optimizează aplicaţia <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Se pornesc aplicaţiile."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Se finalizează pornirea."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Rulează <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Solicitarea SS este modificată într-o solicitare DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Solicitarea SS este modificată într-o solicitare USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Solicitarea SS este modificată într-o nouă solicitare SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a768aa9..58dce27 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 час назад"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ч. назад"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Последние <xliff:g id="COUNT">%d</xliff:g> дн."</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Прошлый месяц"</string>
<string name="older" msgid="5211975022815554840">"Еще раньше"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Запуск Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизация хранилища…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизация приложения <xliff:g id="NUMBER_0">%1$d</xliff:g> из <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск приложений."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Окончание загрузки..."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Приложение <xliff:g id="APP">%1$s</xliff:g> запущено"</string>
@@ -1846,7 +1846,7 @@
<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="battery_saver_description" msgid="1960431123816253034">"Чтобы заряд батареи расходовался медленнее, режим энергосбережения уменьшает быстродействие устройства и ограничивает количество ресурсов, затрачиваемых на вибрацию, Геолокацию и большинство процессов обработки данных в фоновом режиме. Приложения, которые используют синхронизацию (например, для электронной почты и обмена SMS), могут не обновляться, пока вы их не откроете.\n\nКогда устройство заряжается, режим энергосбережения отключается автоматически."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"Чтобы продлить время работы устройства от батареи, в режиме энергосбережения снижается производительность, а также ограничивается использование вибрации, геолокации и фоновой передачи данных. Данные, требующие синхронизации, могут обновляться только когда вы откроете приложение.\n\nРежим энергосбережения автоматически отключается во время зарядки устройства."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"До отключения режима (в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
<string name="downtime_condition_line_one" msgid="8762708714645352010">"До отключения режима"</string>
<plurals name="zen_mode_duration_minutes_summary">
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-запрос преобразован в DIAL-запрос."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-запрос преобразован в USSD-запрос."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-запрос преобразован в новый SS-запрос."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 3cde8f6..a431ca3 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1144,9 +1144,7 @@
<item quantity="one" msgid="9150797944610821849">"පැය 1 කට පෙර"</item>
<item quantity="other" msgid="2467273239587587569">"පැය <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"අන්තිම දවස් <xliff:g id="COUNT">%d</xliff:g>"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"අවසාන මාසය"</string>
<string name="older" msgid="5211975022815554840">"පරණ"</string>
<plurals name="num_days_ago">
@@ -1305,6 +1303,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android ආරම්භ කරමින්…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"ආචයනය ප්රශස්තිකරණය කිරීම."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> කින් <xliff:g id="NUMBER_0">%1$d</xliff:g> වැනි යෙදුම ප්රශස්ත කරමින්."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"යෙදුම් ආරම්භ කරමින්."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ඇරඹුම අවසාන කරමින්."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ධාවනය වෙමින්"</string>
@@ -1881,4 +1881,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ඉල්ලීම DIAL ඉල්ලීම වෙත විකරණය කරන ලදී."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ඉල්ලීම USSD ඉල්ලීම වෙත විකරණය කරන ලදී."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ඉල්ලීම නව DIAL ඉල්ලීම වෙත විකරණය කරන ලදී."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4b56f04..5b43942 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"pred 1 hodinou"</item>
<item quantity="other" msgid="2467273239587587569">"pred <xliff:g id="COUNT">%d</xliff:g> hodinami"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Posledných <xliff:g id="COUNT">%d</xliff:g> dní"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Minulý mesiac"</string>
<string name="older" msgid="5211975022815554840">"Staršie"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Systém Android sa spúšťa…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimalizuje sa úložisko"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Prebieha optimalizácia aplikácie <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Prebieha spúšťanie aplikácií."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Prebieha dokončovanie spúšťania."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Spustená aplikácia: <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Žiadosť SS bola upravená na žiadosť DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Žiadosť SS bola upravená na žiadosť USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Žiadosť SS bola upravená na novú žiadosť SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index dca7d4e..0387d64 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"pred 1 uro"</item>
<item quantity="other" msgid="2467273239587587569">"Pred <xliff:g id="COUNT">%d</xliff:g> urami"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Zadnjih <xliff:g id="COUNT">%d</xliff:g> dni"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Pretekli mesec"</string>
<string name="older" msgid="5211975022815554840">"Starejše"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android se zaganja …"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje shrambe."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Zagon aplikacij."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončevanje zagona."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> se izvaja"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Zahteva SS je spremenjena v zahtevo DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Zahteva SS je spremenjena v zahtevo USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Zahteva SS je spremenjena v novo zahtevo SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index de9029f..04caa4d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Пре сат времена"</item>
<item quantity="other" msgid="2467273239587587569">"пре <xliff:g id="COUNT">%d</xliff:g> сата(и)"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"У последња(их) <xliff:g id="COUNT">%d</xliff:g> дана"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Прошлог месеца"</string>
<string name="older" msgid="5211975022815554840">"Старије"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android се покреће…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Меморија се оптимизује."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Покретање апликација."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Завршавање покретања."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS захтев је промењен у DIAL захтев."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS захтев је промењен у USSD захтев."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS захтев је промењен у нови SS захтев."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index ad5c495..68a5987 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"för 1 timme sedan"</item>
<item quantity="other" msgid="2467273239587587569">"för <xliff:g id="COUNT">%d</xliff:g> timmar sedan"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"De senaste <xliff:g id="COUNT">%d</xliff:g> dagarna"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Föregående månad"</string>
<string name="older" msgid="5211975022815554840">"Äldre"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android startar …"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lagringsutrymmet optimeras."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerar app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Appar startas."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Uppgraderingen är klar."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS-begäran har ändrats till en DIAL-begäran."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-begäran har ändrats till en USSD-begäran."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-begäran har ändrats till en ny SS-begäran."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2db8cd6..8a6943b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"Saa 1 iliyopita"</item>
<item quantity="other" msgid="2467273239587587569">"Saa <xliff:g id="COUNT">%d</xliff:g> zilizopita"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Siku <xliff:g id="COUNT">%d</xliff:g> zilizopita"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Mwezi uliopita"</string>
<string name="older" msgid="5211975022815554840">"Kuukuu zaidi"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Inaanzisha Android..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Inaboresha hifadhi."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Inaboresha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> kutoka <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> inaendelea"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Ombi la SS limerekebishwa na kuwa ombi la DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Ombi la SS limerekebishwa na kuwa ombi la USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Ombi la SS limerekebishwa na kuwa ombi jipya la SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 570671b..0f00395 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 மணிநேரம் முன்பு"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> மணிநேரத்திற்கு முன்பு"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"கடந்த <xliff:g id="COUNT">%d</xliff:g> நாட்கள்"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"சென்ற மாதம்"</string>
<string name="older" msgid="5211975022815554840">"பழையது"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android துவங்குகிறது..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"சேமிப்பகத்தை உகந்ததாக்குகிறது."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> பயன்பாட்டை ஒருங்கிணைக்கிறது."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS கோரிக்கையானது DIAL கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS கோரிக்கையானது USSD கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS கோரிக்கையானது புதிய SS கோரிக்கைக்கு மாற்றப்பட்டது."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 9975c71..1a7ef93 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 గంట క్రితం"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> గంటల క్రితం"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"గత <xliff:g id="COUNT">%d</xliff:g> రోజులు"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"గత నెల"</string>
<string name="older" msgid="5211975022815554840">"పాతది"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android ప్రారంభమవుతోంది…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"నిల్వను అనుకూలపరుస్తోంది."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> అనువర్తనాన్ని అనుకూలీకరిస్తోంది."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"అనువర్తనాలను ప్రారంభిస్తోంది."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"బూట్ను ముగిస్తోంది."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> అమలవుతోంది"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS అభ్యర్థన డయల్ అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS అభ్యర్థన USSD అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS అభ్యర్థన కొత్త SS అభ్యర్థనగా సవరించబడింది."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f9bcd79..76e4fab 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ชั่วโมงที่ผ่านมา"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ชั่วโมงที่ผ่านมา"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> วันที่แล้ว"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"เดือนที่แล้ว"</string>
<string name="older" msgid="5211975022815554840">"เก่ากว่า"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android กำลังเริ่มต้น…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"กำลังเพิ่มประสิทธิภาพพื้นที่จัดเก็บข้อมูล"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"กำลังเพิ่มประสิทธิภาพแอปพลิเคชัน <xliff:g id="NUMBER_0">%1$d</xliff:g> จาก <xliff:g id="NUMBER_1">%2$d</xliff:g> รายการ"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"เสร็จสิ้นการบูต"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงาน"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"คำขอ SS ได้รับการแก้ไขให้เป็นคำขอ DIAL"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"คำขอ SS ได้รับการแก้ไขให้เป็นคำขอ USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"คำขอ SS ได้รับการแก้ไขให้เป็นคำขอ SS ใหม่"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 2364e29..fcb6910 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 oras ang nakalipas"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> (na) oras ang nakalipas"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Huling <xliff:g id="COUNT">%d</xliff:g> (na) araw"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Nakaraang buwan"</string>
<string name="older" msgid="5211975022815554840">"Mas luma"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Nagsisimula ang Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ino-optimize ang storage."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ino-optimize ang app <xliff:g id="NUMBER_0">%1$d</xliff:g> ng <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Sinisimulan ang apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Pagtatapos ng pag-boot."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Tumatakbo ang <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Ginawang DIAL request ang SS request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Ginawang USSD request ang SS request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Ginawang bagong SS request ang SS request."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 07d1ba7..c7a5cfe 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -208,8 +208,8 @@
<string name="managed_profile_label" msgid="6260850669674791528">"İş"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Size maliyet getiren hizmetler"</string>
<string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Size maliyet getirebilecek işlemler yapma."</string>
- <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesajlarınız"</string>
- <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS mesajlarınızı, e-posta iletilerinizi ve diğer mesajlarınızı okuyup yazma."</string>
+ <string name="permgrouplab_messages" msgid="7521249148445456662">"İletileriniz"</string>
+ <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS, e-posta ve diğer iletilerinizi okuyup yazma."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Kişisel bilgileriniz"</string>
<string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Sizinle ilgili, kişi kartınızda kayıtlı bilgilere doğrudan erişim."</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosyal bilgileriniz"</string>
@@ -290,25 +290,25 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"giden çağrıları yeniden yönlendir"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Uygulamaya, giden bir çağrının numarası çevrilirken çağrıyı farklı bir numaraya yönlendirme ya da tamamen kapatma seçeneğiyle birlikte numarayı görme izni verir."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"kısa mesajları al (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Uygulamaya SMS mesajlarını alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen mesajları takip edip size göstermeden silebileceği anlamına gelir."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Uygulamaya SMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"kısa mesajları (MMS) al"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Uygulamaya MMS mesajlarını alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen mesajları takip edip size göstermeden silebileceği anlamına gelir."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Uygulamaya MMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"acil durum yayınlarını al"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Uygulamaya, acil yayın mesajları alma ve işleme izni verir. Bu izin, sadece sistem uygulamaları için kullanılabilir."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"hücre yayını mesajlarını oku"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Uygulamaya, cihazınız tarafından alınan hücre yayını mesajlarını okuma izni verir. Hücre yayını uyarıları bazı yerlerde acil durumlar konusunda sizi uyarmak için gönderilir. Kötü amaçlı uygulamalar acil hücre yayını alındığında cihazınızın performansına ya da çalışmasına engel olabilir."</string>
- <string name="permlab_sendSms" msgid="5600830612147671529">"SMS mesajları gönder"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"Uygulamaya SMS mesajları gönderme izni verir. Bu durum beklenmeyen ödemelere neden olabilir. Kötü amaçlı uygulamalar onayınız olmadan mesajlar göndererek sizi zarara uğratabilir."</string>
+ <string name="permlab_sendSms" msgid="5600830612147671529">"SMS iletileri gönder"</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Uygulamaya SMS iletisi gönderme izni verir. Bu durum beklenmeyen ödemelere neden olabilir. Kötü amaçlı uygulamalar onayınız olmadan iletiler göndererek sizi zarara uğratabilir."</string>
<string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"mesajla yanıtla etkinlikleri gönder"</string>
<string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Uygulamaya, gelen çağrıları mesajla yanıtlama etkinliklerini işlemek üzere diğer mesajlaşma uygulamalarına istek gönderme izni verir."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"kısa mesajlarımı (SMS veya MMS) oku"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Uygulamaya tabletinizde veya SIM kartta saklanan SMS mesajlarını okuma izni verir. Bu izin, uygulamanın tüm SMS mesajlarını içeriğinden veya gizliliğinden bağımsız olarak okumasına olanak sağlar."</string>
- <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Uygulamaya, TV\'nizde veya SIM kartta depolanmış SMS mesajlarını okuma izni verir. Bu izin, uygulamanın içeriğe veya gizliliğe bakılmaksızın tüm SMS mesajlarını okumasına olanak sağlar."</string>
- <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Uygulamaya telefonunuzda veya SIM kartta saklanan SMS mesajlarını okuma izni verir. Bu izin, uygulamanın tüm SMS mesajlarını içeriğinden veya gizliliğinden bağımsız olarak okumasına olanak sağlar."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Uygulamaya tabletinizde veya SIM kartta saklanan SMS iletilerini okuma izni verir. Bu izin, uygulamanın tüm SMS iletilerini içeriğinden veya gizliliğinden bağımsız olarak okumasına olanak sağlar."</string>
+ <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Uygulamaya, TV\'nizde veya SIM kartta depolanmış SMS iletilerini okuma izni verir. Bu izin, uygulamanın içeriğe veya gizliliğe bakılmaksızın tüm SMS iletilerini okumasına olanak sağlar."</string>
+ <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Uygulamaya telefonunuzda veya SIM kartta saklanan SMS iletilerini okuma izni verir. Bu izin, uygulamanın tüm SMS iletilerini içeriğinden veya gizliliğinden bağımsız olarak okumasına olanak sağlar."</string>
<string name="permlab_writeSms" msgid="3216950472636214774">"kısa mesajlarımı (SMS veya MMS) düzenle"</string>
- <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Uygulamaya, tabletinizde veya SIM kartınızda depolanan SMS mesajlarına yazma izni verir. Kötü amaçlı uygulamalar mesajlarınızı silebilir."</string>
- <string name="permdesc_writeSms" product="tv" msgid="955871498983538187">"Uygulamaya, TV\'niz ya da SIM kartınızda saklanan SMS mesajlarına yazma izni verir. Kötü amaçlı uygulamalar mesajlarınızı silebilir."</string>
- <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Uygulamaya, telefonunuzdaki veya SIM kartınızdaki SMS mesajlarına yazma izni verir. Kötü amaçlı uygulamalar mesajlarınızı silebilir."</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Uygulamaya, tabletinizde veya SIM kartınızda depolanan SMS iletilerine yazma izni verir. Kötü amaçlı uygulamalar iletilerinizi silebilir."</string>
+ <string name="permdesc_writeSms" product="tv" msgid="955871498983538187">"Uygulamaya, TV\'niz ya da SIM kartınızda saklanan SMS iletilerine yazma izni verir. Kötü amaçlı uygulamalar iletilerinizi silebilir."</string>
+ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Uygulamaya, telefonunuzdaki veya SIM kartınızdaki SMS iletilerine yazma izni verir. Kötü amaçlı uygulamalar iletilerinizi silebilir."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"kısa mesajları (WAP) al"</string>
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"Uygulamaya WAP mesajlarını alma ve işleme izni verir. Buna, size gönderilen mesajları takip edip size göstermeden silebilme izni de dahildir."</string>
<string name="permlab_receiveBluetoothMap" msgid="7593811487142360528">"Bluetooth iletilerini al (MAP)"</string>
@@ -370,7 +370,7 @@
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"paket ile kaldırılan yayını gönder"</string>
<string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Uygulamaya, bir uygulama paketinin kaldırıldığına dair bildirim yayınlama izni verir. Kötü amaçlı uygulamalar çalışan diğer uygulamaları kapatmak için bunu kullanabilir."</string>
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS ile alınan yayın gönder"</string>
- <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Uygulamaya, SMS mesajı alındığına dair bildirim yayınlama izni verir. Kötü amaçlı uygulamalar sahte SMS mesajları göndermek için bunu kullanabilir."</string>
+ <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Uygulamaya, SMS iletisi alındığına dair bildirim yayınlama izni verir. Kötü amaçlı uygulamalar sahte SMS iletileri göndermek için bunu kullanabilir."</string>
<string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH ile alınan yayın gönder"</string>
<string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Uygulamaya, WAP PUSH mesajı alındığına dair bildirim yayınlama izni verir. Kötü amaçlı uygulamalar sahte MMS bildirimleri oluşturmak veya bir web sayfasının içeriğini sessiz şekilde zararlı öğelerle değiştirmek için bunu kullanabilir."</string>
<string name="permlab_setProcessLimit" msgid="2451873664363662666">"çalışan işlem sayısını sınırla"</string>
@@ -526,15 +526,15 @@
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosyal akışınızı okuma"</string>
<string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Uygulamaya size veya arkadaşlarınıza ait sosyal güncellemelere erişme ve bunları senkronize etme izni verir. Bilgi paylaşırken dikkatli olun. Bu izin, uygulamanın sosyal ağlarda sizinle arkadaşlarınız arasındaki iletişimi, gizliliğine bakılmaksızın okumasına olanak sağlar. Not: Bu izin tüm sosyal ağlar için geçerli olmayabilir."</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosyal akışınıza yazma"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Uygulamaya arkadaşlarınızın sosyal güncellemelerini gösterme izni verir. Bilgi paylaşırken dikkatli olun -- Bu uygulama bir arkadaşınızdan geliyormuş gibi görünen mesajlar oluşturabilir. Not: Bu izin, tüm sosyal ağlarda geçerli olmayabilir."</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Uygulamaya arkadaşlarınızın sosyal güncellemelerini gösterme izni verir. Bilgi paylaşırken dikkatli olun -- Bu uygulama bir arkadaşınızdan geliyormuş gibi görünen iletiler oluşturabilir. Not: Bu izin, tüm sosyal ağlarda geçerli olmayabilir."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"takvim etkinliklerini ve gizli bilgileri oku"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Uygulamaya, arkadaşlarınızın ve iş arkadaşlarınızın etkinlikleri de olmak üzere tabletinizde depolanan tüm takvim etkinliklerini okuma izni verir. Bu izin, uygulamanın takvim verilerinizi gizliliğine ve hassaslığına bakmaksızın paylaşmasına ve kaydetmesine olanak sağlayabilir."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Uygulamaya, arkadaşlarınızın ve iş arkadaşlarınızın etkinlikleri dahil olmak üzere TV\'nizde kayıtlı tüm takvim etkinliklerini okuma izni verir. Bu da uygulamanın gizlilik ve duyarlılık dikkate alınmaksızın takvim verilerinizi paylaşmasına veya kaydetmesine olanak sağlayabilir."</string>
<string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Uygulamaya, arkadaşlarınızın ve iş arkadaşlarınızın etkinlikleri de dahil olmak üzere telefonunuzda depolanan tüm takvim etkinliklerini okuma izni verir. Bu izin, uygulamanın takvim verilerinizi gizliliğine ve hassaslığına bakmaksızın paylaşmasına ve kaydetmesine olanak sağlayabilir."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"sahibin bilgisi olmadan takvim etkinlikleri ekle veya mevcut etkinlikleri değiştir ve misafirlere e-posta gönder"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere tabletinizde değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen mesajlar göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere tabletinizde değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen iletiler göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere cihazınızda değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın, takvim sahiplerinden gelmiş gibi görünen iletiler göndermesine veya takvim sahiplerinin bilgisi olmadan etkinlikleri değiştirmesine olanak sağlayabilir."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere telefonunuzda değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen mesajlar göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere telefonunuzda değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen iletiler göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"test için sahte konum kaynakları"</string>
<string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Test amacıyla veya yeni bir konum sağlayıcı yüklemek için sahte konum kaynakları oluşturma. Bu izin, uygulamanın GPS veya konum sağlayıcıları gibi diğer konum kaynakları tarafından döndürülen konum ve/veya durum bilgisini geçersiz kılmasına olanak sağlar."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ek konum sağlayıcı komutlarına eriş"</string>
@@ -747,9 +747,9 @@
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Uygulamaya, o anda senkronize olan özet akışları ile ilgili bilgi alma izni verir."</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"abone olunan yayınları yazma"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Uygulamaya, o anda senkronize edilmiş özet akışlarını değiştirme izni verir. Kötü amaçlı uygulamalar senkronize edilmiş özet akışlarını değiştirebilir."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"sözlüğe eklediğim terimleri oku"</string>
+ <string name="permlab_readDictionary" msgid="4107101525746035718">"sözlüğe eklediğiniz terimleri okuma"</string>
<string name="permdesc_readDictionary" msgid="659614600338904243">"Uygulamaya, kullanıcının kullanıcı sözlüğünde depolamış olabileceği kelimeleri, adları ve kelime öbeklerini okuma izni verir."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"kullanıcı tanımlı sözlüğe kelime ekle"</string>
+ <string name="permlab_writeDictionary" msgid="2183110402314441106">"kullanıcı tanımlı sözlüğe kelime ekleme"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Uygulamaya, kullanıcı sözlüğüne yeni kelimeler yazma izni verir."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB belleğini okuma"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD kartımın içeriğini oku"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 saat önce"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> saat önce"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Son <xliff:g id="COUNT">%d</xliff:g> gün"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Son ay"</string>
<string name="older" msgid="5211975022815554840">"Daha eski"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android başlatılıyor…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Depolama optimize ediliyor."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> uygulama optimize ediliyor."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uygulamalar başlatılıyor"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Açılış tamamlanıyor."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışıyor"</string>
@@ -1367,11 +1367,11 @@
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile bağlantıya sahipken TV\'nizin Kablosuz bağlantısı geçici olarak kesilecek."</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaza bağlıyken Kablosuz ağ bağlantısı geçici olarak kesilecektir"</string>
<string name="select_character" msgid="3365550120617701745">"Karakter ekle"</string>
- <string name="sms_control_title" msgid="7296612781128917719">"SMS mesajları gönderiliyor"</string>
- <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> çok sayıda SMS mesajı gönderiyor. Bu uygulamanın mesaj göndermeye devam etmesine izin veriyor musunuz?"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"SMS iletileri gönderiliyor"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> çok sayıda SMS iletisi gönderiyor. Bu uygulamanın ileti göndermeye devam etmesine izin veriyor musunuz?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"İzin ver"</string>
<string name="sms_control_no" msgid="625438561395534982">"Reddet"</string>
- <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> adresine bir mesaj göndermek istiyor."</string>
+ <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> adresine bir ileti göndermek istiyor."</string>
<string name="sms_short_code_details" msgid="5873295990846059400">"Bu işlem, mobil hesabınızdan "<b>"ödeme alınmasına neden olabilir"</b>"."</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Bu işlem, mobil hesabınızdan ödeme alınmasına neden olacak."</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Gönder"</string>
@@ -1847,8 +1847,8 @@
<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="battery_saver_description" msgid="1960431123816253034">"Pil tasarrufu özelliği, pil ömrünü iyileştirmeye yardımcı olmak için cihazın performansını düşürür, titreşimi, konum hizmetlerini ve arka plan verilerinin çoğunu sınırlar. Senkronizasyona dayalı olarak çalışan e-posta, mesajlaşma uygulamaları ve diğer uygulamalar, bunları açmadığınız sürece güncellenmeyebilir.\n\nCihazınız şarj olurken pil tasarrufu otomatik olarak kapatılır."</string>
- <string name="downtime_condition_summary" msgid="8761776337475705749">"Kesinti süreniz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> saatinde sona erene kadar"</string>
- <string name="downtime_condition_line_one" msgid="8762708714645352010">"Kullanım dışı kalma durumunuz bitene kadar"</string>
+ <string name="downtime_condition_summary" msgid="8761776337475705749">"Bildirim istenmeyen zaman <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> saatinde sona erene kadar"</string>
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Bildirim istenmeyen zaman bitene kadar"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Bir dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS isteği DIAL isteği olarak değiştirildi."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS isteği USSD isteği olarak değiştirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS isteği yeni SS isteği olarak değiştirildi."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 79281b33..c650daa 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -71,7 +71,7 @@
<string name="ClirMmi" msgid="7784673673446833091">"Вихід. ід. абонента"</string>
<string name="ColpMmi" msgid="3065121483740183974">"Ідентифікатор під’єднаної лінії"</string>
<string name="ColrMmi" msgid="4996540314421889589">"Обмеження ідентифікатора під’єднаної лінії"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Переадрес. виклику"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Переадресація виклику"</string>
<string name="CwMmi" msgid="9129678056795016867">"Паралел. виклик"</string>
<string name="BaMmi" msgid="455193067926770581">"Заборона викл."</string>
<string name="PwdMmi" msgid="7043715687905254199">"Зміна пароля"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 год. тому"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> год. тому"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Остан. <xliff:g id="COUNT">%d</xliff:g> дн."</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Останній міс."</string>
<string name="older" msgid="5211975022815554840">"Давніше"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Запуск ОС Android…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимізація пам’яті."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимізація програми <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск програм."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Завершення завантаження."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Працює <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Запит SS перетворено на запит DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Запит SS перетворено на запит USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Запит SS перетворено на новий запит SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 7f8a88e..259dc0e 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 گھنٹہ پہلے"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> گھنٹے پہلے"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"آخری <xliff:g id="COUNT">%d</xliff:g> دن"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"پچھلے مہینے"</string>
<string name="older" msgid="5211975022815554840">"پرانا"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android شروع ہو رہا ہے…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"اسٹوریج کو بہترین بنایا جا رہا ہے۔"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"ایپ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g> کو بہتر بنایا جا رہا ہے۔"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ایپس شروع ہو رہی ہیں۔"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"بوٹ مکمل ہو رہا ہے۔"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> چل رہی ہے"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS درخواست میں ترمیم کر کے DIAL درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS درخواست میں ترمیم کر کے USSD درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS درخواست میں ترمیم کر کے نئی SS درخواست بنا دی گئی ہے۔"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 306e4b2..3257124 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 soat oldin"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> soat oldin"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"O‘tgan <xliff:g id="COUNT">%d</xliff:g> kun"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"O‘tgan oy"</string>
<string name="older" msgid="5211975022815554840">"Eskiroq"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android ishga tushmoqda…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Xotira optimallashtirilmoqda."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ilovalar optimallashtirilmoqda (<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>)."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ilovalar ishga tushirilmoqda."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Tizimni yuklashni tugatish."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ishlamoqda"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS so‘rovi DIAL so‘roviga o‘zgartirildi."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS so‘rovi USSD so‘roviga o‘zgartirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS so‘rovi yangi SS so‘roviga o‘zgartirildi."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e361bad..5ea9b66 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 giờ trước"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> giờ trước"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ngày trước"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Tháng trước"</string>
<string name="older" msgid="5211975022815554840">"Cũ hơn"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android đang khởi động..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tối ưu hóa lưu trữ."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Đang tối ưu hóa ứng dụng <xliff:g id="NUMBER_0">%1$d</xliff:g> trong tổng số <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Khởi động ứng dụng."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Hoàn tất khởi động."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> đang hoạt động"</string>
@@ -1881,4 +1881,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Yêu cầu SS được sửa đổi thành yêu cầu DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Yêu cầu SS được sửa đổi thành yêu cầu USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Yêu cầu SS được sửa đổi thành yêu cầu SS mới."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4a03e7b..605c9d7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -970,7 +970,7 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"重试"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"重试"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
- <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"没有SIM卡"</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"没有 SIM 卡"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"平板电脑中没有SIM卡。"</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"电视中没有 SIM 卡。"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"手机中无SIM卡"</string>
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1小时前"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g>小时前"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"过去<xliff:g id="COUNT">%d</xliff:g>天"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"上个月"</string>
<string name="older" msgid="5211975022815554840">"往前"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android 正在启动…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在优化存储空间。"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"正在优化第<xliff:g id="NUMBER_0">%1$d</xliff:g>个应用(共<xliff:g id="NUMBER_1">%2$d</xliff:g>个)。"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"即将完成启动。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>正在运行"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS 请求已修改为 DIAL 请求。"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 请求已修改为 USSD 请求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 请求已修改为新的 SS 请求。"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index bb39491..8a8b5dc 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 小時前"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> 小時前"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"最近 <xliff:g id="COUNT">%d</xliff:g> 天"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"上個月"</string>
<string name="older" msgid="5211975022815554840">"較舊"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android 正在啟動…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在優化儲存空間。"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"正在優化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"正在執行 <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS 要求已修改為 DIAL 要求。"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 要求已修改為 USSD 要求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 要求已修改為新的 SS 要求。"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 507205a..5e1c3ff 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 小時以前"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> 小時前"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"最近 <xliff:g id="COUNT">%d</xliff:g> 天"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"上個月"</string>
<string name="older" msgid="5211975022815554840">"較舊"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"Android 正在啟動…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在對儲存空間進行最佳化處理。"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"正在最佳化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> 執行中"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS 要求已改為 DIAL 要求。"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 要求已改為 USSD 要求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 要求已改為新的 SS 要求。"</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 1222904..44f4750 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1142,9 +1142,7 @@
<item quantity="one" msgid="9150797944610821849">"1 ihora eledlule"</item>
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> amahora adlule"</item>
</plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Izinsuku zokugcina ezingu- <xliff:g id="COUNT">%d</xliff:g>"</item>
- </plurals>
+ <!-- no translation found for last_num_days:one (7555846096746489821) -->
<string name="last_month" msgid="3959346739979055432">"Inyanga edlule"</string>
<string name="older" msgid="5211975022815554840">"Okudala kakhulu"</string>
<plurals name="num_days_ago">
@@ -1303,6 +1301,8 @@
<string name="android_start_title" msgid="8418054686415318207">"I-Android iyaqala…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ikhulisa isitoreji."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> uhlelo lokusebenza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <!-- no translation found for android_preparing_apk (8162599310274079154) -->
+ <skip />
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinhlelo zokusebenza."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Qedela ukuqala kabusha."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> iyasebenza"</string>
@@ -1879,4 +1879,8 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Isicelo se-SS siguqulelwe kusicelo se-DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Isicelo se-SS siguqulelwe kusicelo se-USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Isicelo se-SS siguqulelwe kusicelo esisha se-SS."</string>
+ <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
+ <skip />
+ <!-- no translation found for usb_midi_peripheral_model_name (1959288763942653301) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 39c42ee..559d750 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4338,6 +4338,10 @@
<attr name="popupAnimationStyle" format="reference" />
<!-- Whether the popup window should overlap its anchor view. -->
<attr name="overlapAnchor" format="boolean" />
+ <!-- Transition used to move views into the popup window. -->
+ <attr name="popupEnterTransition" format="reference" />
+ <!-- Transition used to move views out of the popup window. -->
+ <attr name="popupExitTransition" format="reference" />
</declare-styleable>
<declare-styleable name="ListPopupWindow">
<!-- Amount of pixels by which the drop down should be offset vertically. -->
@@ -7257,8 +7261,34 @@
<declare-styleable name="Switch">
<!-- Drawable to use as the "thumb" that switches back and forth. -->
<attr name="thumb" />
+ <!-- Tint to apply to the thumb. -->
+ <attr name="thumbTint" />
+ <!-- Blending mode used to apply the thumb tint. -->
+ <attr name="thumbTintMode" />
<!-- Drawable to use as the "track" that the switch thumb slides within. -->
<attr name="track" format="reference" />
+ <!-- Tint to apply to the track. -->
+ <attr name="trackTint" format="color" />
+ <!-- Blending mode used to apply the track tint. -->
+ <attr name="trackTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
+ </attr>
<!-- Text to use when the switch is in the checked/"on" state. -->
<attr name="textOn" />
<!-- Text to use when the switch is in the unchecked/"off" state. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9945c63..461f9a0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2608,6 +2608,9 @@
=============================================================== -->
<eat-comment />
+ <public type="attr" name="trackTint" />
+ <public type="attr" name="trackTintMode" />
+
<public type="style" name="Widget.Material.Button.Colored" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index efdc3c8..ab6dbff 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3397,6 +3397,7 @@
<!-- This is used to express that something occurred within the last X days (e.g., Last 7 days). -->
<plurals name="last_num_days">
+ <item quantity="one">Last <xliff:g id="count">%d</xliff:g> day</item>
<item quantity="other">Last <xliff:g id="count">%d</xliff:g> days</item>
</plurals>
@@ -3748,6 +3749,9 @@
<xliff:g id="number" example="123">%1$d</xliff:g> of
<xliff:g id="number" example="123">%2$d</xliff:g>.</string>
+ <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog for each .apk pre boot broadcast -->
+ <string name="android_preparing_apk">Preparing <xliff:g id="appname">%1$s</xliff:g>.</string>
+
<!-- [CHAR LIMIT=NONE] Message to show in upgrading dialog when reached the point of starting apps. -->
<string name="android_upgrading_starting_apps">Starting apps.</string>
@@ -3853,7 +3857,7 @@
<!-- title for this message -->
<string name="wifi_connect_alert_title">Allow connection?</string>
<!-- message explaining who is connecting to what -->
- <string name="wifi_connect_alert_message">%1$s would like to connect to %2$s</string>
+ <string name="wifi_connect_alert_message">Application %1$s would like to connect to Wifi Network %2$s</string>
<!-- default application in case name can not be found -->
<string name="wifi_connect_default_application">An application</string>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 4329809..48645ed 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -770,6 +770,9 @@
<item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="popupBackground">@drawable/popup_background_material</item>
<item name="popupElevation">@dimen/floating_window_z</item>
+ <item name="popupAnimationStyle">@empty</item>
+ <item name="popupEnterTransition">@transition/popup_window_enter</item>
+ <item name="popupExitTransition">@transition/popup_window_exit</item>
<item name="dropDownVerticalOffset">0dip</item>
<item name="dropDownHorizontalOffset">0dip</item>
<item name="overlapAnchor">true</item>
@@ -780,11 +783,7 @@
</style>
<style name="Widget.Material.Spinner.DropDown"/>
-
- <style name="Widget.Material.Spinner.DropDown.ActionBar">
- <item name="background">@drawable/spinner_background_material</item>
- <item name="overlapAnchor">true</item>
- </style>
+ <style name="Widget.Material.Spinner.DropDown.ActionBar" />
<style name="Widget.Material.Spinner.Underlined">
<item name="background">@drawable/spinner_textfield_background_material</item>
@@ -847,7 +846,9 @@
<item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="popupBackground">@drawable/popup_background_material</item>
<item name="popupElevation">@dimen/floating_window_z</item>
- <item name="popupAnimationStyle">@style/Animation.Material.Popup</item>
+ <item name="popupAnimationStyle">@empty</item>
+ <item name="popupEnterTransition">@transition/popup_window_enter</item>
+ <item name="popupExitTransition">@transition/popup_window_exit</item>
<item name="dropDownVerticalOffset">0dip</item>
<item name="dropDownHorizontalOffset">0dip</item>
<item name="dropDownWidth">wrap_content</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 607744f..9c1fd07 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1514,6 +1514,7 @@
<java-symbol type="layout" name="screen_title" />
<java-symbol type="layout" name="screen_title_icons" />
<java-symbol type="string" name="system_ui_date_pattern" />
+ <java-symbol type="string" name="android_preparing_apk" />
<java-symbol type="string" name="android_start_title" />
<java-symbol type="string" name="android_upgrading_title" />
<java-symbol type="string" name="bugreport_title" />
diff --git a/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
index e7f4bad..e5a92bf 100644
--- a/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
+++ b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
@@ -11,7 +11,7 @@
public void testSmallList() throws Exception {
final int objectCount = 100;
- List<SmallObject> list = new ArrayList<>();
+ List<SmallObject> list = new ArrayList<SmallObject>();
for (int i = 0; i < objectCount; i++) {
list.add(new SmallObject(i * 2, (i * 2) + 1));
}
@@ -20,7 +20,7 @@
Parcel parcel = Parcel.obtain();
try {
- parcel.writeParcelable(new ParceledListSlice<>(list), 0);
+ parcel.writeParcelable(new ParceledListSlice<SmallObject>(list), 0);
parcel.setDataPosition(0);
slice = parcel.readParcelable(getClass().getClassLoader());
} finally {
@@ -56,7 +56,7 @@
final int thresholdBytes = 256 * 1024;
final int objectCount = thresholdBytes / measureLargeObject();
- List<LargeObject> list = new ArrayList<>();
+ List<LargeObject> list = new ArrayList<LargeObject>();
for (int i = 0; i < objectCount; i++) {
list.add(new LargeObject(
i * 5,
@@ -71,7 +71,7 @@
Parcel parcel = Parcel.obtain();
try {
- parcel.writeParcelable(new ParceledListSlice<>(list), 0);
+ parcel.writeParcelable(new ParceledListSlice<LargeObject>(list), 0);
parcel.setDataPosition(0);
slice = parcel.readParcelable(getClass().getClassLoader());
} finally {
@@ -95,7 +95,7 @@
* Test that only homogeneous elements may be unparceled.
*/
public void testHomogeneousElements() throws Exception {
- List<BaseObject> list = new ArrayList<>();
+ List<BaseObject> list = new ArrayList<BaseObject>();
list.add(new LargeObject(0, 1, 2, 3, 4));
list.add(new SmallObject(5, 6));
list.add(new SmallObject(7, 8));
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 5265f20..4e03108 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -57,7 +57,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015.
<br/>Any versions with less than 0.1% distribution are not shown.</em>
</p>
@@ -88,7 +88,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015.
<br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
@@ -108,7 +108,7 @@
<img alt="" style="float:right"
-src="//chart.googleapis.com/chart?chl=GL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A69.9%2C30.1&chco=c4df9b%2C6fad0c&cht=p&chs=400x250" />
+src="//chart.googleapis.com/chart?chl=GL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A68.9%2C31.1&chco=c4df9b%2C6fad0c&cht=p&chs=400x250" />
<p>To declare which version of OpenGL ES your application requires, you should use the {@code
@@ -127,17 +127,17 @@
</tr>
<tr>
<td>2.0</td>
-<td>69.9%</td>
+<td>68.9%</td>
</tr>
<tr>
<td>3.0</td>
-<td>30.1%</td>
+<td>31.1%</td>
</tr>
</table>
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 5, 2015</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 2, 2015</em></p>
@@ -155,7 +155,7 @@
var VERSION_DATA =
[
{
- "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chco=c4df9b%2C6fad0c&chd=t%3A0.4%2C7.8%2C6.7%2C46.0%2C39.1&chf=bg%2Cs%2C00000000&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat",
+ "chart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A0.4%2C7.4%2C6.4%2C44.5%2C39.7%2C1.6&chco=c4df9b%2C6fad0c&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat%7CLollipop&chs=500x250&cht=p",
"data": [
{
"api": 8,
@@ -165,32 +165,37 @@
{
"api": 10,
"name": "Gingerbread",
- "perc": "7.8"
+ "perc": "7.4"
},
{
"api": 15,
"name": "Ice Cream Sandwich",
- "perc": "6.7"
+ "perc": "6.4"
},
{
"api": 16,
"name": "Jelly Bean",
- "perc": "19.2"
+ "perc": "18.4"
},
{
"api": 17,
"name": "Jelly Bean",
- "perc": "20.3"
+ "perc": "19.8"
},
{
"api": 18,
"name": "Jelly Bean",
- "perc": "6.5"
+ "perc": "6.3"
},
{
"api": 19,
"name": "KitKat",
- "perc": "39.1"
+ "perc": "39.7"
+ },
+ {
+ "api": 21,
+ "name": "Lollipop",
+ "perc": "1.6"
}
]
}
@@ -203,29 +208,29 @@
"data": {
"Large": {
"hdpi": "0.6",
- "ldpi": "0.6",
- "mdpi": "5.4",
- "tvdpi": "2.3",
+ "ldpi": "0.5",
+ "mdpi": "5.1",
+ "tvdpi": "2.2",
"xhdpi": "0.6"
},
"Normal": {
- "hdpi": "37.5",
- "mdpi": "8.8",
+ "hdpi": "38.3",
+ "mdpi": "8.7",
"tvdpi": "0.1",
- "xhdpi": "18.4",
- "xxhdpi": "16.3"
+ "xhdpi": "18.8",
+ "xxhdpi": "15.9"
},
"Small": {
"ldpi": "4.8"
},
"Xlarge": {
"hdpi": "0.3",
- "mdpi": "3.7",
+ "mdpi": "3.5",
"xhdpi": "0.6"
}
},
- "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b%2C6fad0c&chd=t%3A5.4%2C17.9%2C2.4%2C38.4%2C19.6%2C16.3&chf=bg%2Cs%2C00000000&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
- "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b%2C6fad0c&chd=t%3A4.6%2C9.5%2C81.1%2C4.8&chf=bg%2Cs%2C00000000&chl=Xlarge%7CLarge%7CNormal%7CSmall"
+ "densitychart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A5.3%2C17.3%2C2.3%2C39.2%2C20.0%2C15.9&chco=c4df9b%2C6fad0c&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chs=400x250&cht=p",
+ "layoutchart": "//chart.googleapis.com/chart?chf=bg%2Cs%2C00000000&chd=t%3A4.4%2C9.0%2C81.8%2C4.8&chco=c4df9b%2C6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall&chs=400x250&cht=p"
}
];
@@ -305,7 +310,7 @@
},
{
"api":21,
- "link":"<a href='/about/versions/android-5.0.html'>4.4</a>",
+ "link":"<a href='/about/versions/android-5.0.html'>5.0</a>",
"codename":"Lollipop"
}
];
diff --git a/docs/html/images/tv/app-browse.png b/docs/html/images/tv/app-browse.png
new file mode 100644
index 0000000..7670713
--- /dev/null
+++ b/docs/html/images/tv/app-browse.png
Binary files differ
diff --git a/docs/html/images/tv/card-view.png b/docs/html/images/tv/card-view.png
new file mode 100644
index 0000000..5e907de
--- /dev/null
+++ b/docs/html/images/tv/card-view.png
Binary files differ
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index e74d46a..af6f6b8 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -481,14 +481,14 @@
<ul>
<li>GNOME or KDE desktop</li>
-<li>GNU C Library (glibc) 2.11 or later</li>
+<li>GNU C Library (glibc) 2.15 or later</li>
<li>2 GB RAM minimum, 4 GB RAM recommended</li>
<li>400 MB hard disk space</li>
<li>At least 1 GB for Android SDK, emulator system images, and caches</li>
<li>1280 x 800 minimum screen resolution</li>
<li>Oracle® Java Development Kit (JDK) 7 </li>
</ul>
-<p>Tested on Ubuntu® 12.04, Precise Pangolin (64-bit distribution capable of running
+<p>Tested on Ubuntu® 14.04, Trusty Tahr (64-bit distribution capable of running
32-bit applications).</p>
diff --git a/docs/html/tools/devices/emulator.jd b/docs/html/tools/devices/emulator.jd
index 42240b9..5bdd4e2 100644
--- a/docs/html/tools/devices/emulator.jd
+++ b/docs/html/tools/devices/emulator.jd
@@ -122,7 +122,7 @@
mobile devices, including: </p>
<ul>
- <li>An ARMv5 CPU and the corresponding memory-management unit (MMU)</li>
+ <li>An ARMv5, ARMv7, or x86 CPU</li>
<li>A 16-bit LCD display</li>
<li>One or more keyboards (a Qwerty-based keyboard and associated Dpad/Phone
buttons)</li>
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index 4698ba1..b9463e4 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -153,7 +153,8 @@
<pre>
PackageManager packageManager = {@link android.content.Context#getPackageManager()};
-List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;
</pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index f5999a5..c59d8ff 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -951,6 +951,10 @@
Creating a Catalog Browser</a>
</li>
<li>
+ <a href="<?cs var:toroot ?>training/tv/playback/card.html">
+ Providing a Card View</a>
+ </li>
+ <li>
<a href="<?cs var:toroot ?>training/tv/playback/details.html"
ja-lang="詳細ビューをビルドする">
Building a Details View</a>
@@ -1883,4 +1887,4 @@
buildToggleLists();
changeNavLang(getLangPref());
//-->
-</script>
+</script>
\ No newline at end of file
diff --git a/docs/html/training/tv/playback/card.jd b/docs/html/training/tv/playback/card.jd
new file mode 100644
index 0000000..8ac75fd
--- /dev/null
+++ b/docs/html/training/tv/playback/card.jd
@@ -0,0 +1,156 @@
+page.title=Providing a Card View
+page.tags="card"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#presenter">Create a Card Presenter</a></li>
+ <li><a href="#card-view">Create a Card View</a></li>
+ </ol>
+ <h2>Try it out</h2>
+ <ul>
+ <li><a class="external-link" href="https://github.com/googlesamples/androidtv-Leanback">Android
+ Leanback sample app</a></li>
+ </ul>
+</div>
+</div>
+
+<p>In the previous lesson, you created a catalog browser, implemented in a browse fragment, that
+displays a list of media items. In this lesson, you create the card views for your media items and
+present them in the browse fragment.</p>
+
+<p>The {@link android.support.v17.leanback.widget.BaseCardView} class and subclasses display the meta
+data associated with a media item. The {@link android.support.v17.leanback.widget.ImageCardView}
+class used in this lesson displays an image for the content along with the media item's title.</p>
+
+<p>This lesson describes code from the <a href="https://github.com/googlesamples/androidtv-Leanback">
+Android Leanback sample app</a>, available on GitHub. Use this sample code to start your own
+app.</p>
+
+<img itemprop="image" src="{@docRoot}images/tv/app-browse.png" alt="App main screen"/>
+<p class="img-caption"><b>Figure 1.</b> The <a href="https://github.com/googlesamples/androidtv-Leanback">
+Leanback sample app</a> browse fragment with a card presenter displaying card view objects.</p>
+
+<h2 id="presenter">Create a Card Presenter</h2>
+
+<p>A {@link android.support.v17.leanback.widget.Presenter} generates views and binds objects to them
+on demand. In the browse fragment where your app presents its content to the user, you create a
+{@link android.support.v17.leanback.widget.Presenter} for the content cards and pass it to the adapter
+that adds the content to the screen. In the following code, the <code>CardPresenter</code> is created
+in the {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object) onLoadFinished()}
+callback of the {@link android.support.v4.app.LoaderManager}.</p>
+
+<pre>
+@Override
+public void onLoadFinished(Loader<HashMap<String, List<Movie>>> arg0,
+ HashMap<String, List<Movie>> data) {
+
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ CardPresenter cardPresenter = new CardPresenter();
+
+ int i = 0;
+
+ for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ List<Movie> list = entry.getValue();
+
+ for (int j = 0; j < list.size(); j++) {
+ listRowAdapter.add(list.get(j));
+ }
+ HeaderItem header = new HeaderItem(i, entry.getKey(), null);
+ i++;
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+
+ HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples),
+ null);
+
+ GridItemPresenter gridPresenter = new GridItemPresenter();
+ ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
+ gridRowAdapter.add(getString(R.string.grid_view));
+ gridRowAdapter.add(getString(R.string.error_fragment));
+ gridRowAdapter.add(getString(R.string.personal_settings));
+ mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
+
+ setAdapter(mRowsAdapter);
+
+ updateRecommendations();
+}
+</pre>
+
+<h2 id="card-view">Create a Card View</h2>
+
+<p>In this step, you build the card presenter with a view holder for the card view that describes
+your media content items. Note that each presenter must only create one view type. If you have two
+different card view types then you need two different card presenters.</p>
+
+<p>In the {@link android.support.v17.leanback.widget.Presenter}, implement an
+{@link android.support.v17.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup) onCreateViewHolder()}
+callback that creates a view holder that can be used to display a content item.</p>
+
+<pre>
+@Override
+public class CardPresenter extends Presenter {
+
+ private Context mContext;
+ private static int CARD_WIDTH = 313;
+ private static int CARD_HEIGHT = 176;
+ private Drawable mDefaultCardImage;
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ mContext = parent.getContext();
+ mDefaultCardImage = mContext.getResources().getDrawable(R.drawable.movie);
+...
+</pre>
+
+<p>In the {@link android.support.v17.leanback.widget.Presenter#onCreateViewHolder(android.view.ViewGroup)
+onCreateViewHolder()} method, create a card view for content items. The sample below uses an
+{@link android.support.v17.leanback.widget.ImageCardView}.</p>
+
+<p>When a card is selected, the default behavior expands it to a larger size. If you want to designate
+a different color for the selected card, call {@link android.support.v17.leanback.widget.BaseCardView#setSelected(boolean)
+setSelected()}
+as shown here.</p>
+
+<pre>
+...
+ ImageCardView cardView = new ImageCardView(mContext) {
+ @Override
+ public void setSelected(boolean selected) {
+ int selected_background = mContext.getResources().getColor(R.color.detail_background);
+ int default_background = mContext.getResources().getColor(R.color.default_background);
+ int color = selected ? selected_background : default_background;
+ findViewById(R.id.info_field).setBackgroundColor(color);
+ super.setSelected(selected);
+ }
+ };
+...
+</pre>
+
+<p>When the user opens your app, the {@link android.support.v17.leanback.widget.Presenter.ViewHolder}
+displays the <code>CardView</code> objects for your content items. You need to set these to receive
+focus from the D-pad controller by calling {@link android.view.View#setFocusable(boolean) setFocusable(true)}
+and {@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode(true)}.</p>
+
+<pre>
+...
+ cardView.setFocusable(true);
+ cardView.setFocusableInTouchMode(true);
+ return new ViewHolder(cardView);
+}
+</pre>
+
+<p>When the user selects the {@link android.support.v17.leanback.widget.ImageCardView}, it expands
+to reveal its text area with the background color you specify, as shown in figure 2.</p>
+
+<img itemprop="image" src="{@docRoot}images/tv/card-view.png" alt="App card view"/>
+<p class="img-caption"><b>Figure 2.</b> The <a href="https://github.com/googlesamples/androidtv-Leanback">
+Leanback sample app</a> image card view when selected.</p>
+
+
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 5427d48..0e9c5ec 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -56,6 +56,9 @@
<dd>Learn how to use the Leanback support library to build a browsing interface for media
catalogs.</dd>
+ <dt><b><a href="details.html">Providing a Card View</a></b></dt>
+ <dd>Learn how to use the Leanback support library to build a card view for content items.</dd>
+
<dt><b><a href="details.html">Building a Details View</a></b></dt>
<dd>Learn how to use the Leanback support library to build a details page for media items.</dd>
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index 177ea7a..a378096 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -119,8 +119,8 @@
<p>
Avoid screen elements being clipped due to overscan and by incorporating a 10% margin
- on all sides of your layout. This translates into a 27dp margin on the left and right edges and
- a 48dp margin on the top and bottom of your base layouts for activities. The following
+ on all sides of your layout. This translates into a 48dp margin on the left and right edges and
+ a 27dp margin on the top and bottom of your base layouts for activities. The following
example layout demonstrates how to set these margins in the root layout for a TV app:
</p>
diff --git a/graphics/java/android/graphics/AvoidXfermode.java b/graphics/java/android/graphics/AvoidXfermode.java
index 206c959..48ee6fa 100644
--- a/graphics/java/android/graphics/AvoidXfermode.java
+++ b/graphics/java/android/graphics/AvoidXfermode.java
@@ -23,7 +23,7 @@
@Deprecated
public class AvoidXfermode extends Xfermode {
- // these need to match the enum in SkAvoidXfermode.h on the native side
+ // these need to match the enum in AvoidXfermode.h on the native side
public enum Mode {
AVOID (0), //!< draw everywhere except on the opColor
TARGET (1); //!< draw only on top of the opColor
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index fa9af2a..39272b9 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -122,11 +122,6 @@
* @param canvas The picture is drawn to this canvas
*/
public void draw(Canvas canvas) {
- if (canvas.isHardwareAccelerated()) {
- throw new IllegalArgumentException(
- "Picture playback is only supported on software canvas.");
- }
-
if (mRecordingCanvas != null) {
endRecording();
}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 488ee4c..50a6df4 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -119,6 +119,23 @@
a.recycle();
}
+ private void setDrawable(Drawable dr) {
+ if (mDrawable != null) {
+ mDrawable.setCallback(null);
+ }
+
+ mDrawable = dr;
+
+ if (dr != null) {
+ dr.setCallback(this);
+ dr.setVisible(isVisible(), true);
+ dr.setState(getState());
+ dr.setLevel(getLevel());
+ dr.setBounds(getBounds());
+ dr.setLayoutDirection(getLayoutDirection());
+ }
+ }
+
private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
Theme theme) throws XmlPullParserException, IOException {
// Load inner XML elements.
@@ -133,9 +150,10 @@
}
final Drawable dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
- mState.mDrawableState = dr.getConstantState();
- mDrawable = dr;
- dr.setCallback(this);
+ if (dr != null) {
+ mState.mDrawableState = dr.getConstantState();
+ setDrawable(dr);
+ }
}
}
@@ -166,8 +184,7 @@
final Drawable dr = a.getDrawable(attr);
if (dr != null) {
mState.mDrawableState = dr.getConstantState();
- mDrawable = dr;
- dr.setCallback(this);
+ setDrawable(dr);
}
break;
case R.styleable.InsetDrawable_inset:
@@ -408,6 +425,7 @@
if (!mMutated && super.mutate() == this) {
mState = new InsetState(mState);
mDrawable.mutate();
+ mState.mDrawableState = mDrawable.getConstantState();
mMutated = true;
}
return this;
@@ -509,7 +527,8 @@
*/
private void updateLocalState(Resources res) {
if (mState.mDrawableState != null) {
- mDrawable = mState.mDrawableState.newDrawable(res);
+ final Drawable dr = mState.mDrawableState.newDrawable(res);
+ setDrawable(dr);
}
}
}
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index de9ef06..a05217f 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -65,6 +65,7 @@
ResourceCache.cpp \
ShadowTessellator.cpp \
SkiaCanvas.cpp \
+ SkiaCanvasProxy.cpp \
SkiaShader.cpp \
Snapshot.cpp \
SpotShadow.cpp \
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index f9c8620..7ad0683 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -42,15 +42,15 @@
*/
static Canvas* create_canvas(SkCanvas* skiaCanvas);
- // TODO: enable HWUI to either create similar canvas wrapper or subclass
- // directly from Canvas
- //static Canvas* create_canvas(uirenderer::Renderer* renderer);
-
- // TODO: this is a temporary affordance until all necessary logic can be
- // moved within this interface! Further, the return value should
- // NOT be unref'd and is valid until this canvas is destroyed or a
- // new bitmap is set.
- virtual SkCanvas* getSkCanvas() = 0;
+ /**
+ * Provides a Skia SkCanvas interface that acts as a proxy to this Canvas.
+ * It is useful for testing and clients (e.g. Picture/Movie) that expect to
+ * draw their contents into an SkCanvas.
+ *
+ * Further, the returned SkCanvas should NOT be unref'd and is valid until
+ * this canvas is destroyed or a new bitmap is set.
+ */
+ virtual SkCanvas* asSkCanvas() = 0;
virtual void setBitmap(SkBitmap* bitmap, bool copyState) = 0;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d98d744..23181bc 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -59,6 +59,7 @@
mPathMap.clear();
DisplayListData* data = mDisplayListData;
mDisplayListData = nullptr;
+ mSkiaCanvasProxy.reset(nullptr);
return data;
}
@@ -94,6 +95,15 @@
mDisplayListData->functors.add(functor);
}
+SkCanvas* DisplayListRenderer::asSkCanvas() {
+ LOG_ALWAYS_FATAL_IF(!mDisplayListData,
+ "attempting to get an SkCanvas when we are not recording!");
+ if (!mSkiaCanvasProxy) {
+ mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
+ }
+ return mSkiaCanvasProxy.get();
+}
+
int DisplayListRenderer::save(SkCanvas::SaveFlags flags) {
addStateOp(new (alloc()) SaveOp((int) flags));
return mState.save((int) flags);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index d2b3ead..bd0b3b7 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,6 +28,7 @@
#include "Canvas.h"
#include "CanvasState.h"
#include "DisplayList.h"
+#include "SkiaCanvasProxy.h"
#include "RenderNode.h"
#include "Renderer.h"
#include "ResourceCache.h"
@@ -136,10 +137,8 @@
// ----------------------------------------------------------------------------
// android/graphics/Canvas interface
// ----------------------------------------------------------------------------
- virtual SkCanvas* getSkCanvas() override {
- LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas");
- return nullptr;
- }
+ virtual SkCanvas* asSkCanvas() override;
+
virtual void setBitmap(SkBitmap* bitmap, bool copyState) override {
LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
}
@@ -244,6 +243,7 @@
private:
CanvasState mState;
+ std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
enum DeferredBarrierType {
kBarrier_None,
diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h
deleted file mode 100644
index fc29f7ac1..0000000
--- a/libs/hwui/Fence.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_FENCE_H
-#define ANDROID_HWUI_FENCE_H
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Creating a Fence instance inserts a new sync fence in the OpenGL
- * commands stream. The caller can then wait for the fence to be signaled
- * by calling the wait method.
- */
-class Fence {
-public:
- enum {
- /**
- * Default timeout in nano-seconds for wait()
- */
- kDefaultTimeout = 1000000000
- };
-
- /**
- * Inserts a new sync fence in the OpenGL commands stream.
- */
- Fence() {
- mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (mDisplay != EGL_NO_DISPLAY) {
- mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, nullptr);
- } else {
- mFence = EGL_NO_SYNC_KHR;
- }
- }
-
- /**
- * Destroys the fence. Any caller waiting on the fence will be
- * signaled immediately.
- */
- ~Fence() {
- if (mFence != EGL_NO_SYNC_KHR) {
- eglDestroySyncKHR(mDisplay, mFence);
- }
- }
-
- /**
- * Blocks the calling thread until this fence is signaled, or until
- * <timeout> nanoseconds have passed.
- *
- * Returns true if waiting for the fence was successful, false if
- * a timeout or an error occurred.
- */
- bool wait(EGLTimeKHR timeout = kDefaultTimeout) {
- EGLint waitStatus = eglClientWaitSyncKHR(mDisplay, mFence,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, timeout);
- if (waitStatus == EGL_FALSE) {
- ALOGW("Failed to wait for the fence %#x", eglGetError());
- }
- return waitStatus == EGL_CONDITION_SATISFIED_KHR;
- }
-
-private:
- EGLDisplay mDisplay;
- EGLSyncKHR mFence;
-
-}; // class Fence
-
-/**
- * An AutoFence creates a Fence instance and waits for the fence
- * to be signaled when the AutoFence is destroyed. This is useful
- * to automatically wait for a series of OpenGL commands to be
- * executed. For example:
- *
- * void drawAndWait() {
- * glDrawElements();
- * AutoFence fence;
- * }
- */
-class AutoFence {
-public:
- AutoFence(EGLTimeKHR timeout = Fence::kDefaultTimeout): mTimeout(timeout) {
- }
-
- ~AutoFence() {
- mFence.wait(mTimeout);
- }
-
-private:
- EGLTimeKHR mTimeout;
- Fence mFence;
-
-}; // class AutoFence
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_FENCE_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ab6f0ce..b56ce4f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -18,7 +18,6 @@
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
-#include "Fence.h"
#include "GammaFontRenderer.h"
#include "Patch.h"
#include "PathTessellator.h"
@@ -502,7 +501,7 @@
updateLayers();
flushLayers();
// Wait for all the layer updates to be executed
- AutoFence fence;
+ glFinish();
}
void OpenGLRenderer::markLayersAsBuildLayers() {
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 7fdbf9a..efbb709 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -46,82 +46,87 @@
canvas->ref();
}
- virtual SkCanvas* getSkCanvas() {
+ virtual SkCanvas* asSkCanvas() override {
return mCanvas.get();
}
- virtual void setBitmap(SkBitmap* bitmap, bool copyState);
+ virtual void setBitmap(SkBitmap* bitmap, bool copyState) override;
- virtual bool isOpaque();
- virtual int width();
- virtual int height();
+ virtual bool isOpaque() override;
+ virtual int width() override;
+ virtual int height() override;
- virtual int getSaveCount() const;
- virtual int save(SkCanvas::SaveFlags flags);
- virtual void restore();
- virtual void restoreToCount(int saveCount);
+ virtual int getSaveCount() const override;
+ virtual int save(SkCanvas::SaveFlags flags) override;
+ virtual void restore() override;
+ virtual void restoreToCount(int saveCount) override;
virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, SkCanvas::SaveFlags flags);
+ const SkPaint* paint, SkCanvas::SaveFlags flags) override;
virtual int saveLayerAlpha(float left, float top, float right, float bottom,
- int alpha, SkCanvas::SaveFlags flags);
+ int alpha, SkCanvas::SaveFlags flags) override;
- virtual void getMatrix(SkMatrix* outMatrix) const;
- virtual void setMatrix(const SkMatrix& matrix);
- virtual void concat(const SkMatrix& matrix);
- virtual void rotate(float degrees);
- virtual void scale(float sx, float sy);
- virtual void skew(float sx, float sy);
- virtual void translate(float dx, float dy);
+ virtual void getMatrix(SkMatrix* outMatrix) const override;
+ virtual void setMatrix(const SkMatrix& matrix) override;
+ virtual void concat(const SkMatrix& matrix) override;
+ virtual void rotate(float degrees) override;
+ virtual void scale(float sx, float sy) override;
+ virtual void skew(float sx, float sy) override;
+ virtual void translate(float dx, float dy) override;
- virtual bool getClipBounds(SkRect* outRect) const;
- virtual bool quickRejectRect(float left, float top, float right, float bottom) const;
- virtual bool quickRejectPath(const SkPath& path) const;
- virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual bool clipPath(const SkPath* path, SkRegion::Op op);
- virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
+ virtual bool getClipBounds(SkRect* outRect) const override;
+ virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
+ virtual bool quickRejectPath(const SkPath& path) const override;
+ virtual bool clipRect(float left, float top, float right, float bottom,
+ SkRegion::Op op) override;
+ virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
+ virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
- virtual SkDrawFilter* getDrawFilter();
- virtual void setDrawFilter(SkDrawFilter* drawFilter);
+ virtual SkDrawFilter* getDrawFilter() override;
+ virtual void setDrawFilter(SkDrawFilter* drawFilter) override;
- virtual void drawColor(int color, SkXfermode::Mode mode);
- virtual void drawPaint(const SkPaint& paint);
+ virtual void drawColor(int color, SkXfermode::Mode mode) override;
+ virtual void drawPaint(const SkPaint& paint) override;
- virtual void drawPoint(float x, float y, const SkPaint& paint);
- virtual void drawPoints(const float* points, int count, const SkPaint& paint);
+ virtual void drawPoint(float x, float y, const SkPaint& paint) override;
+ virtual void drawPoints(const float* points, int count, const SkPaint& paint) override;
virtual void drawLine(float startX, float startY, float stopX, float stopY,
- const SkPaint& paint);
- virtual void drawLines(const float* points, int count, const SkPaint& paint);
- virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint);
+ const SkPaint& paint) override;
+ virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
+ virtual void drawRect(float left, float top, float right, float bottom,
+ const SkPaint& paint) override;
virtual void drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint& paint);
- virtual void drawCircle(float x, float y, float radius, const SkPaint& paint);
- virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint);
+ float rx, float ry, const SkPaint& paint) override;
+ virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
+ virtual void drawOval(float left, float top, float right, float bottom,
+ const SkPaint& paint) override;
virtual void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint);
- virtual void drawPath(const SkPath& path, const SkPaint& paint);
+ float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
+ virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
const float* verts, const float* tex, const int* colors,
- const uint16_t* indices, int indexCount, const SkPaint& paint);
+ const uint16_t* indices, int indexCount, const SkPaint& paint) override;
- virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint);
- virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, float left, float top,
+ const SkPaint* paint) override;
+ virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+ const SkPaint* paint) override;
virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint);
+ float dstRight, float dstBottom, const SkPaint* paint) override;
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
- const float* vertices, const int* colors, const SkPaint* paint);
+ const float* vertices, const int* colors, const SkPaint* paint) override;
virtual void drawText(const uint16_t* text, const float* positions, int count,
const SkPaint& paint, float x, float y,
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
- float totalAdvance);
+ float totalAdvance) override;
virtual void drawPosText(const uint16_t* text, const float* positions, int count,
- int posCount, const SkPaint& paint);
+ int posCount, const SkPaint& paint) override;
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
- float hOffset, float vOffset, const SkPaint& paint);
+ float hOffset, float vOffset, const SkPaint& paint) override;
- virtual bool drawTextAbsolutePos() const { return true; }
+ virtual bool drawTextAbsolutePos() const override { return true; }
private:
struct SaveRec {
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
new file mode 100644
index 0000000..de5f91c
--- /dev/null
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SkiaCanvasProxy.h"
+
+#include <cutils/log.h>
+#include <SkPatchUtils.h>
+
+namespace android {
+namespace uirenderer {
+
+SkiaCanvasProxy::SkiaCanvasProxy(Canvas* canvas)
+ : INHERITED(canvas->width(), canvas->height())
+ , mCanvas(canvas) {}
+
+void SkiaCanvasProxy::onDrawPaint(const SkPaint& paint) {
+ mCanvas->drawPaint(paint);
+}
+
+void SkiaCanvasProxy::onDrawPoints(PointMode pointMode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) {
+ // convert the SkPoints into floats
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ const size_t floatCount = count << 1;
+ const float* floatArray = &pts[0].fX;
+
+ switch (pointMode) {
+ case kPoints_PointMode: {
+ mCanvas->drawPoints(floatArray, floatCount, paint);
+ break;
+ }
+ case kLines_PointMode: {
+ mCanvas->drawLines(floatArray, floatCount, paint);
+ break;
+ }
+ case kPolygon_PointMode: {
+ SkPaint strokedPaint(paint);
+ strokedPaint.setStyle(SkPaint::kStroke_Style);
+
+ SkPath path;
+ for (size_t i = 0; i < count - 1; i++) {
+ path.moveTo(pts[i]);
+ path.lineTo(pts[i+1]);
+ this->drawPath(path, strokedPaint);
+ path.rewind();
+ }
+ break;
+ }
+ default:
+ LOG_ALWAYS_FATAL("Unknown point type");
+ }
+}
+
+void SkiaCanvasProxy::onDrawOval(const SkRect& rect, const SkPaint& paint) {
+ mCanvas->drawOval(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint);
+}
+
+void SkiaCanvasProxy::onDrawRect(const SkRect& rect, const SkPaint& paint) {
+ mCanvas->drawRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint);
+}
+
+void SkiaCanvasProxy::onDrawRRect(const SkRRect& roundRect, const SkPaint& paint) {
+ if (!roundRect.isComplex()) {
+ const SkRect& rect = roundRect.rect();
+ SkVector radii = roundRect.getSimpleRadii();
+ mCanvas->drawRoundRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom,
+ radii.fX, radii.fY, paint);
+ } else {
+ SkPath path;
+ path.addRRect(roundRect);
+ mCanvas->drawPath(path, paint);
+ }
+}
+
+void SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) {
+ mCanvas->drawPath(path, paint);
+}
+
+void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint) {
+ mCanvas->drawBitmap(bitmap, left, top, paint);
+}
+
+void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr,
+ const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags) {
+ SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height());
+ mCanvas->drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
+ dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
+}
+
+void SkiaCanvasProxy::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint*) {
+ //TODO make nine-patch drawing a method on Canvas.h
+ SkDEBUGFAIL("SkiaCanvasProxy::onDrawBitmapNine is not yet supported");
+}
+
+void SkiaCanvasProxy::onDrawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint) {
+ mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+ mCanvas->setMatrix(SkMatrix::I());
+ mCanvas->drawBitmap(bitmap, left, top, paint);
+ mCanvas->restore();
+}
+
+void SkiaCanvasProxy::onDrawVertices(VertexMode mode, int vertexCount, const SkPoint vertices[],
+ const SkPoint texs[], const SkColor colors[], SkXfermode*, const uint16_t indices[],
+ int indexCount, const SkPaint& paint) {
+ // convert the SkPoints into floats
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ const int floatCount = vertexCount << 1;
+ const float* vArray = &vertices[0].fX;
+ const float* tArray = (texs) ? &texs[0].fX : NULL;
+ const int* cArray = (colors) ? (int*)colors : NULL;
+ mCanvas->drawVertices(mode, floatCount, vArray, tArray, cArray, indices, indexCount, paint);
+}
+
+SkSurface* SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
+ SkDEBUGFAIL("SkiaCanvasProxy::onNewSurface is not supported");
+ return NULL;
+}
+
+void SkiaCanvasProxy::willSave() {
+ mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+}
+
+SkCanvas::SaveLayerStrategy SkiaCanvasProxy::willSaveLayer(const SkRect* rectPtr,
+ const SkPaint* paint, SaveFlags flags) {
+ SkRect rect;
+ if (rectPtr) {
+ rect = *rectPtr;
+ } else if(!mCanvas->getClipBounds(&rect)) {
+ rect = SkRect::MakeEmpty();
+ }
+ mCanvas->saveLayer(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint, flags);
+ return SkCanvas::kNoLayer_SaveLayerStrategy;
+}
+
+void SkiaCanvasProxy::willRestore() {
+ mCanvas->restore();
+}
+
+void SkiaCanvasProxy::didConcat(const SkMatrix& matrix) {
+ mCanvas->concat(matrix);
+}
+
+void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) {
+ mCanvas->setMatrix(matrix);
+}
+
+void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ SkPath path;
+ path.addRRect(outer);
+ path.addRRect(inner);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ this->drawPath(path, paint);
+}
+
+/**
+ * Utility class that converts the incoming text & paint from the given encoding
+ * into glyphIDs.
+ */
+class GlyphIDConverter {
+public:
+ GlyphIDConverter(const void* text, size_t byteLength, const SkPaint& origPaint) {
+ paint = origPaint;
+ if (paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding) {
+ glyphIDs = (uint16_t*)text;
+ count = byteLength >> 1;
+ } else {
+ storage.reset(byteLength); // ensures space for one glyph per ID given UTF8 encoding.
+ glyphIDs = storage.get();
+ count = paint.textToGlyphs(text, byteLength, storage.get());
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ }
+ }
+
+ SkPaint paint;
+ uint16_t* glyphIDs;
+ int count;
+private:
+ SkAutoSTMalloc<32, uint16_t> storage;
+};
+
+void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+
+ // compute the glyph positions
+ SkAutoSTMalloc<32, SkPoint> pointStorage(glyphs.count);
+ SkAutoSTMalloc<32, SkScalar> glyphWidths(glyphs.count);
+ glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get());
+
+ // compute conservative bounds
+ // NOTE: We could call the faster paint.getFontBounds for a less accurate,
+ // but even more conservative bounds if this is too slow.
+ SkRect bounds;
+ glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
+
+ // adjust for non-left alignment
+ if (glyphs.paint.getTextAlign() != SkPaint::kLeft_Align) {
+ SkScalar stop = 0;
+ for (int i = 0; i < glyphs.count; i++) {
+ stop += glyphWidths[i];
+ }
+ if (glyphs.paint.getTextAlign() == SkPaint::kCenter_Align) {
+ stop = SkScalarHalf(stop);
+ }
+ if (glyphs.paint.isVerticalText()) {
+ y -= stop;
+ } else {
+ x -= stop;
+ }
+ }
+
+ // setup the first glyph position and adjust bounds if needed
+ if (mCanvas->drawTextAbsolutePos()) {
+ bounds.offset(x,y);
+ pointStorage[0].set(x, y);
+ } else {
+ pointStorage[0].set(0, 0);
+ }
+
+ // setup the remaining glyph positions
+ if (glyphs.paint.isVerticalText()) {
+ for (int i = 1; i < glyphs.count; i++) {
+ pointStorage[i].set(x, glyphWidths[i-1] + pointStorage[i-1].fY);
+ }
+ } else {
+ for (int i = 1; i < glyphs.count; i++) {
+ pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, y);
+ }
+ }
+
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
+ x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+}
+
+void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+
+ // convert to relative positions if necessary
+ int x, y;
+ const SkPoint* posArray;
+ SkAutoSTMalloc<32, SkPoint> pointStorage;
+ if (mCanvas->drawTextAbsolutePos()) {
+ x = 0;
+ y = 0;
+ posArray = pos;
+ } else {
+ x = pos[0].fX;
+ y = pos[0].fY;
+ posArray = pointStorage.reset(glyphs.count);
+ for (int i = 0; i < glyphs.count; i++) {
+ pointStorage[i].fX = pos[i].fX- x;
+ pointStorage[i].fY = pos[i].fY- y;
+ }
+ }
+
+ // compute conservative bounds
+ // NOTE: We could call the faster paint.getFontBounds for a less accurate,
+ // but even more conservative bounds if this is too slow.
+ SkRect bounds;
+ glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
+
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
+ bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+}
+
+void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint& paint) {
+ const size_t pointCount = byteLength >> 1;
+ SkAutoSTMalloc<32, SkPoint> storage(pointCount);
+ SkPoint* pts = storage.get();
+ for (size_t i = 0; i < pointCount; i++) {
+ pts[i].set(xpos[i], constY);
+ }
+ this->onDrawPosText(text, byteLength, pts, paint);
+}
+
+void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+ mCanvas->drawTextOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint);
+}
+
+void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextBlob is not supported");
+}
+
+void SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+ SkPatchUtils::VertexData data;
+
+ SkMatrix matrix;
+ mCanvas->getMatrix(&matrix);
+ SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix);
+
+ // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
+ // If it fails to generate the vertices, then we do not draw.
+ if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
+ this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+ data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
+ paint);
+ }
+}
+
+void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) {
+ mCanvas->clipRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, op);
+}
+
+void SkiaCanvasProxy::onClipRRect(const SkRRect& roundRect, SkRegion::Op op, ClipEdgeStyle) {
+ SkPath path;
+ path.addRRect(roundRect);
+ mCanvas->clipPath(&path, op);
+}
+
+void SkiaCanvasProxy::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) {
+ mCanvas->clipPath(&path, op);
+}
+
+void SkiaCanvasProxy::onClipRegion(const SkRegion& region, SkRegion::Op op) {
+ mCanvas->clipRegion(®ion, op);
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h
new file mode 100644
index 0000000..4322fcf
--- /dev/null
+++ b/libs/hwui/SkiaCanvasProxy.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkiaCanvasProxy_DEFINED
+#define SkiaCanvasProxy_DEFINED
+
+#include <cutils/compiler.h>
+#include <SkCanvas.h>
+
+#include "Canvas.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * This class serves as a proxy between Skia's SkCanvas and Android Framework's
+ * Canvas. The class does not maintain any state and will pass through any request
+ * directly to the Canvas provided in the constructor.
+ *
+ * Upon construction it is expected that the provided Canvas has already been
+ * prepared for recording and will continue to be in the recording state while
+ * this proxy class is being used.
+ */
+class ANDROID_API SkiaCanvasProxy : public SkCanvas {
+public:
+ SkiaCanvasProxy(Canvas* canvas);
+ virtual ~SkiaCanvasProxy() {}
+
+protected:
+
+ virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
+
+ virtual void willSave() override;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+ virtual void willRestore() override;
+
+ virtual void didConcat(const SkMatrix&) override;
+ virtual void didSetMatrix(const SkMatrix&) override;
+
+ virtual void onDrawPaint(const SkPaint& paint) override;
+ virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[],
+ const SkPaint&) override;
+ virtual void onDrawOval(const SkRect&, const SkPaint&) override;
+ virtual void onDrawRect(const SkRect&, const SkPaint&) override;
+ virtual void onDrawRRect(const SkRRect&, const SkPaint&) override;
+ virtual void onDrawPath(const SkPath& path, const SkPaint&) override;
+ virtual void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
+ const SkPaint*) override;
+ virtual void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
+ const SkPaint* paint, DrawBitmapRectFlags flags) override;
+ virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint*) override;
+ virtual void onDrawSprite(const SkBitmap&, int left, int top,
+ const SkPaint*) override;
+ virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
+ const SkPoint texs[], const SkColor colors[], SkXfermode*,
+ const uint16_t indices[], int indexCount,
+ const SkPaint&) override;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
+
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) override;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) override;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) override;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) override;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) override;
+
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) override;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) override;
+
+private:
+ Canvas* mCanvas;
+
+ typedef SkCanvas INHERITED;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // SkiaCanvasProxy_DEFINED
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 8eda7c9..5e02844 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -43,7 +43,9 @@
mStencil = new Stencil();
// This is delayed because the first access of Caches makes GL calls
- mCaches = &Caches::createInstance(*this);
+ if (!mCaches) {
+ mCaches = &Caches::createInstance(*this);
+ }
mCaches->init();
mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
}
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index f2337cb..3afca2f 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -22,10 +22,13 @@
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <EGL/eglext.h>
#define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions"
#define GLES_VERSION 2
+#define WAIT_FOR_GPU_COMPLETION 0
+
// Android-specific addition that is used to show when frames began in systrace
EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
@@ -260,6 +263,14 @@
bool EglManager::swapBuffers(EGLSurface surface) {
mInFrame = false;
+
+#if WAIT_FOR_GPU_COMPLETION
+ {
+ ATRACE_NAME("Finishing GPU work");
+ fence();
+ }
+#endif
+
eglSwapBuffers(mEglDisplay, surface);
EGLint err = eglGetError();
if (CC_LIKELY(err == EGL_SUCCESS)) {
@@ -278,6 +289,13 @@
return false;
}
+void EglManager::fence() {
+ EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ eglClientWaitSyncKHR(mEglDisplay, fence,
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
+ eglDestroySyncKHR(mEglDisplay, fence);
+}
+
void EglManager::cancelFrame() {
mInFrame = false;
}
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index e12db3a..b1a18a9 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -55,6 +55,8 @@
void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
+ void fence();
+
private:
friend class RenderThread;
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index fcf222b..bf3387b 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -170,6 +170,9 @@
* Converts a coordinate to a String representation. The outputType
* may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
* The coordinate must be a valid double between -180.0 and 180.0.
+ * This conversion is performed in a method that is dependent on the
+ * default locale, and so is not guaranteed to round-trip with
+ * {@link #convert(String)}.
*
* @throws IllegalArgumentException if coordinate is less than
* -180.0, greater than 180.0, or is not a number.
@@ -217,7 +220,9 @@
/**
* Converts a String in one of the formats described by
* FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a
- * double.
+ * double. This conversion is performed in a locale agnostic
+ * method, and so is not guaranteed to round-trip with
+ * {@link #convert(double, int)}.
*
* @throws NullPointerException if coordinate is null
* @throws IllegalArgumentException if the coordinate is not
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 9bcf3c8..f448dc2 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -346,6 +346,31 @@
*/
public static final int ADJUST_SAME = 0;
+ /**
+ * Mute the volume. Has no effect if the stream is already muted.
+ *
+ * @see #adjustVolume(int, int)
+ * @see #adjustStreamVolume(int, int, int)
+ */
+ public static final int ADJUST_MUTE = -100;
+
+ /**
+ * Unmute the volume. Has no effect if the stream is not muted.
+ *
+ * @see #adjustVolume(int, int)
+ * @see #adjustStreamVolume(int, int, int)
+ */
+ public static final int ADJUST_UNMUTE = 100;
+
+ /**
+ * Toggle the mute state. If muted the stream will be unmuted. If not muted
+ * the stream will be muted.
+ *
+ * @see #adjustVolume(int, int)
+ * @see #adjustStreamVolume(int, int, int)
+ */
+ public static final int ADJUST_TOGGLE_MUTE = 101;
+
// Flags should be powers of 2!
/**
@@ -777,13 +802,17 @@
* screen is showing. Another example, if music is playing in the background
* and a call is not active, the music stream will be adjusted.
* <p>
- * This method should only be used by applications that replace the platform-wide
- * management of audio settings or the main telephony application.
- * <p>This method has no effect if the device implements a fixed volume policy
+ * This method should only be used by applications that replace the
+ * platform-wide management of audio settings or the main telephony
+ * application.
+ * <p>
+ * This method has no effect if the device implements a fixed volume policy
* as indicated by {@link #isVolumeFixed()}.
+ *
* @param direction The direction to adjust the volume. One of
- * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
- * {@link #ADJUST_SAME}.
+ * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+ * {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+ * {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
* @param flags One or more flags.
* @see #adjustSuggestedStreamVolume(int, int, int)
* @see #adjustStreamVolume(int, int, int)
@@ -808,16 +837,20 @@
* Adjusts the volume of the most relevant stream, or the given fallback
* stream.
* <p>
- * This method should only be used by applications that replace the platform-wide
- * management of audio settings or the main telephony application.
- *
- * <p>This method has no effect if the device implements a fixed volume policy
+ * This method should only be used by applications that replace the
+ * platform-wide management of audio settings or the main telephony
+ * application.
+ * <p>
+ * This method has no effect if the device implements a fixed volume policy
* as indicated by {@link #isVolumeFixed()}.
+ *
* @param direction The direction to adjust the volume. One of
- * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
- * {@link #ADJUST_SAME}.
+ * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+ * {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+ * {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
* @param suggestedStreamType The stream type that will be used if there
- * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is valid here.
+ * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is
+ * valid here.
* @param flags One or more flags.
* @see #adjustVolume(int, int)
* @see #adjustStreamVolume(int, int, int)
@@ -1088,72 +1121,72 @@
}
/**
- * Solo or unsolo a particular stream. All other streams are muted.
+ * Solo or unsolo a particular stream.
* <p>
- * The solo command is protected against client process death: if a process
- * with an active solo request on a stream dies, all streams that were muted
- * because of this request will be unmuted automatically.
- * <p>
- * The solo requests for a given stream are cumulative: the AudioManager
- * can receive several solo requests from one or more clients and the stream
- * will be unsoloed only when the same number of unsolo requests are received.
- * <p>
- * For a better user experience, applications MUST unsolo a soloed stream
- * in onPause() and solo is again in onResume() if appropriate.
- * <p>This method has no effect if the device implements a fixed volume policy
- * as indicated by {@link #isVolumeFixed()}.
+ * Do not use. This method has been deprecated and is now a no-op.
+ * {@link #requestAudioFocus} should be used for exclusive audio playback.
*
* @param streamType The stream to be soloed/unsoloed.
- * @param state The required solo state: true for solo ON, false for solo OFF
- *
+ * @param state The required solo state: true for solo ON, false for solo
+ * OFF
* @see #isVolumeFixed()
+ * @deprecated Do not use. If you need exclusive audio playback use
+ * {@link #requestAudioFocus}.
*/
+ @Deprecated
public void setStreamSolo(int streamType, boolean state) {
- IAudioService service = getService();
- try {
- service.setStreamSolo(streamType, state, mICallBack);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setStreamSolo", e);
- }
+ Log.w(TAG, "setStreamSolo has been deprecated. Do not use.");
}
/**
* Mute or unmute an audio stream.
* <p>
- * The mute command is protected against client process death: if a process
- * with an active mute request on a stream dies, this stream will be unmuted
- * automatically.
+ * This method should only be used by applications that replace the
+ * platform-wide management of audio settings or the main telephony
+ * application.
* <p>
- * The mute requests for a given stream are cumulative: the AudioManager
- * can receive several mute requests from one or more clients and the stream
- * will be unmuted only when the same number of unmute requests are received.
- * <p>
- * For a better user experience, applications MUST unmute a muted stream
- * in onPause() and mute is again in onResume() if appropriate.
- * <p>
- * This method should only be used by applications that replace the platform-wide
- * management of audio settings or the main telephony application.
- * <p>This method has no effect if the device implements a fixed volume policy
+ * This method has no effect if the device implements a fixed volume policy
* as indicated by {@link #isVolumeFixed()}.
+ * <p>
+ * This method was deprecated in API level 22. Prior to API level 22 this
+ * method had significantly different behavior and should be used carefully.
+ * The following applies only to pre-22 platforms:
+ * <ul>
+ * <li>The mute command is protected against client process death: if a
+ * process with an active mute request on a stream dies, this stream will be
+ * unmuted automatically.</li>
+ * <li>The mute requests for a given stream are cumulative: the AudioManager
+ * can receive several mute requests from one or more clients and the stream
+ * will be unmuted only when the same number of unmute requests are
+ * received.</li>
+ * <li>For a better user experience, applications MUST unmute a muted stream
+ * in onPause() and mute is again in onResume() if appropriate.</li>
+ * </ul>
*
* @param streamType The stream to be muted/unmuted.
- * @param state The required mute state: true for mute ON, false for mute OFF
- *
+ * @param state The required mute state: true for mute ON, false for mute
+ * OFF
* @see #isVolumeFixed()
+ * @deprecated Use {@link #adjustStreamVolume(int, int, int)} with
+ * {@link #ADJUST_MUTE} or {@link #ADJUST_UNMUTE} instead.
*/
+ @Deprecated
public void setStreamMute(int streamType, boolean state) {
- IAudioService service = getService();
- try {
- service.setStreamMute(streamType, state, mICallBack);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setStreamMute", e);
+ Log.w(TAG, "setStreamMute is deprecated. adjustStreamVolume should be used instead.");
+ int direction = state ? ADJUST_MUTE : ADJUST_UNMUTE;
+ if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+ adjustSuggestedStreamVolume(direction, streamType, 0);
+ } else {
+ adjustStreamVolume(streamType, direction, 0);
}
}
/**
- * get stream mute state.
+ * Returns the current mute state for a particular stream.
*
- * @hide
+ * @param streamType The stream to get mute state for.
+ * @return The mute state for the given stream.
+ * @see #adjustStreamVolume(int, int, int)
*/
public boolean isStreamMute(int streamType) {
IAudioService service = getService();
@@ -1166,29 +1199,6 @@
}
/**
- * set master mute state.
- *
- * @hide
- */
- public void setMasterMute(boolean state) {
- setMasterMute(state, FLAG_SHOW_UI);
- }
-
- /**
- * set master mute state with optional flags.
- *
- * @hide
- */
- public void setMasterMute(boolean state, int flags) {
- IAudioService service = getService();
- try {
- service.setMasterMute(state, flags, mContext.getOpPackageName(), mICallBack);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setMasterMute", e);
- }
- }
-
- /**
* get master mute state.
*
* @hide
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 616bdd1..873c142 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -41,9 +41,6 @@
public abstract void adjustMasterVolumeForUid(int steps, int flags, String callingPackage,
int uid);
- public abstract void setMasterMuteForUid(boolean state, int flags, String callingPackage,
- IBinder cb, int uid);
-
public abstract void setRingerModeDelegate(RingerModeDelegate delegate);
public abstract int getRingerModeInternal();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 0ffa5fc..98a43a8 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -153,11 +153,11 @@
private final AppOpsManager mAppOps;
// the platform has no specific capabilities
- private static final int PLATFORM_DEFAULT = 0;
+ public static final int PLATFORM_DEFAULT = 0;
// the platform is voice call capable (a phone)
- private static final int PLATFORM_VOICE = 1;
+ public static final int PLATFORM_VOICE = 1;
// the platform is a television or a set-top box
- private static final int PLATFORM_TELEVISION = 2;
+ public static final int PLATFORM_TELEVISION = 2;
// the platform type affects volume and silent mode behavior
private final int mPlatformType;
@@ -546,15 +546,7 @@
mContentResolver = context.getContentResolver();
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
- if (mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_voice_capable)) {
- mPlatformType = PLATFORM_VOICE;
- } else if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LEANBACK)) {
- mPlatformType = PLATFORM_TELEVISION;
- } else {
- mPlatformType = PLATFORM_DEFAULT;
- }
+ mPlatformType = getPlatformType(context);
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
@@ -667,6 +659,26 @@
LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
}
+ /**
+ * Return the platform type that this is running on. One of:
+ * <ul>
+ * <li>{@link #PLATFORM_VOICE}</li>
+ * <li>{@link #PLATFORM_TELEVISION}</li>
+ * <li>{@link #PLATFORM_DEFAULT}</li>
+ * </ul>
+ */
+ public static int getPlatformType(Context context) {
+ if (context.getResources().getBoolean(
+ com.android.internal.R.bool.config_voice_capable)) {
+ return PLATFORM_VOICE;
+ } else if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK)) {
+ return PLATFORM_TELEVISION;
+ } else {
+ return PLATFORM_DEFAULT;
+ }
+ }
+
public void systemReady() {
sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
0, 0, null, 0);
@@ -748,7 +760,7 @@
setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]]);
}
// apply stream volume
- if (!mStreamStates[streamType].isMuted_syncVSS()) {
+ if (!mStreamStates[streamType].mIsMuted) {
mStreamStates[streamType].applyAllVolumes();
}
}
@@ -970,6 +982,7 @@
if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream="+suggestedStreamType
+ ", flags=" + flags);
int streamType;
+ boolean isMute = isMuteAdjust(direction);
if (mVolumeControlStream != -1) {
streamType = mVolumeControlStream;
} else {
@@ -984,7 +997,8 @@
}
// For notifications/ring, show the ui before making any adjustments
- if (mVolumeController.suppressAdjustment(resolvedStream, flags)) {
+ // Don't suppress mute/unmute requests
+ if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
direction = 0;
flags &= ~AudioManager.FLAG_PLAY_SOUND;
flags &= ~AudioManager.FLAG_VIBRATE;
@@ -1011,10 +1025,17 @@
ensureValidDirection(direction);
ensureValidStreamType(streamType);
+ boolean isMuteAdjust = isMuteAdjust(direction);
+
// use stream type alias here so that streams with same alias have the same behavior,
// including with regard to silent mode control (e.g the use of STREAM_RING below and in
// checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
int streamTypeAlias = mStreamVolumeAlias[streamType];
+
+ if (isMuteAdjust && !isStreamAffectedByMute(streamTypeAlias)) {
+ return;
+ }
+
VolumeStreamState streamState = mStreamStates[streamTypeAlias];
final int device = getDeviceForStream(streamTypeAlias);
@@ -1100,13 +1121,37 @@
}
}
- if ((direction == AudioManager.ADJUST_RAISE) &&
+ if (isMuteAdjust) {
+ boolean state;
+ if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
+ state = !streamState.mIsMuted;
+ } else {
+ state = direction == AudioManager.ADJUST_MUTE;
+ }
+ if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
+ setSystemAudioMute(state);
+ }
+ for (int stream = 0; stream < mStreamStates.length; stream++) {
+ if (streamTypeAlias == mStreamVolumeAlias[stream]) {
+ mStreamStates[stream].mute(state);
+
+ Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
+ intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, stream);
+ intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
+ sendBroadcastToAll(intent);
+ }
+ }
+ } else if ((direction == AudioManager.ADJUST_RAISE) &&
!checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
- Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);
+ Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
mVolumeController.postDisplaySafeVolumeWarning(flags);
- } else if (streamState.adjustIndex(direction * step, device)) {
- // Post message to set system volume (it in turn will post a message
- // to persist). Do not change volume if stream is muted.
+ } else if (streamState.adjustIndex(direction * step, device) || streamState.mIsMuted) {
+ // Post message to set system volume (it in turn will post a
+ // message to persist).
+ if (streamState.mIsMuted) {
+ // Unmute the stream if it was previously muted
+ streamState.mute(false);
+ }
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
SENDMSG_QUEUE,
@@ -1116,7 +1161,7 @@
0);
}
- // Check if volume update should be send to Hdmi system audio.
+ // Check if volume update should be sent to Hdmi system audio.
int newIndex = mStreamStates[streamType].getIndex(device);
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
@@ -1129,7 +1174,7 @@
oldIndex != newIndex) {
synchronized (mHdmiPlaybackClient) {
int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN :
- KeyEvent.KEYCODE_VOLUME_UP;
+ KeyEvent.KEYCODE_VOLUME_UP;
mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
}
@@ -1172,6 +1217,10 @@
if (mUseFixedVolume) {
return;
}
+ if (isMuteAdjust(steps)) {
+ setMasterMuteInternal(steps, flags, callingPackage, uid);
+ return;
+ }
ensureValidSteps(steps);
int volume = Math.round(AudioSystem.getMasterVolume() * MAX_MASTER_VOLUME);
int delta = 0;
@@ -1500,46 +1549,6 @@
}
}
- /** @see AudioManager#setStreamSolo(int, boolean) */
- public void setStreamSolo(int streamType, boolean state, IBinder cb) {
- if (mUseFixedVolume) {
- return;
- }
- int streamAlias = mStreamVolumeAlias[streamType];
- for (int stream = 0; stream < mStreamStates.length; stream++) {
- if (!isStreamAffectedByMute(streamAlias) || streamAlias == mStreamVolumeAlias[stream]) {
- continue;
- }
- mStreamStates[stream].mute(cb, state);
- }
- }
-
- /** @see AudioManager#setStreamMute(int, boolean) */
- public void setStreamMute(int streamType, boolean state, IBinder cb) {
- if (mUseFixedVolume) {
- return;
- }
- if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
- streamType = getActiveStreamType(streamType);
- }
- int streamAlias = mStreamVolumeAlias[streamType];
- if (isStreamAffectedByMute(streamAlias)) {
- if (streamAlias == AudioSystem.STREAM_MUSIC) {
- setSystemAudioMute(state);
- }
- for (int stream = 0; stream < mStreamStates.length; stream++) {
- if (streamAlias == mStreamVolumeAlias[stream]) {
- mStreamStates[stream].mute(cb, state);
-
- Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
- intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, stream);
- intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
- sendBroadcastToAll(intent);
- }
- }
- }
- }
-
private void setSystemAudioMute(boolean state) {
if (mHdmiManager == null || mHdmiTvClient == null) return;
synchronized (mHdmiManager) {
@@ -1561,7 +1570,7 @@
streamType = getActiveStreamType(streamType);
}
synchronized (VolumeStreamState.class) {
- return mStreamStates[streamType].isMuted_syncVSS();
+ return mStreamStates[streamType].mIsMuted;
}
}
@@ -1665,20 +1674,17 @@
}
}
- /** @see AudioManager#setMasterMute(boolean, int) */
- public void setMasterMute(boolean state, int flags, String callingPackage, IBinder cb) {
- setMasterMuteInternal(state, flags, callingPackage, cb, Binder.getCallingUid());
- }
-
- private void setMasterMuteInternal(boolean state, int flags, String callingPackage, IBinder cb,
- int uid) {
- if (mUseFixedVolume) {
- return;
- }
+ private void setMasterMuteInternal(int adjust, int flags, String callingPackage, int uid) {
if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage)
!= AppOpsManager.MODE_ALLOWED) {
return;
}
+ boolean state;
+ if (adjust == AudioManager.ADJUST_TOGGLE_MUTE) {
+ state = !AudioSystem.getMasterMute();
+ } else {
+ state = adjust == AudioManager.ADJUST_MUTE;
+ }
if (state != AudioSystem.getMasterMute()) {
setSystemAudioMute(state);
AudioSystem.setMasterMute(state);
@@ -1714,7 +1720,7 @@
int index = mStreamStates[streamType].getIndex(device);
// by convention getStreamVolume() returns 0 when a stream is muted.
- if (mStreamStates[streamType].isMuted_syncVSS()) {
+ if (mStreamStates[streamType].mIsMuted) {
index = 0;
}
if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
@@ -1934,11 +1940,11 @@
}
}
}
- mStreamStates[streamType].mute(null, false);
+ mStreamStates[streamType].mute(false);
mRingerModeMutedStreams &= ~(1 << streamType);
} else {
// mute
- mStreamStates[streamType].mute(null, true);
+ mStreamStates[streamType].mute(true);
mRingerModeMutedStreams |= (1 << streamType);
}
}
@@ -2426,13 +2432,9 @@
streamState.readSettings();
synchronized (VolumeStreamState.class) {
// unmute stream that was muted but is not affect by mute anymore
- if (streamState.isMuted_syncVSS() && ((!isStreamAffectedByMute(streamType) &&
+ if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
!isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
- int size = streamState.mDeathHandlers.size();
- for (int i = 0; i < size; i++) {
- streamState.mDeathHandlers.get(i).mMuteCount = 1;
- streamState.mDeathHandlers.get(i).mute_syncVSS(false);
- }
+ streamState.mIsMuted = false;
}
}
}
@@ -3221,8 +3223,16 @@
}
private void ensureValidDirection(int direction) {
- if (direction < AudioManager.ADJUST_LOWER || direction > AudioManager.ADJUST_RAISE) {
- throw new IllegalArgumentException("Bad direction " + direction);
+ switch (direction) {
+ case AudioManager.ADJUST_LOWER:
+ case AudioManager.ADJUST_RAISE:
+ case AudioManager.ADJUST_SAME:
+ case AudioManager.ADJUST_MUTE:
+ case AudioManager.ADJUST_UNMUTE:
+ case AudioManager.ADJUST_TOGGLE_MUTE:
+ break;
+ default:
+ throw new IllegalArgumentException("Bad direction " + direction);
}
}
@@ -3238,6 +3248,11 @@
}
}
+ private boolean isMuteAdjust(int adjust) {
+ return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
+ || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
+ }
+
private boolean isInCommunication() {
boolean IsInCall = false;
@@ -3467,11 +3482,11 @@
public class VolumeStreamState {
private final int mStreamType;
+ private boolean mIsMuted;
private String mVolumeIndexSettingName;
private int mIndexMax;
private final ConcurrentHashMap<Integer, Integer> mIndex =
new ConcurrentHashMap<Integer, Integer>(8, 0.75f, 4);
- private ArrayList<VolumeDeathHandler> mDeathHandlers; //handles mute/solo clients death
private VolumeStreamState(String settingName, int streamType) {
@@ -3482,9 +3497,6 @@
AudioSystem.initStreamVolume(streamType, 0, mIndexMax);
mIndexMax *= 10;
- // mDeathHandlers must be created before calling readSettings()
- mDeathHandlers = new ArrayList<VolumeDeathHandler>();
-
readSettings();
}
@@ -3549,7 +3561,7 @@
// must be called while synchronized VolumeStreamState.class
public void applyDeviceVolume_syncVSS(int device) {
int index;
- if (isMuted_syncVSS()) {
+ if (mIsMuted) {
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported)
|| ((device & mFullVolumeDevices) != 0)) {
@@ -3565,7 +3577,7 @@
// apply default volume first: by convention this will reset all
// devices volumes in audio policy manager to the supplied value
int index;
- if (isMuted_syncVSS()) {
+ if (mIsMuted) {
index = 0;
} else {
index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
@@ -3578,7 +3590,7 @@
Map.Entry entry = (Map.Entry)i.next();
int device = ((Integer)entry.getKey()).intValue();
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
- if (isMuted_syncVSS()) {
+ if (mIsMuted) {
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
mAvrcpAbsVolSupported)
@@ -3688,14 +3700,20 @@
}
}
- public void mute(IBinder cb, boolean state) {
+ public void mute(boolean state) {
synchronized (VolumeStreamState.class) {
- VolumeDeathHandler handler = getDeathHandler_syncVSS(cb, state);
- if (handler == null) {
- Log.e(TAG, "Could not get client death handler for stream: "+mStreamType);
- return;
+ if (state != mIsMuted) {
+ mIsMuted = state;
+ // Set the new mute volume. This propagates the values to
+ // the audio system, otherwise the volume won't be changed
+ // at the lower level.
+ sendMsg(mAudioHandler,
+ MSG_SET_ALL_VOLUMES,
+ SENDMSG_QUEUE,
+ 0,
+ 0,
+ this, 0);
}
- handler.mute_syncVSS(state);
}
}
@@ -3733,117 +3751,9 @@
return index;
}
- private class VolumeDeathHandler implements IBinder.DeathRecipient {
- private IBinder mICallback; // To be notified of client's death
- private int mMuteCount; // Number of active mutes for this client
-
- VolumeDeathHandler(IBinder cb) {
- mICallback = cb;
- }
-
- // must be called while synchronized VolumeStreamState.class
- public void mute_syncVSS(boolean state) {
- boolean updateVolume = false;
- if (state) {
- if (mMuteCount == 0) {
- // Register for client death notification
- try {
- // mICallback can be 0 if muted by AudioService
- if (mICallback != null) {
- mICallback.linkToDeath(this, 0);
- }
- VolumeStreamState.this.mDeathHandlers.add(this);
- // If the stream is not yet muted by any client, set level to 0
- if (!VolumeStreamState.this.isMuted_syncVSS()) {
- updateVolume = true;
- }
- } catch (RemoteException e) {
- // Client has died!
- binderDied();
- return;
- }
- } else {
- Log.w(TAG, "stream: "+mStreamType+" was already muted by this client");
- }
- mMuteCount++;
- } else {
- if (mMuteCount == 0) {
- Log.e(TAG, "unexpected unmute for stream: "+mStreamType);
- } else {
- mMuteCount--;
- if (mMuteCount == 0) {
- // Unregister from client death notification
- VolumeStreamState.this.mDeathHandlers.remove(this);
- // mICallback can be 0 if muted by AudioService
- if (mICallback != null) {
- mICallback.unlinkToDeath(this, 0);
- }
- if (!VolumeStreamState.this.isMuted_syncVSS()) {
- updateVolume = true;
- }
- }
- }
- }
- if (updateVolume) {
- sendMsg(mAudioHandler,
- MSG_SET_ALL_VOLUMES,
- SENDMSG_QUEUE,
- 0,
- 0,
- VolumeStreamState.this, 0);
- }
- }
-
- public void binderDied() {
- Log.w(TAG, "Volume service client died for stream: "+mStreamType);
- synchronized (VolumeStreamState.class) {
- if (mMuteCount != 0) {
- // Reset all active mute requests from this client.
- mMuteCount = 1;
- mute_syncVSS(false);
- }
- }
- }
- }
-
- private int muteCount() {
- int count = 0;
- int size = mDeathHandlers.size();
- for (int i = 0; i < size; i++) {
- count += mDeathHandlers.get(i).mMuteCount;
- }
- return count;
- }
-
- // must be called while synchronized VolumeStreamState.class
- private boolean isMuted_syncVSS() {
- return muteCount() != 0;
- }
-
- // must be called while synchronized VolumeStreamState.class
- private VolumeDeathHandler getDeathHandler_syncVSS(IBinder cb, boolean state) {
- VolumeDeathHandler handler;
- int size = mDeathHandlers.size();
- for (int i = 0; i < size; i++) {
- handler = mDeathHandlers.get(i);
- if (cb == handler.mICallback) {
- return handler;
- }
- }
- // If this is the first mute request for this client, create a new
- // client death handler. Otherwise, it is an out of sequence unmute request.
- if (state) {
- handler = new VolumeDeathHandler(cb);
- } else {
- Log.w(TAG, "stream was not muted by this client");
- handler = null;
- }
- return handler;
- }
-
private void dump(PrintWriter pw) {
- pw.print(" Mute count: ");
- pw.println(muteCount());
+ pw.print(" Muted: ");
+ pw.println(mIsMuted);
pw.print(" Max: ");
pw.println((mIndexMax + 5) / 10);
pw.print(" Current: ");
@@ -5648,7 +5558,10 @@
Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
}
- public boolean suppressAdjustment(int resolvedStream, int flags) {
+ public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
+ if (isMute) {
+ return false;
+ }
boolean suppress = false;
if (resolvedStream == AudioSystem.STREAM_RING && mController != null) {
final long now = SystemClock.uptimeMillis();
@@ -5801,12 +5714,6 @@
public void setRingerModeInternal(int ringerMode, String caller) {
AudioService.this.setRingerModeInternal(ringerMode, caller);
}
-
- @Override
- public void setMasterMuteForUid(boolean state, int flags, String callingPackage, IBinder cb,
- int uid) {
- setMasterMuteInternal(state, flags, callingPackage, cb, uid);
- }
}
//==========================================================================================
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1af0372..caccb6e 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1237,8 +1237,14 @@
/**
* Flushes the audio data currently queued for playback. Any data that has
- * not been played back will be discarded. No-op if not stopped or paused,
+ * been written but not yet presented will be discarded. No-op if not stopped or paused,
* or if the track's creation mode is not {@link #MODE_STREAM}.
+ * <BR> Note that although data written but not yet presented is discarded, there is no
+ * guarantee that all of the buffer space formerly used by that data
+ * is available for a subsequent write.
+ * For example, a call to {@link #write(byte[], int, int)} with <code>sizeInBytes</code>
+ * less than or equal to the total buffer size
+ * may return a short actual transfer count.
*/
public void flush() {
if (mState == STATE_INITIALIZED) {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fad3cec..bfb78a1 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -52,16 +52,10 @@
void setMasterVolume(int index, int flags, String callingPackage);
- void setStreamSolo(int streamType, boolean state, IBinder cb);
-
- void setStreamMute(int streamType, boolean state, IBinder cb);
-
boolean isStreamMute(int streamType);
void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb);
- void setMasterMute(boolean state, int flags, String callingPackage, IBinder cb);
-
boolean isMasterMute();
int getStreamVolume(int streamType);
diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java
index 7ea269b..4ea22f9 100644
--- a/media/java/android/media/session/MediaSessionLegacyHelper.java
+++ b/media/java/android/media/session/MediaSessionLegacyHelper.java
@@ -221,14 +221,10 @@
mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE,
direction, flags);
} else if (isMute) {
- if (down) {
- // We need to send two volume events on down, one to mute
- // and one to show the UI
+ if (down && keyEvent.getRepeatCount() == 0) {
mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE,
- MediaSessionManager.DIRECTION_MUTE, flags);
+ AudioManager.ADJUST_TOGGLE_MUTE, flags);
}
- mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE,
- 0 /* direction, causes UI to show on down */, flags);
}
}
}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index a4ef851..b4fff8f 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -59,14 +59,6 @@
private Context mContext;
/**
- * Special flag for sending the mute key to dispatchAdjustVolume used by the
- * system.
- *
- * @hide
- */
- public static final int DIRECTION_MUTE = -99;
-
- /**
* @hide
*/
public MediaSessionManager(Context context) {
diff --git a/packages/Keyguard/res/layout/keyguard_host_view.xml b/packages/Keyguard/res/layout/keyguard_host_view.xml
index 3635aff..7291cd4 100644
--- a/packages/Keyguard/res/layout/keyguard_host_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_host_view.xml
@@ -26,7 +26,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
- android:clipToPadding="false">
+ android:clipToPadding="false"
+ android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent
+ from this view when bouncer is shown -->
<com.android.keyguard.KeyguardSecurityContainer
android:id="@+id/keyguard_security_container"
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index 50ac2612..4a9440c 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -50,8 +50,14 @@
updateEmergencyCallButton();
}
};
+
+ public interface EmergencyButtonCallback {
+ public void onEmergencyButtonClickedWhenInCall();
+ }
+
private LockPatternUtils mLockPatternUtils;
private PowerManager mPowerManager;
+ private EmergencyButtonCallback mEmergencyButtonCallback;
public EmergencyButton(Context context) {
this(context, null);
@@ -95,6 +101,9 @@
mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
if (mLockPatternUtils.isInCall()) {
mLockPatternUtils.resumeCall();
+ if (mEmergencyButtonCallback != null) {
+ mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
+ }
} else {
final boolean bypassHandler = true;
KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(bypassHandler);
@@ -124,4 +133,7 @@
mLockPatternUtils.updateEmergencyCallButtonState(this, enabled, false);
}
+ public void setCallback(EmergencyButtonCallback callback) {
+ mEmergencyButtonCallback = callback;
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index b03176c..6f322b6 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -32,7 +32,7 @@
* Base class for PIN and password unlock screens.
*/
public abstract class KeyguardAbsKeyInputView extends LinearLayout
- implements KeyguardSecurityView {
+ implements KeyguardSecurityView, EmergencyButton.EmergencyButtonCallback {
protected KeyguardSecurityCallback mCallback;
protected LockPatternUtils mLockPatternUtils;
protected SecurityMessageDisplay mSecurityMessageDisplay;
@@ -85,6 +85,13 @@
mLockPatternUtils = new LockPatternUtils(mContext);
mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+
+ EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
+ button.setCallback(this);
+ }
+
+ public void onEmergencyButtonClickedWhenInCall() {
+ mCallback.reset();
}
/*
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index c7bc04d..10ce426 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -29,6 +29,7 @@
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.internal.widget.LockPatternUtils;
@@ -153,6 +154,16 @@
return false;
}
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ event.getText().add(mSecurityContainer.getCurrentSecurityModeContentDescription());
+ return true;
+ } else {
+ return super.dispatchPopulateAccessibilityEvent(event);
+ }
+ }
+
protected KeyguardSecurityContainer getSecurityContainer() {
return mSecurityContainer;
}
@@ -185,6 +196,11 @@
}
@Override
+ public void reset() {
+ mViewMediatorCallback.resetKeyguard();
+ }
+
+ @Override
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
if (mViewMediatorCallback != null) {
mViewMediatorCallback.setNeedsInput(needsInput);
@@ -416,6 +432,4 @@
public SecurityMode getCurrentSecurityMode() {
return mSecurityContainer.getCurrentSecurityMode();
}
-
-
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 62f1b69..053b309 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -38,7 +38,8 @@
import java.util.List;
public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView,
- AppearAnimationCreator<LockPatternView.CellState> {
+ AppearAnimationCreator<LockPatternView.CellState>,
+ EmergencyButton.EmergencyButtonCallback {
private static final String TAG = "SecurityPatternView";
private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -140,6 +141,13 @@
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
mContainer = (ViewGroup) findViewById(R.id.container);
mHelpMessage = (KeyguardMessageArea) findViewById(R.id.keyguard_message_area);
+
+ EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
+ button.setCallback(this);
+ }
+
+ public void onEmergencyButtonClickedWhenInCall() {
+ mCallback.reset();
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
index 8bb8805..5877bc8 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -40,4 +40,8 @@
*/
void reportUnlockAttempt(boolean success);
+ /**
+ * Resets the keyguard view.
+ */
+ void reset();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 61eef48..41ec3b0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -55,6 +55,7 @@
public void userActivity();
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
public void finish();
+ public void reset();
}
public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
@@ -111,6 +112,14 @@
}
}
+ public CharSequence getCurrentSecurityModeContentDescription() {
+ View v = (View) getSecurityView(mCurrentSecuritySelection);
+ if (v != null) {
+ return v.getContentDescription();
+ }
+ return "";
+ }
+
private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
KeyguardSecurityView view = null;
@@ -406,7 +415,6 @@
}
private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
-
public void userActivity() {
if (mSecurityCallback != null) {
mSecurityCallback.userActivity();
@@ -431,6 +439,9 @@
}
}
+ public void reset() {
+ mSecurityCallback.reset();
+ }
};
// The following is used to ignore callbacks from SecurityViews that are no longer current
@@ -445,6 +456,8 @@
public boolean isVerifyUnlockOnly() { return false; }
@Override
public void dismiss(boolean securityVerified) { }
+ @Override
+ public void reset() {}
};
private int getSecurityViewIdForMode(SecurityMode securityMode) {
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index f327078..5bbcc8c 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -62,6 +62,11 @@
void readyForKeyguardDone();
/**
+ * Reset the keyguard and bouncer.
+ */
+ void resetKeyguard();
+
+ /**
* Play the "device trusted" sound.
*/
void playTrustedSound();
diff --git a/packages/SettingsLib/Android.mk b/packages/SettingsLib/Android.mk
new file mode 100644
index 0000000..0245ed3
--- /dev/null
+++ b/packages/SettingsLib/Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := SettingsLib
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/packages/SettingsLib/AndroidManifest.xml b/packages/SettingsLib/AndroidManifest.xml
new file mode 100644
index 0000000..eacafd5
--- /dev/null
+++ b/packages/SettingsLib/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.settingslib">
+</manifest>
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
new file mode 100644
index 0000000..b017047
--- /dev/null
+++ b/packages/SettingsLib/common.mk
@@ -0,0 +1,18 @@
+#
+# Include this make file to build your application against this module.
+#
+# Make sure to include it after you've set all your desired LOCAL variables.
+# Note that you must explicitly set your LOCAL_RESOURCE_DIR before including
+# this file.
+#
+# For example:
+#
+# LOCAL_RESOURCE_DIR := \
+# $(LOCAL_PATH)/res
+#
+# include frameworks/base/packages/SettingsLib/common.mk
+#
+
+LOCAL_RESOURCE_DIR += $(call my-dir)/res
+LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.android.settingslib
+LOCAL_STATIC_JAVA_LIBRARIES += SettingsLib
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
new file mode 100644
index 0000000..a0993b1
--- /dev/null
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Blank.java b/packages/SettingsLib/src/com/android/settingslib/Blank.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/Blank.java
diff --git a/packages/SettingsProvider/res/values-tl/strings.xml b/packages/SettingsProvider/res/values-tl/strings.xml
index 19219ec..0fe535e 100644
--- a/packages/SettingsProvider/res/values-tl/strings.xml
+++ b/packages/SettingsProvider/res/values-tl/strings.xml
@@ -19,5 +19,5 @@
<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="4567566098528588863">"Imbakan ng Mga Setting"</string>
+ <string name="app_label" msgid="4567566098528588863">"Storage ng Mga Setting"</string>
</resources>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index 2e95b4e..ed0697e 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -21,5 +21,5 @@
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Hata raporunuzu paylaşmak için hızlıca sola kaydırın"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Hata raporunuzu paylaşmak için dokunun"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Hata raporları, kişisel ve özel bilgiler dahil olmak üzere sistemin çeşitli günlük dosyalarından veriler içerir. Hata raporlarını sadece güvendiğiniz uygulamalar ve kişilerle paylaşın."</string>
- <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu mesajı göster"</string>
+ <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu iletiyi göster"</string>
</resources>
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 2ff9a28..47ef42a 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -20,6 +20,8 @@
$(LOCAL_PATH)/res
LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.android.keyguard
+include frameworks/base/packages/SettingsLib/common.mk
+
include $(BUILD_PACKAGE)
ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 4cf4f52d..01b2713 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -21,7 +21,8 @@
android:id="@+id/keyguard_bottom_area"
android:layout_height="match_parent"
android:layout_width="match_parent"
- >
+ android:outlineProvider="none"
+ android:elevation="5dp" > <!-- Put it above the status bar header -->
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text"
diff --git a/packages/SystemUI/res/layout/recents.xml b/packages/SystemUI/res/layout/recents.xml
index 8f367a6..26523f9 100644
--- a/packages/SystemUI/res/layout/recents.xml
+++ b/packages/SystemUI/res/layout/recents.xml
@@ -15,7 +15,7 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Status Bar Scrim View -->
<ImageView
@@ -29,9 +29,16 @@
<!-- Recents View -->
<com.android.systemui.recents.views.RecentsView
android:id="@+id/recents_view"
- android:layout_width="match_parent"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
- android:focusable="true" />
+ android:focusable="true">
+ <!-- MultiStack Debug View -->
+ <ViewStub android:id="@+id/multistack_debug_view_stub"
+ android:layout="@layout/recents_multistack_debug"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|bottom" />
+ </com.android.systemui.recents.views.RecentsView>
<!-- Empty View -->
<ViewStub android:id="@+id/empty_view_stub"
diff --git a/packages/SystemUI/res/layout/recents_multistack_debug.xml b/packages/SystemUI/res/layout/recents_multistack_debug.xml
new file mode 100644
index 0000000..6524a54
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_multistack_debug.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|bottom"
+ android:orientation="vertical">
+ <Button
+ android:id="@+id/add_stack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:padding="8dp"
+ android:textSize="20sp"
+ android:textColor="#ffffffff"
+ android:text="@string/recents_multistack_add_stack"
+ android:fontFamily="sans-serif"
+ android:background="#000000"
+ android:alpha="0.5" />
+ <Button
+ android:id="@+id/resize_stack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:padding="8dp"
+ android:textSize="20sp"
+ android:textColor="#ffffffff"
+ android:text="@string/recents_multistack_resize_stack"
+ android:fontFamily="sans-serif"
+ android:background="#000000"
+ android:alpha="0.5" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml b/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml
new file mode 100644
index 0000000..36e54a0
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:orientation="vertical"
+ android:descendantFocusability="beforeDescendants"
+ android:focusableInTouchMode="true">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <EditText
+ android:id="@+id/inset_left"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:hint="Left"
+ android:singleLine="true"
+ android:imeOptions="actionNext"
+ android:inputType="number"
+ android:selectAllOnFocus="true" />
+ <EditText
+ android:id="@+id/inset_top"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:hint="Top"
+ android:singleLine="true"
+ android:imeOptions="actionNext"
+ android:inputType="number"
+ android:selectAllOnFocus="true" />
+ <EditText
+ android:id="@+id/inset_right"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:hint="Right"
+ android:singleLine="true"
+ android:imeOptions="actionNext"
+ android:inputType="number"
+ android:selectAllOnFocus="true" />
+ <EditText
+ android:id="@+id/inset_bottom"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:hint="Bottom"
+ android:singleLine="true"
+ android:imeOptions="actionDone"
+ android:inputType="number"
+ android:selectAllOnFocus="true" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index f1d8ad0..53047a3 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -43,6 +43,16 @@
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<com.android.systemui.recents.views.FixedSizeImageView
+ android:id="@+id/move_task"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_marginEnd="52dp"
+ android:layout_gravity="center_vertical|end"
+ android:padding="12dp"
+ android:background="@drawable/recents_button_bg"
+ android:src="@drawable/star"
+ android:visibility="gone" />
+ <com.android.systemui.recents.views.FixedSizeImageView
android:id="@+id/dismiss_task"
android:layout_width="48dp"
android:layout_height="48dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 428c9f4..ba2c8eb 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Maak alle programme toe"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Gelaai"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Laai tans"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> tot vol"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e57c5f4..f4ba6f6 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"ሁሉንም ማመልከቻዎች አሰናብት"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ባትሪ ሞልቷል"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ኃይል በመሙላት ላይ"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> እስኪሞላ ድረስ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 44f4948..67e151e 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"تجاهل كل التطبيقات"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"تم الشحن"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"جارٍ الشحن"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> حتى الاكتمال"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 7fc379c..4d37f4a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -191,10 +191,10 @@
<string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Затваряне на панела."</string>
<string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Повече време."</string>
<string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"По-малко време."</string>
- <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Светкавицата е изключена."</string>
- <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Светкавицата е включена."</string>
- <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Светкавицата се изключи."</string>
- <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Светкавицата се включи."</string>
+ <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Фенерчето е изключено."</string>
+ <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Фенерчето е включено."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Фенерчето е изключено."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Фенерчето е включено."</string>
<string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Функцията за инвертиране на цветовете се изключи."</string>
<string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Функцията за инвертиране на цветовете се включи."</string>
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобилната точка за достъп се изключи."</string>
@@ -268,7 +268,7 @@
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетъринг"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка за достъп"</string>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Известия"</string>
- <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Светкавица"</string>
+ <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Фенерче"</string>
<string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Мобилни данни"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Пренос на данни"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Оставащи данни"</string>
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Отхвърляне на всички приложения"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Заредена"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Зарежда се"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> до пълно зареждане"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 1110310..71c78b2 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"সমস্ত অ্যাপ্লিকেশন খারিজ করুন"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"চার্জ হয়েছে"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"চার্জ হচ্ছে"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"পূর্ণ হতে <xliff:g id="CHARGING_TIME">%s</xliff:g> সময় লাগবে"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ef5986b..16d5d109 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Descarta totes les aplicacions"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"S\'està carregant"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> per completar la càrrega"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 6235eb1..c949164 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Odstranit všechny aplikace"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nabito"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Nabíjení"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> do plného nabití"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 3153d3f..733f0c9 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Luk alle applikationer"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opladet"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Oplader"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> indtil fuld opladet"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 3165a3c..9d0b907 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Alle Apps entfernen"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Aufgeladen"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Wird aufgeladen"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Voll in <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index e6ea177..5e672b3 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Παράβλεψη όλων των εφαρμογών"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Φορτίστηκε"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Φόρτιση"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> για πλήρη φόρτιση"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 8e46cce..0d627cf 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Dismiss all applications"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Charging"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> until full"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 8e46cce..0d627cf 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Dismiss all applications"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Charging"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> until full"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c788677..a70ef9a 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Descartar todas las aplicaciones"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Cargando"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> para completarse"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3f2fa15..54926ce 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Ignorar todas las aplicaciones"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Cargando"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> para completarse"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 9c05158..cb2dd7b 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Loobu kõikidest rakendustest"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Laetud"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Laadimine"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Täislaadimiseks kulub <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index e2a81e9..ae02787 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -159,7 +159,7 @@
<skip />
<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 aplikazioen atala garbitu da."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Azken aplikazio guztiak baztertu da."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> hasten."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Jakinarazpena baztertu da."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Jakinarazpenen panela."</string>
@@ -281,7 +281,19 @@
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pantaila-ainguratzea"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string>
- <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Garbitu aplikazio guztiak"</string>
+ <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Baztertu aplikazio guztiak"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Kargatuta"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Kargatzen"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> falta zaizkio guztiz kargatzeko"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index c50eabf..becc464 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"رد کردن همه برنامهها"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"شارژ کامل شد"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"در حال شارژ شدن"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> مانده تا شارژ کامل شود"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 3208b1b..5fbe650 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Hylkää kaikki sovellukset"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Ladattu"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Ladataan"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> kunnes täynnä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e6bd1f6..daf87ef 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Supprimer toutes les applications"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Chargée"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Charge en cours..."</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Chargée dans <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1d91c8a..32dac57 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Supprimer toutes les applications"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Chargé"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"En charge"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Chargé dans <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 78a5fbb..8b1a3da 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Rexeitar todas as aplicacións"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Cargando"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> para completar a carga"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 411e3c3..34040d1 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"सभी ऐप्लिकेशन ख़ारिज करें"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज हो गई है"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"चार्ज हो रही है"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"पूर्ण होने में <xliff:g id="CHARGING_TIME">%s</xliff:g> शेष"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 1e42832..5fc2f88 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Odbaci sve aplikacije"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Napunjeno"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Punjenje"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> do napunjenosti"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ed105d0..8b0edbc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Összes alkalmazás elvetése"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Feltöltve"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Töltés"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> a teljes töltöttségig"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 6432060..2fa89c8 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Հեռացնել բոլոր հավելվածները"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Լիցքավորված է"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Լիցքավորվում է"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Լրիվ լիցքավորմանը մնաց <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index bd0a99f..501b99e 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -159,7 +159,7 @@
<skip />
<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 ditutup."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaru telah ditutup."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Memulai <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan disingkirkan."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bayangan pemberitahuan."</string>
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Tutup semua aplikasi"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Terisi"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Mengisi daya"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> sampai penuh"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index adcda3f..a408204 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Fjarlægja öll forrit"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Fullhlaðin"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Í hleðslu"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> þar til fullri hleðslu er náð"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 21a483f..369e51a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Rimuovi tutte le applicazioni"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carica"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"In carica"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> al termine della carica"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 15bd235..bdfdcc3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"סגור את כל האפליקציות"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"טעון"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"טוען"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> עד למילוי"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 5b68f86..330e55a 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"すべてのアプリケーションを消去"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"充電が完了しました"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"充電しています"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"充電完了まで<xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index b6650d0..26b4025 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"ყველა აპლიკაციის გაუქმება"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"დატენილია"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"მიმდინარეობს დატენვა"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> სრულად დატენვამდე"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 15c4584..6258a8c 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Барлық қолданбаларды қабылдамау"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Зарядталды"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Зарядталуда"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Толғанға дейін <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 28d586a..71d616f 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"មិនអាចចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"បោះបង់កម្មវិធីទាំងអស់"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"កំពុងបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> រហូតដល់ពេញ"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 4134c11..b2e2a1a 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 549da84..a0d614a 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"모든 애플리케이션 닫기"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"충전됨"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"충전 중"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"완충까지 <xliff:g id="CHARGING_TIME">%s</xliff:g> 남음"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 960541a..f51814f 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -307,6 +307,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Бардык колдонмолорду көз жаздымда калтыруу"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Кубатталды"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Кубатталууда"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> толгонго чейин"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 33e98b2..01ef31a 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່ສາມາດເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"ປ່ອຍທຸກແອັບພລິເຄ"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ສາກເຕັມແລ້ວ."</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ກຳລັງສາກໄຟ"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ຈຶ່ງຈະເຕັມ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index f7a8c00..50fdaff 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Atsisakyti visų programų"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Įkrautas"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Kraunamas"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> iki visiško įkrovimo"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index a9f7110..4d36ab5 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Noņemt visas lietojumprogrammas"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Akumulators uzlādēts"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Notiek uzlāde"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> līdz pilnam akumulatoram"</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 4686ba5..a026e6f 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Отфрли ги сите апликации"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Наполнета"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Се полни"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> додека не се наполни"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 41f5923..d2b2247 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"എല്ലാ അപ്ലിക്കേഷനുകളും നിരസിക്കുക"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ചാർജ്ജുചെയ്തു"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 8f81367..4982f10 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Бүх програмыг арилгах"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Цэнэглэгдсэн"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Цэнэглэж байна"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"дүүргэхэд <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index bf7c5a6..900890c 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -225,7 +225,7 @@
<string name="start_dreams" msgid="7219575858348719790">"डेड्रीम"</string>
<string name="ethernet_label" msgid="7967563676324087464">"इथरनेट"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"विमान मोड"</string>
- <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ब"</string>
+ <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ब्लूटुथ"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ब (<xliff:g id="NUMBER">%d</xliff:g> डिव्हाइसेस)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ब बंद"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"कोणतेही जोडलेले डिव्हाइसेस उपलब्ध नाहीत"</string>
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"सर्व अनुप्रयोग डिसमिस करा"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज झाली"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"चार्ज होत आहे"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण होईपर्यंत"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 5845d59..f3c6e32 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Ketepikan semua aplikasi"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Sudah dicas"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Mengecas"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Lagi <xliff:g id="CHARGING_TIME">%s</xliff:g> untuk penuh"</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index c8f4c55..c9db1b1 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"အပလီကေးရှင်းများအားလုံး ဖယ်ထုတ်မည်"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"အားသွင်းပြီး"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"အားသွင်းနေ"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ပြည်သည့် အထိ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 60e27ee..b2fbd78 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Avvis alle apper"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Oppladet"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Lader"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Fulladet om <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 87cbb6f..67a1c30 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"सबै अनुप्रयोगहरू खारेज गर्नुहोस्"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज भयो"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"चार्ज हुँदै"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण नभएसम्म"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6786a74..2c2d6ef 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Alle apps sluiten"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opgeladen"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Opladen"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> tot volledig opgeladen"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 3f2c7fd..e2ef340 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Zamknij wszystkie aplikacje"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Naładowana"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Ładowanie"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> do pełnego naładowania"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index b5b2650..df1192d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Ignorar todas as aplicações"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"A carregar"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> até ficar completa"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c914a50..770cabe 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Dispensar todos os apps"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Carregando"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> até concluir"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index c84b96f..cd3a1c0 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Închideți toate aplicațiile"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"S-a încărcat"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Se încarcă"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> până la încărcare completă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index cd00556..7f5d352 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Закрыть все приложения"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Батарея заряжена"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Зарядка батареи"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> до полной зарядки"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 0a54324..5bd1f8d 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -159,7 +159,7 @@
<skip />
<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>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"සියලුම මෑත යෙඳුම් අස් කරන ලදි."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කරමින්."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"දැනුම්දීම නිෂ්ප්රභා කරඇත."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"දැනුම්දීම් ආවරණය."</string>
@@ -281,7 +281,19 @@
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"තිර ඇමිණීම"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string>
- <string name="recents_dismiss_all_message" msgid="8495275386693095768">"සියලු යෙදුම් අස් කරන්න"</string>
+ <string name="recents_dismiss_all_message" msgid="8495275386693095768">"සියලුම යෙදුම් අස් කරන්න"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"අරෝපිතයි"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ආරෝපණය වෙමින්"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> සම්පූර්ණ වන තෙක්"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9fbd73e4..5183dab 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Odmietnuť všetky aplikácie"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nabitá"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Nabíja sa"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Úplné nabitie o <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e4a2016..2afb65b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Opusti vse aplikacije"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Akumulator napolnjen"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Polnjenje"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> do napolnjenosti"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f3d7da0..d7ab3a6 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Одбаци све апликације"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Напуњена је"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Пуњење"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> док се не напуни"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 0e9879a..f293649 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Ta bort alla appar"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Laddat"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Laddar"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> tills batteriet är fulladdat"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 05cd74a..d7621e9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Ondoa programu zote"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Betri imejaa"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Inachaji"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Imebakisha <xliff:g id="CHARGING_TIME">%s</xliff:g> ijae"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 7556c7b..d861522 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"எல்லா பயன்பாடுகளையும் விலக்கு"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"சார்ஜ் செய்யப்பட்டது"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"சார்ஜாகிறது"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"முழுவதும் சார்ஜாக <xliff:g id="CHARGING_TIME">%s</xliff:g> ஆகும்"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 7704e85..10b3214 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"అన్ని అనువర్తనాలను తీసివేయి"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ఛార్జ్ చేయబడింది"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ఛార్జ్ అవుతోంది"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"పూర్తిగా నిండటానికి <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d591d0a..1bc9585 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"ปิดแอปพลิเคชันทั้งหมด"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ชาร์จแล้ว"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"กำลังชาร์จ"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"อีก <xliff:g id="CHARGING_TIME">%s</xliff:g> จึงจะเต็ม"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index abe7b53..a061b43 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"I-dismiss ang lahat ng application"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nasingil na"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Nagcha-charge"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> hanggang mapuno"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 9bcdc27..1b7353b 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Tüm uygulamaları kapat"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Ödeme alındı"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Şarj oluyor"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Tam şarj olmasına <xliff:g id="CHARGING_TIME">%s</xliff:g> kaldı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 68f7daa..0909eaa 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Закрити всі додатки"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Заряджено"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Заряджається"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"До повного зарядження <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index bc3dbc2..1b29477 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"سبھی ایپلیکیشنز کو برخاست کریں"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"چارج ہوگئی"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"چارج ہو رہی ہے"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> مکمل ہونے تک"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 86ad17e..15c84cb 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Barcha ilovalarni olib tashlash"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Batareya quvvati to‘ldi"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Quvvat olmoqda"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g>da to‘ladi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 506c60a..20a19a3 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -159,7 +159,7 @@
<skip />
<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">"Đã loại bỏ tất cả các ứng dụng gần đây."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Đã bỏ qua tất cả các ứng dụng gần đây."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Bắt đầu <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bóng thông báo."</string>
@@ -281,7 +281,19 @@
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"khóa màn hình"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string>
- <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Loại bỏ tất cả các ứng dụng"</string>
+ <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Bỏ qua tất cả các ứng dụng"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Đã sạc"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Đang sạc"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> cho đến khi đầy"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 4b39f65..0c5c57b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"关闭所有应用"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"充电完成"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"正在充电"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"还需<xliff:g id="CHARGING_TIME">%s</xliff:g>充满"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 50d8489..6e6cc1e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -161,7 +161,7 @@
<skip />
<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>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"所有最近使用的應用程式均已關閉。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知已關閉。"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知欄。"</string>
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"關閉所有應用程式"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"已完成充電"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"充電中"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g>後完成充電"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 8a50cf9..5329977 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -161,7 +161,7 @@
<skip />
<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>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近使用的應用程式已全部關閉。"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"已關閉通知。"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知欄。"</string>
@@ -284,6 +284,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"關閉所有應用程式"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"已充飽"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"充電中"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g>後充飽"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 19e6b49..2a7adb5 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -282,6 +282,18 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Cashisa zonke izinhlelo zokusebenza"</string>
+ <!-- no translation found for recents_multistack_add_stack (5044995965068125420) -->
+ <skip />
+ <!-- no translation found for recents_multistack_remove_stack (3014058144068028841) -->
+ <skip />
+ <!-- no translation found for recents_multistack_resize_stack (5511174284568497822) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+ <skip />
+ <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+ <skip />
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Kushajiwe"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"Iyashaja"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ize igcwale"</string>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c977db9..40bf13f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -672,6 +672,19 @@
<!-- Recents: Dismiss all button. [CHAR LIMIT=NONE] -->
<string name="recents_dismiss_all_message">Dismiss all applications</string>
+ <!-- Recents: MultiStack add stack button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_add_stack">+</string>
+ <!-- Recents: MultiStack remove stack button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_remove_stack">-</string>
+ <!-- Recents: MultiStack resize stack button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_resize_stack">[]</string>
+ <!-- Recents: MultiStack add stack split horizontal radio button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_add_stack_dialog_split_horizontal">Split Horizontal</string>
+ <!-- Recents: MultiStack add stack split vertical radio button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_add_stack_dialog_split_vertical">Split Vertical</string>
+ <!-- Recents: MultiStack add stack split custom radio button. [CHAR LIMIT=NONE] -->
+ <string name="recents_multistack_add_stack_dialog_split_custom">Split Custom</string>
+
<!-- Expanded Status Bar Header: Battery Charged [CHAR LIMIT=40] -->
<string name="expanded_header_battery_charged">Charged</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f2b4a69..bf19b8d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -20,7 +20,7 @@
<item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
</style>
- <style name="RecentsTheme" parent="@android:style/Theme">
+ <style name="RecentsTheme" parent="@android:style/Theme.Material.Light">
<!-- NoTitle -->
<item name="android:windowNoTitle">true</item>
<!-- Misc -->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6df78ac..f3d214f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -489,6 +489,11 @@
}
@Override
+ public void resetKeyguard() {
+ resetStateLocked();
+ }
+
+ @Override
public void playTrustedSound() {
KeyguardViewMediator.this.playTrustedSound();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 974235e..4dacacf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -423,7 +423,9 @@
}
for (TileRecord record : mRecords) {
- record.tileView.setDual(record.tile.supportsDualTargets());
+ if (record.tileView.setDual(record.tile.supportsDualTargets())) {
+ record.tileView.handleStateChanged(record.tile.getState());
+ }
if (record.tileView.getVisibility() == GONE) continue;
final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth;
final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index bb353d5..16ae6b4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -172,7 +172,7 @@
}
}
- public void setDual(boolean dual) {
+ public boolean setDual(boolean dual) {
final boolean changed = dual != mDual;
mDual = dual;
if (changed) {
@@ -199,6 +199,7 @@
setFocusable(!dual);
mDivider.setVisibility(dual ? VISIBLE : GONE);
postInvalidate();
+ return changed;
}
private void setRipple(RippleDrawable tileBackground) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index cfd6b40..192acc6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -39,6 +39,8 @@
public static final boolean EnableSearchLayout = true;
// Enables the thumbnail alpha on the front-most task
public static final boolean EnableThumbnailAlphaOnFrontmost = false;
+ // Enables all system stacks to show up in the same recents stack
+ public static final boolean EnableMultiStackToSingleStack = true;
// This disables the bitmap and icon caches
public static final boolean DisableBackgroundCache = false;
// Enables the simulated task affiliations
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 3c75aac..9dd82fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -24,7 +24,6 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -56,7 +55,6 @@
import com.android.systemui.recents.views.TaskViewTransform;
import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -112,6 +110,9 @@
/** Preloads the next task */
public void run() {
+ // Temporarily skip this if multi stack is enabled
+ if (mConfig.multiStackEnabled) return;
+
RecentsConfiguration config = RecentsConfiguration.getInstance();
if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
@@ -362,13 +363,21 @@
}
void showRelativeAffiliatedTask(boolean showNextTask) {
+ // Return early if there is no focused stack
+ int focusedStackId = mSystemServicesProxy.getFocusedStack();
+ TaskStack focusedStack = null;
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
loader.preloadTasks(plan, true /* isTopTaskHome */);
- TaskStack stack = plan.getTaskStack();
+ if (mConfig.multiStackEnabled) {
+ if (focusedStackId < 0) return;
+ focusedStack = plan.getTaskStack(focusedStackId);
+ } else {
+ focusedStack = plan.getAllTaskStacks().get(0);
+ }
- // Return early if there are no tasks
- if (stack.getTaskCount() == 0) return;
+ // Return early if there are no tasks in the focused stack
+ if (focusedStack.getTaskCount() == 0) return;
ActivityManager.RunningTaskInfo runningTask = mSystemServicesProxy.getTopMostTask();
// Return early if there is no running task (can't determine affiliated tasks in this case)
@@ -377,7 +386,7 @@
if (mSystemServicesProxy.isInHomeStack(runningTask.id)) return;
// Find the task in the recents list
- ArrayList<Task> tasks = stack.getTasks();
+ ArrayList<Task> tasks = focusedStack.getTasks();
Task toTask = null;
ActivityOptions launchOpts = null;
int taskCount = tasks.size();
@@ -399,7 +408,7 @@
R.anim.recents_launch_prev_affiliated_task_source);
}
if (toTaskKey != null) {
- toTask = stack.findTaskWithId(toTaskKey.id);
+ toTask = focusedStack.findTaskWithId(toTaskKey.id);
}
numAffiliatedTasks = group.getTaskCount();
break;
@@ -473,8 +482,9 @@
// Reload the widget id before we get the task stack bounds
reloadSearchBarAppWidget(mContext, mSystemServicesProxy);
}
- mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
- (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds);
+ mConfig.getAvailableTaskStackBounds(mWindowRect.width(), mWindowRect.height(),
+ mStatusBarHeight, (mConfig.hasTransposedNavBar ? mNavBarWidth : 0),
+ mTaskStackBounds);
if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
} else {
@@ -653,8 +663,25 @@
// Create a new load plan if onPreloadRecents() was never triggered
sInstanceLoadPlan = loader.createLoadPlan(mContext);
}
+
+ // Temporarily skip the transition (use a dummy fade) if multi stack is enabled.
+ // For multi-stack we need to figure out where each of the tasks are going.
+ if (mConfig.multiStackEnabled) {
+ loader.preloadTasks(sInstanceLoadPlan, true);
+ ArrayList<TaskStack> stacks = sInstanceLoadPlan.getAllTaskStacks();
+ TaskStack stack = stacks.get(0);
+ mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, true);
+ TaskStackViewLayoutAlgorithm.VisibilityReport stackVr =
+ mDummyStackView.computeStackVisibilityReport();
+ ActivityOptions opts = getUnknownTransitionActivityOptions();
+ startAlternateRecentsActivity(topTask, opts, true /* fromHome */,
+ false /* fromSearchHome */, false /* fromThumbnail */, stackVr);
+ return;
+ }
+
loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome);
- TaskStack stack = sInstanceLoadPlan.getTaskStack();
+ ArrayList<TaskStack> stacks = sInstanceLoadPlan.getAllTaskStacks();
+ TaskStack stack = stacks.get(0);
// Prepare the dummy stack for the transition
mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1833e09..b1ac733 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.app.ActivityOptions;
+import android.app.Dialog;
import android.app.SearchManager;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
@@ -43,7 +44,6 @@
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
-import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.DebugOverlayView;
@@ -75,6 +75,9 @@
View mEmptyView;
DebugOverlayView mDebugOverlay;
+ // MultiStack debug
+ RecentsMultiStackDialog mMultiStackDebugDialog;
+
// Search AppWidget
RecentsAppWidgetHost mAppWidgetHost;
AppWidgetProviderInfo mSearchAppWidgetInfo;
@@ -190,7 +193,8 @@
}
// Start loading tasks according to the load plan
- if (plan.getTaskStack() == null) {
+ ArrayList<TaskStack> stacks = plan.getAllTaskStacks();
+ if (stacks.size() == 0) {
loader.preloadTasks(plan, mConfig.launchedFromHome);
}
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
@@ -199,9 +203,7 @@
loadOpts.numVisibleTaskThumbnails = mConfig.launchedNumVisibleThumbnails;
loader.loadTasks(this, plan, loadOpts);
- SpaceNode root = plan.getSpaceNode();
- ArrayList<TaskStack> stacks = root.getStacks();
- boolean hasTasks = root.hasTasks();
+ boolean hasTasks = plan.hasTasks();
if (hasTasks) {
mRecentsView.setTaskStacks(stacks);
}
@@ -591,6 +593,40 @@
}
}
+
+ /**** RecentsMultiStackDialog ****/
+
+ private RecentsMultiStackDialog getMultiStackDebugDialog() {
+ if (mMultiStackDebugDialog == null) {
+ mMultiStackDebugDialog = new RecentsMultiStackDialog(getFragmentManager());
+ }
+ return mMultiStackDebugDialog;
+ }
+
+ @Override
+ public void onMultiStackAddStack() {
+ RecentsMultiStackDialog dialog = getMultiStackDebugDialog();
+ dialog.showAddStackDialog();
+ }
+
+ @Override
+ public void onMultiStackResizeStack() {
+ RecentsMultiStackDialog dialog = getMultiStackDebugDialog();
+ dialog.showResizeStackDialog();
+ }
+
+ @Override
+ public void onMultiStackRemoveStack() {
+ RecentsMultiStackDialog dialog = getMultiStackDebugDialog();
+ dialog.showRemoveStackDialog();
+ }
+
+ @Override
+ public void onMultiStackMoveTask(Task t) {
+ RecentsMultiStackDialog dialog = getMultiStackDebugDialog();
+ dialog.showMoveTaskDialog(t);
+ }
+
/**** RecentsView.RecentsViewCallbacks Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index bc10a48..1736c77 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -134,6 +134,7 @@
public boolean fakeShadows;
/** Dev options and global settings */
+ public boolean multiStackEnabled;
public boolean lockToAppEnabled;
public boolean developerOptionsEnabled;
public boolean debugModeEnabled;
@@ -294,6 +295,7 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED) != 0;
lockToAppEnabled = ssp.getSystemSetting(context,
Settings.System.LOCK_TO_APP_ENABLED) != 0;
+ multiStackEnabled = "1".equals(ssp.getSystemProperty("overview.enableMultiStack"));
}
/** Called when the configuration has changed, and we want to reset any configuration specific
@@ -335,8 +337,8 @@
* Returns the task stack bounds in the current orientation. These bounds do not account for
* the system insets.
*/
- public void getTaskStackBounds(int windowWidth, int windowHeight, int topInset, int rightInset,
- Rect taskStackBounds) {
+ public void getAvailableTaskStackBounds(int windowWidth, int windowHeight, int topInset,
+ int rightInset, Rect taskStackBounds) {
Rect searchBarBounds = new Rect();
getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds);
if (isLandscape && hasTransposedSearchBar) {
@@ -353,7 +355,7 @@
* the system insets.
*/
public void getSearchBarBounds(int windowWidth, int windowHeight, int topInset,
- Rect searchBarSpaceBounds) {
+ Rect searchBarSpaceBounds) {
// Return empty rects if search is not enabled
int searchBarSize = searchBarSpaceHeightPx;
if (!Constants.DebugFlags.App.EnableSearchLayout || !hasSearchBarAppWidget()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsMultiStackDialog.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsMultiStackDialog.java
new file mode 100644
index 0000000..fdf9d39
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsMultiStackDialog.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.util.MutableInt;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+import com.android.systemui.R;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.model.RecentsTaskLoader;
+import com.android.systemui.recents.model.Task;
+
+import java.util.List;
+
+/**
+ * A helper for the dialogs that show when multistack debugging is on.
+ */
+public class RecentsMultiStackDialog extends DialogFragment {
+
+ static final String TAG = "RecentsMultiStackDialog";
+
+ public static final int ADD_STACK_DIALOG = 0;
+ public static final int ADD_STACK_PICK_APP_DIALOG = 1;
+ public static final int REMOVE_STACK_DIALOG = 2;
+ public static final int RESIZE_STACK_DIALOG = 3;
+ public static final int RESIZE_STACK_PICK_STACK_DIALOG = 4;
+ public static final int MOVE_TASK_DIALOG = 5;
+
+ FragmentManager mFragmentManager;
+ int mCurrentDialogType;
+ MutableInt mTargetStackIndex = new MutableInt(0);
+ Task mTaskToMove;
+ SparseArray<ActivityManager.StackInfo> mStacks;
+ List<ResolveInfo> mLauncherActivities;
+ Rect mAddStackRect;
+ Intent mAddStackIntent;
+
+ View mAddStackDialogContent;
+
+ public RecentsMultiStackDialog() {}
+
+ public RecentsMultiStackDialog(FragmentManager mgr) {
+ mFragmentManager = mgr;
+ }
+
+ /** Shows the add-stack dialog. */
+ void showAddStackDialog() {
+ mCurrentDialogType = ADD_STACK_DIALOG;
+ show(mFragmentManager, TAG);
+ }
+
+ /** Creates a new add-stack dialog. */
+ private void createAddStackDialog(final Context context, LayoutInflater inflater,
+ AlertDialog.Builder builder, final SystemServicesProxy ssp) {
+ builder.setTitle("Add Stack - Enter new dimensions");
+ mAddStackDialogContent =
+ inflater.inflate(R.layout.recents_multistack_stack_size_dialog, null, false);
+ Rect windowRect = ssp.getWindowRect();
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_left, windowRect.left);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_top, windowRect.top);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_right, windowRect.right);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_bottom, windowRect.bottom);
+ builder.setView(mAddStackDialogContent);
+ builder.setPositiveButton("Add Stack", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int left = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_left);
+ int top = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_top);
+ int right = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_right);
+ int bottom = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_bottom);
+ if (bottom <= top || right <= left) {
+ Toast.makeText(context, "Invalid dimensions", Toast.LENGTH_SHORT).show();
+ dismiss();
+ return;
+ }
+
+ // Prompt the user for the app to start
+ dismiss();
+ mCurrentDialogType = ADD_STACK_PICK_APP_DIALOG;
+ mAddStackRect = new Rect(left, top, right, bottom);
+ show(mFragmentManager, TAG);
+ }
+ });
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+ }
+
+ /** Creates a new add-stack pick-app dialog. */
+ private void createAddStackPickAppDialog(final Context context, LayoutInflater inflater,
+ AlertDialog.Builder builder, final SystemServicesProxy ssp) {
+ mLauncherActivities = ssp.getLauncherApps();
+ mAddStackIntent = null;
+ int activityCount = mLauncherActivities.size();
+ CharSequence[] activityNames = new CharSequence[activityCount];
+ for (int i = 0; i < activityCount; i++) {
+ activityNames[i] = ssp.getActivityLabel(mLauncherActivities.get(i).activityInfo);
+ }
+ builder.setTitle("Add Stack - Pick starting app");
+ builder.setSingleChoiceItems(activityNames, -1,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ ActivityInfo ai = mLauncherActivities.get(which).activityInfo;
+ mAddStackIntent = new Intent(Intent.ACTION_MAIN);
+ mAddStackIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ mAddStackIntent.setComponent(new ComponentName(ai.packageName, ai.name));
+ }
+ });
+ builder.setPositiveButton("Add Stack", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // Display 0 = default display
+ ssp.createNewStack(0, mAddStackRect, mAddStackIntent);
+ }
+ });
+ builder.setNegativeButton("Skip", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // Display 0 = default display
+ ssp.createNewStack(0, mAddStackRect, null);
+ }
+ });
+ }
+
+ /** Shows the resize-stack dialog. */
+ void showResizeStackDialog() {
+ mCurrentDialogType = RESIZE_STACK_PICK_STACK_DIALOG;
+ show(mFragmentManager, TAG);
+ }
+
+ /** Creates a new resize-stack pick-stack dialog. */
+ private void createResizeStackPickStackDialog(final Context context, LayoutInflater inflater,
+ AlertDialog.Builder builder, final SystemServicesProxy ssp) {
+ mStacks = ssp.getAllStackInfos();
+ mTargetStackIndex.value = -1;
+ CharSequence[] stackNames = getAllStacksDescriptions(mStacks, -1, null);
+ builder.setTitle("Resize Stack - Pick stack");
+ builder.setSingleChoiceItems(stackNames, mTargetStackIndex.value,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mTargetStackIndex.value = which;
+ }
+ });
+ builder.setPositiveButton("Resize Stack", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (mTargetStackIndex.value != -1) {
+ // Prompt the user for the new dimensions
+ dismiss();
+ mCurrentDialogType = RESIZE_STACK_DIALOG;
+ show(mFragmentManager, TAG);
+ }
+ }
+ });
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+ }
+
+ /** Creates a new resize-stack dialog. */
+ private void createResizeStackDialog(final Context context, LayoutInflater inflater,
+ AlertDialog.Builder builder, final SystemServicesProxy ssp) {
+ builder.setTitle("Resize Stack - Enter new dimensions");
+ final ActivityManager.StackInfo stack = mStacks.valueAt(mTargetStackIndex.value);
+ mAddStackDialogContent =
+ inflater.inflate(R.layout.recents_multistack_stack_size_dialog, null, false);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_left, stack.bounds.left);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_top, stack.bounds.top);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_right, stack.bounds.right);
+ setDimensionInEditText(mAddStackDialogContent, R.id.inset_bottom, stack.bounds.bottom);
+ builder.setView(mAddStackDialogContent);
+ builder.setPositiveButton("Resize Stack", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int left = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_left);
+ int top = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_top);
+ int right = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_right);
+ int bottom = getDimensionFromEditText(mAddStackDialogContent, R.id.inset_bottom);
+ if (bottom <= top || right <= left) {
+ Toast.makeText(context, "Invalid dimensions", Toast.LENGTH_SHORT).show();
+ dismiss();
+ return;
+ }
+ ssp.resizeStack(stack.stackId, new Rect(left, top, right, bottom));
+ }
+ });
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+ }
+
+ /** Shows the remove-stack dialog. */
+ void showRemoveStackDialog() {
+ mCurrentDialogType = REMOVE_STACK_DIALOG;
+ show(mFragmentManager, TAG);
+ }
+
+ /** Shows the move-task dialog. */
+ void showMoveTaskDialog(Task task) {
+ mCurrentDialogType = MOVE_TASK_DIALOG;
+ mTaskToMove = task;
+ show(mFragmentManager, TAG);
+ }
+
+ /** Creates a new move-stack dialog. */
+ private void createMoveTaskDialog(final Context context, LayoutInflater inflater,
+ AlertDialog.Builder builder, final SystemServicesProxy ssp) {
+ mStacks = ssp.getAllStackInfos();
+ mTargetStackIndex.value = -1;
+ CharSequence[] stackNames = getAllStacksDescriptions(mStacks, mTaskToMove.key.stackId,
+ mTargetStackIndex);
+ builder.setTitle("Move Task to Stack");
+ builder.setSingleChoiceItems(stackNames, mTargetStackIndex.value,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mTargetStackIndex.value = which;
+ }
+ });
+ builder.setPositiveButton("Move Task", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (mTargetStackIndex.value != -1) {
+ ActivityManager.StackInfo toStack = mStacks.valueAt(mTargetStackIndex.value);
+ if (toStack.stackId != mTaskToMove.key.stackId) {
+ ssp.moveTaskToStack(mTaskToMove.key.id, toStack.stackId, true);
+ mTaskToMove.setStackId(toStack.stackId);
+ }
+ }
+ }
+ });
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+ }
+
+ /** Helper to get an integer value from an edit text. */
+ private int getDimensionFromEditText(View container, int id) {
+ String text = ((EditText) container.findViewById(id)).getText().toString();
+ if (text.trim().length() != 0) {
+ return Integer.parseInt(text.trim());
+ }
+ return 0;
+ }
+
+ /** Helper to set an integer value to an edit text. */
+ private void setDimensionInEditText(View container, int id, int value) {
+ ((EditText) container.findViewById(id)).setText("" + value);
+ }
+
+ /** Gets a list of all the stacks. */
+ private CharSequence[] getAllStacksDescriptions(SparseArray<ActivityManager.StackInfo> stacks,
+ int targetStackId, MutableInt indexOfTargetStackId) {
+ int stackCount = stacks.size();
+ CharSequence[] stackNames = new CharSequence[stackCount];
+ for (int i = 0; i < stackCount; i++) {
+ ActivityManager.StackInfo stack = stacks.valueAt(i);
+ Rect b = stack.bounds;
+ String desc = "Stack " + stack.stackId + " / " +
+ "" + (stack.taskIds.length > 0 ? stack.taskIds.length : "No") + " tasks\n" +
+ "(" + b.left + ", " + b.top + ")-(" + b.right + ", " + b.bottom + ")\n";
+ stackNames[i] = desc;
+ if (targetStackId != -1 && stack.stackId == targetStackId) {
+ indexOfTargetStackId.value = i;
+ }
+ }
+ return stackNames;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle args) {
+ final Context context = this.getActivity();
+ final SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ switch(mCurrentDialogType) {
+ case ADD_STACK_DIALOG:
+ createAddStackDialog(context, inflater, builder, ssp);
+ break;
+ case ADD_STACK_PICK_APP_DIALOG:
+ createAddStackPickAppDialog(context, inflater, builder, ssp);
+ break;
+ case MOVE_TASK_DIALOG:
+ createMoveTaskDialog(context, inflater, builder, ssp);
+ break;
+ case RESIZE_STACK_PICK_STACK_DIALOG:
+ createResizeStackPickStackDialog(context, inflater, builder, ssp);
+ break;
+ case RESIZE_STACK_DIALOG:
+ createResizeStackDialog(context, inflater, builder, ssp);
+ break;
+ }
+ return builder.create();
+ }
+}
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 237d4f0..72040fe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -20,6 +20,7 @@
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.AppGlobals;
+import android.app.IActivityContainer;
import android.app.IActivityManager;
import android.app.ITaskStackListener;
import android.app.SearchManager;
@@ -49,10 +50,12 @@
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.SurfaceControl;
@@ -64,6 +67,8 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
@@ -228,6 +233,23 @@
return null;
}
+ /** Returns a list of all the launcher apps sorted by name. */
+ public List<ResolveInfo> getLauncherApps() {
+ if (mPm == null) return new ArrayList<ResolveInfo>();
+
+ final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> activities = mPm.queryIntentActivities(mainIntent, 0 /* flags */);
+ Collections.sort(activities, new Comparator<ResolveInfo>() {
+ @Override
+ public int compare(ResolveInfo o1, ResolveInfo o2) {
+ return getActivityLabel(o1.activityInfo).compareTo(
+ getActivityLabel(o2.activityInfo));
+ }
+ });
+ return activities;
+ }
+
/** Returns whether the recents is currently running */
public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
AtomicBoolean isHomeTopMost) {
@@ -250,6 +272,64 @@
return false;
}
+ /** Create a new stack. */
+ public void createNewStack(int displayId, Rect bounds, Intent activity) {
+ try {
+ IActivityContainer container = mIam.createStackOnDisplay(displayId);
+ if (container != null) {
+ // Resize the stack
+ resizeStack(container.getStackId(), bounds);
+ // Start the new activity on that stack
+ container.startActivity(activity);
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Resizes a stack. */
+ public void resizeStack(int stackId, Rect bounds) {
+ if (mIam == null) return;
+
+ try {
+ mIam.resizeStack(stackId, bounds);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Returns the stack info for all stacks. */
+ public SparseArray<ActivityManager.StackInfo> getAllStackInfos() {
+ if (mIam == null) return new SparseArray<ActivityManager.StackInfo>();
+
+ try {
+ SparseArray<ActivityManager.StackInfo> stacks =
+ new SparseArray<ActivityManager.StackInfo>();
+ List<ActivityManager.StackInfo> infos = mIam.getAllStackInfos();
+ int stackCount = infos.size();
+ for (int i = 0; i < stackCount; i++) {
+ ActivityManager.StackInfo info = infos.get(i);
+ stacks.put(info.stackId, info);
+ }
+ return stacks;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ return new SparseArray<ActivityManager.StackInfo>();
+ }
+ }
+
+ /** Returns the focused stack id. */
+ public int getFocusedStack() {
+ if (mIam == null) return -1;
+
+ try {
+ return mIam.getFocusedStackId();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
/** Returns whether the specified task is in the home stack */
public boolean isInHomeStack(int taskId) {
if (mAm == null) return false;
@@ -313,7 +393,7 @@
return thumbnail;
}
- /** Moves a task to the front with the specified activity options */
+ /** Moves a task to the front with the specified activity options. */
public void moveTaskToFront(int taskId, ActivityOptions opts) {
if (mAm == null) return;
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
@@ -326,6 +406,18 @@
}
}
+ /** Moves a task to another stack. */
+ public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
+ if (mIam == null) return;
+ if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
+
+ try {
+ mIam.moveTaskToStack(taskId, stackId, toTop);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
/** Removes the task */
public void removeTask(int taskId) {
if (mAm == null) return;
@@ -524,6 +616,13 @@
}
/**
+ * Returns a system property.
+ */
+ public String getSystemProperty(String key) {
+ return SystemProperties.get(key);
+ }
+
+ /**
* Returns the window rect.
*/
public Rect getWindowRect() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 3d25c80..788e473 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -20,9 +20,12 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.util.Log;
+import android.util.SparseArray;
+import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -60,7 +63,7 @@
SystemServicesProxy mSystemServicesProxy;
List<ActivityManager.RecentTaskInfo> mRawTasks;
- TaskStack mStack;
+ SparseArray<TaskStack> mStacks = new SparseArray<>();
HashMap<Task.ComponentNameKey, ActivityInfoHandle> mActivityInfoCache =
new HashMap<Task.ComponentNameKey, ActivityInfoHandle>();
@@ -90,21 +93,28 @@
synchronized void preloadPlan(RecentsTaskLoader loader, boolean isTopTaskHome) {
if (DEBUG) Log.d(TAG, "preloadPlan");
+ // This activity info cache will be used for both preloadPlan() and executePlan()
mActivityInfoCache.clear();
- mStack = new TaskStack();
+
+ // TODO (multi-display): Currently assume the primary display
+ Rect displayBounds = mSystemServicesProxy.getWindowRect();
Resources res = mContext.getResources();
- ArrayList<Task> loadedTasks = new ArrayList<Task>();
+ SparseArray<ArrayList<Task>> stacksTasks = new SparseArray<>();
if (mRawTasks == null) {
preloadRawTasks(isTopTaskHome);
}
+ int firstStackId = -1;
int taskCount = mRawTasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
+ if (firstStackId < 0) {
+ firstStackId = t.stackId;
+ }
// Compose the task key
- Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
- t.firstActiveTime, t.lastActiveTime);
+ Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent,
+ t.userId, t.firstActiveTime, t.lastActiveTime);
// Get an existing activity info handle if possible
Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
@@ -143,14 +153,42 @@
iconFilename);
task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy, false);
if (DEBUG) Log.d(TAG, "\tthumbnail: " + taskKey + ", " + task.thumbnail);
- loadedTasks.add(task);
- }
- mStack.setTasks(loadedTasks);
- mStack.createAffiliatedGroupings(mConfig);
- // Assertion
- if (mStack.getTaskCount() != mRawTasks.size()) {
- throw new RuntimeException("Loading failed");
+ if (!mConfig.multiStackEnabled ||
+ Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
+ ArrayList<Task> stackTasks = stacksTasks.get(firstStackId);
+ if (stackTasks == null) {
+ stackTasks = new ArrayList<Task>();
+ stacksTasks.put(firstStackId, stackTasks);
+ }
+ stackTasks.add(task);
+ } else {
+ ArrayList<Task> stackTasks = stacksTasks.get(t.stackId);
+ if (stackTasks == null) {
+ stackTasks = new ArrayList<Task>();
+ stacksTasks.put(t.stackId, stackTasks);
+ }
+ stackTasks.add(task);
+ }
+ }
+
+ // Initialize the stacks
+ SparseArray<ActivityManager.StackInfo> stackInfos = mSystemServicesProxy.getAllStackInfos();
+ mStacks.clear();
+ int stackCount = stacksTasks.size();
+ for (int i = 0; i < stackCount; i++) {
+ int stackId = stacksTasks.keyAt(i);
+ ActivityManager.StackInfo info = stackInfos.get(stackId);
+ ArrayList<Task> stackTasks = stacksTasks.valueAt(i);
+ TaskStack stack = new TaskStack(stackId);
+ if (Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
+ stack.setBounds(displayBounds, displayBounds);
+ } else {
+ stack.setBounds(info.bounds, displayBounds);
+ }
+ stack.setTasks(stackTasks);
+ stack.createAffiliatedGroupings(mConfig);
+ mStacks.put(stackId, stack);
}
}
@@ -166,72 +204,93 @@
Resources res = mContext.getResources();
// Iterate through each of the tasks and load them according to the load conditions.
- ArrayList<Task> tasks = mStack.getTasks();
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
- Task task = tasks.get(i);
- Task.TaskKey taskKey = task.key;
+ int stackCount = mStacks.size();
+ for (int j = 0; j < stackCount; j++) {
+ ArrayList<Task> tasks = mStacks.valueAt(j).getTasks();
+ int taskCount = tasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
+ Task task = tasks.get(i);
+ Task.TaskKey taskKey = task.key;
- // Get an existing activity info handle if possible
- Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
- ActivityInfoHandle infoHandle;
- boolean hadCachedActivityInfo = false;
- if (mActivityInfoCache.containsKey(cnKey)) {
- infoHandle = mActivityInfoCache.get(cnKey);
- hadCachedActivityInfo = true;
- } else {
- infoHandle = new ActivityInfoHandle();
- }
-
- boolean isRunningTask = (task.key.id == opts.runningTaskId);
- boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
- boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
-
- // If requested, skip the running task
- if (opts.onlyLoadPausedActivities && isRunningTask) {
- continue;
- }
-
- if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
- if (task.activityIcon == null) {
- if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
- task.activityIcon = loader.getAndUpdateActivityIcon(taskKey, t.taskDescription,
- mSystemServicesProxy, res, infoHandle, true);
+ // Get an existing activity info handle if possible
+ Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
+ ActivityInfoHandle infoHandle;
+ boolean hadCachedActivityInfo = false;
+ if (mActivityInfoCache.containsKey(cnKey)) {
+ infoHandle = mActivityInfoCache.get(cnKey);
+ hadCachedActivityInfo = true;
+ } else {
+ infoHandle = new ActivityInfoHandle();
}
- }
- if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
- if (task.thumbnail == null || isRunningTask) {
- if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
- if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
- task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
- true);
- } else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
- loadQueue.addTask(task);
+
+ boolean isRunningTask = (task.key.id == opts.runningTaskId);
+ boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
+ boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
+
+ // If requested, skip the running task
+ if (opts.onlyLoadPausedActivities && isRunningTask) {
+ continue;
+ }
+
+ if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
+ if (task.activityIcon == null) {
+ if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
+ task.activityIcon = loader.getAndUpdateActivityIcon(taskKey,
+ t.taskDescription, mSystemServicesProxy, res, infoHandle, true);
}
}
- }
+ if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
+ if (task.thumbnail == null || isRunningTask) {
+ if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
+ if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+ task.thumbnail = loader.getAndUpdateThumbnail(taskKey,
+ mSystemServicesProxy, true);
+ } else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
+ loadQueue.addTask(task);
+ }
+ }
+ }
- // Update the activity info cache
- if (!hadCachedActivityInfo && infoHandle.info != null) {
- mActivityInfoCache.put(cnKey, infoHandle);
+ // Update the activity info cache
+ if (!hadCachedActivityInfo && infoHandle.info != null) {
+ mActivityInfoCache.put(cnKey, infoHandle);
+ }
}
}
}
/**
- * Composes and returns a TaskStack from the preloaded list of recent tasks.
+ * Returns all TaskStacks from the preloaded list of recent tasks.
*/
- public TaskStack getTaskStack() {
- return mStack;
+ public ArrayList<TaskStack> getAllTaskStacks() {
+ ArrayList<TaskStack> stacks = new ArrayList<TaskStack>();
+ int stackCount = mStacks.size();
+ for (int i = 0; i < stackCount; i++) {
+ stacks.add(mStacks.valueAt(i));
+ }
+ // Ensure that we have at least one stack
+ if (stacks.isEmpty()) {
+ stacks.add(new TaskStack());
+ }
+ return stacks;
}
/**
- * Composes and returns a SpaceNode from the preloaded list of recent tasks.
+ * Returns a specific TaskStack from the preloaded list of recent tasks.
*/
- public SpaceNode getSpaceNode() {
- SpaceNode node = new SpaceNode();
- node.setStack(mStack);
- return node;
+ public TaskStack getTaskStack(int stackId) {
+ return mStacks.get(stackId);
+ }
+
+ /** Returns whether there are any tasks in any stacks. */
+ public boolean hasTasks() {
+ int stackCount = mStacks.size();
+ for (int i = 0; i < stackCount; i++) {
+ if (mStacks.valueAt(i).getTaskCount() > 0) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
deleted file mode 100644
index 831698a..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
+++ /dev/null
@@ -1,82 +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.recents.model;
-
-import android.graphics.Rect;
-
-import java.util.ArrayList;
-
-
-/**
- * The full recents space is partitioned using a BSP into various nodes that define where task
- * stacks should be placed.
- */
-public class SpaceNode {
- /* BSP node callbacks */
- public interface SpaceNodeCallbacks {
- /** Notifies when a node is added */
- public void onSpaceNodeAdded(SpaceNode node);
- /** Notifies when a node is measured */
- public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
- }
-
- SpaceNode mStartNode;
- SpaceNode mEndNode;
-
- TaskStack mStack;
-
- public SpaceNode() {
- // Do nothing
- }
-
- /** Sets the current stack for this space node */
- public void setStack(TaskStack stack) {
- mStack = stack;
- }
-
- /** Returns the task stack (not null if this is a leaf) */
- TaskStack getStack() {
- return mStack;
- }
-
- /** Returns whether there are any tasks in any stacks below this node. */
- public boolean hasTasks() {
- return (mStack.getTaskCount() > 0) ||
- (mStartNode != null && mStartNode.hasTasks()) ||
- (mEndNode != null && mEndNode.hasTasks());
- }
-
- /** Returns whether this is a leaf node */
- boolean isLeafNode() {
- return (mStartNode == null) && (mEndNode == null);
- }
-
- /** Returns all the descendent task stacks */
- private void getStacksRec(ArrayList<TaskStack> stacks) {
- if (isLeafNode()) {
- stacks.add(mStack);
- } else {
- mStartNode.getStacksRec(stacks);
- mEndNode.getStacksRec(stacks);
- }
- }
- public ArrayList<TaskStack> getStacks() {
- ArrayList<TaskStack> stacks = new ArrayList<TaskStack>();
- getStacksRec(stacks);
- return stacks;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 55dfe45..0cd55d7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -36,6 +36,9 @@
public void onTaskDataLoaded();
/* Notifies when a task has been unbound */
public void onTaskDataUnloaded();
+
+ /* Notifies when a task's stack id has changed. */
+ public void onMultiStackDebugTaskStackIdChanged();
}
/** The ComponentNameKey represents the unique primary key for a component
@@ -68,14 +71,17 @@
public static class TaskKey {
final ComponentNameKey mComponentNameKey;
public final int id;
+ public int stackId;
public final Intent baseIntent;
public final int userId;
public long firstActiveTime;
public long lastActiveTime;
- public TaskKey(int id, Intent intent, int userId, long firstActiveTime, long lastActiveTime) {
+ public TaskKey(int id, int stackId, Intent intent, int userId, long firstActiveTime,
+ long lastActiveTime) {
mComponentNameKey = new ComponentNameKey(intent.getComponent(), userId);
this.id = id;
+ this.stackId = stackId;
this.baseIntent = intent;
this.userId = userId;
this.firstActiveTime = firstActiveTime;
@@ -92,18 +98,19 @@
if (!(o instanceof TaskKey)) {
return false;
}
- return id == ((TaskKey) o).id
- && userId == ((TaskKey) o).userId;
+ TaskKey otherKey = (TaskKey) o;
+ return id == otherKey.id && stackId == otherKey.stackId && userId == otherKey.userId;
}
@Override
public int hashCode() {
- return (id << 5) + userId;
+ return Objects.hash(id, stackId, userId);
}
@Override
public String toString() {
return "Task.Key: " + id + ", "
+ + "s: " + stackId + ", "
+ "u: " + userId + ", "
+ "lat: " + lastActiveTime + ", "
+ baseIntent.getComponent().getPackageName();
@@ -180,6 +187,14 @@
this.group = group;
}
+ /** Updates the stack id of this task. */
+ public void setStackId(int stackId) {
+ key.stackId = stackId;
+ if (mCb != null) {
+ mCb.onMultiStackDebugTaskStackIdChanged();
+ }
+ }
+
/** Notifies the callback listeners that this task has been loaded */
public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) {
this.applicationIcon = applicationIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 7f7eee4..5aaea15 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents.model;
import android.graphics.Color;
+import android.graphics.Rect;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.NamedCounter;
@@ -173,33 +174,38 @@
public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks);
}
- /** A pair of indices representing the group and task positions in the stack and group. */
- public static class GroupTaskIndex {
- public int groupIndex; // Index in the stack
- public int taskIndex; // Index in the group
-
- public GroupTaskIndex() {}
-
- public GroupTaskIndex(int gi, int ti) {
- groupIndex = gi;
- taskIndex = ti;
- }
- }
-
// The task offset to apply to a task id as a group affiliation
static final int IndividualTaskIdOffset = 1 << 16;
+ public final int id;
+ public final Rect stackBounds = new Rect();
+ public final Rect displayBounds = new Rect();
+
FilteredTaskList mTaskList = new FilteredTaskList();
TaskStackCallbacks mCb;
ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>();
HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<Integer, TaskGrouping>();
- /** Sets the callbacks for this task stack */
+ public TaskStack() {
+ this(0);
+ }
+
+ public TaskStack(int stackId) {
+ id = stackId;
+ }
+
+ /** Sets the callbacks for this task stack. */
public void setCallbacks(TaskStackCallbacks cb) {
mCb = cb;
}
+ /** Sets the bounds of this stack. */
+ public void setBounds(Rect stackBounds, Rect displayBounds) {
+ this.stackBounds.set(stackBounds);
+ this.displayBounds.set(displayBounds);
+ }
+
/** Resets this TaskStack. */
public void reset() {
mCb = null;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 5152150..1bed553 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -29,8 +29,10 @@
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewStub;
import android.view.WindowInsets;
import android.widget.FrameLayout;
+import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -40,6 +42,7 @@
import com.android.systemui.recents.model.TaskStack;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -56,13 +59,22 @@
public void onAllTaskViewsDismissed();
public void onExitToHomeAnimationTriggered();
public void onScreenPinningRequest();
+
+ public void onMultiStackAddStack();
+ public void onMultiStackResizeStack();
+ public void onMultiStackRemoveStack();
+ public void onMultiStackMoveTask(Task t);
}
RecentsConfiguration mConfig;
LayoutInflater mInflater;
DebugOverlayView mDebugOverlay;
+ ViewStub mMultiStackDebugStub;
+ View mMultiStackDebugView;
+ RecentsViewLayoutAlgorithm mLayoutAlgorithm;
ArrayList<TaskStack> mStacks;
+ List<TaskStackView> mImmutableTaskStackViews = new ArrayList<TaskStackView>();
View mSearchBar;
RecentsViewCallbacks mCb;
@@ -82,6 +94,29 @@
super(context, attrs, defStyleAttr, defStyleRes);
mConfig = RecentsConfiguration.getInstance();
mInflater = LayoutInflater.from(context);
+ mLayoutAlgorithm = new RecentsViewLayoutAlgorithm(mConfig);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ if (!mConfig.multiStackEnabled) return;
+
+ mMultiStackDebugStub = (ViewStub) findViewById(R.id.multistack_debug_view_stub);
+ if (mMultiStackDebugView == null) {
+ mMultiStackDebugView = mMultiStackDebugStub.inflate();
+ mMultiStackDebugView.findViewById(R.id.add_stack).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCb.onMultiStackAddStack();
+ }
+ });
+ mMultiStackDebugView.findViewById(R.id.resize_stack).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCb.onMultiStackResizeStack();
+ }
+ });
+ }
}
/** Sets the callbacks */
@@ -99,24 +134,19 @@
int numStacks = stacks.size();
// Make a list of the stack view children only
- ArrayList<TaskStackView> stackViews = new ArrayList<TaskStackView>();
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- stackViews.add((TaskStackView) child);
- }
- }
+ ArrayList<TaskStackView> stackViewsList = new ArrayList<TaskStackView>();
+ List<TaskStackView> stackViews = getTaskStackViews();
// Remove all/extra stack views
int numTaskStacksToKeep = 0; // Keep no tasks if we are recreating the layout
if (mConfig.launchedReuseTaskStackViews) {
- numTaskStacksToKeep = Math.min(childCount, numStacks);
+ numTaskStacksToKeep = Math.min(stackViews.size(), numStacks);
}
for (int i = stackViews.size() - 1; i >= numTaskStacksToKeep; i--) {
removeView(stackViews.get(i));
stackViews.remove(i);
}
+ stackViewsList.addAll(stackViews);
// Update the stack views that we are keeping
for (int i = 0; i < numTaskStacksToKeep; i++) {
@@ -133,42 +163,51 @@
TaskStackView stackView = new TaskStackView(getContext(), stack);
stackView.setCallbacks(this);
addView(stackView);
+ stackViewsList.add(stackView);
}
+ // Set the immutable stack views list
+ mImmutableTaskStackViews = Collections.unmodifiableList(stackViewsList);
+
// Enable debug mode drawing on all the stacks if necessary
if (mConfig.debugModeEnabled) {
- for (int i = childCount - 1; i >= 0; i--) {
- View v = getChildAt(i);
- if (v != mSearchBar) {
- TaskStackView stackView = (TaskStackView) v;
- stackView.setDebugOverlay(mDebugOverlay);
- }
+ for (int i = mImmutableTaskStackViews.size() - 1; i >= 0; i--) {
+ TaskStackView stackView = mImmutableTaskStackViews.get(i);
+ stackView.setDebugOverlay(mDebugOverlay);
}
}
+ // Bring the debug view to the front
+ if (mMultiStackDebugView != null) {
+ mMultiStackDebugView.bringToFront();
+ }
+
// Trigger a new layout
requestLayout();
}
+ /** Gets the list of task views */
+ List<TaskStackView> getTaskStackViews() {
+ return mImmutableTaskStackViews;
+ }
+
/** Launches the focused task from the first stack if possible */
public boolean launchFocusedTask() {
// Get the first stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- TaskStack stack = stackView.mStack;
- // Iterate the stack views and try and find the focused task
- List<TaskView> taskViews = stackView.getTaskViews();
- int taskViewCount = taskViews.size();
- for (int j = 0; j < taskViewCount; j++) {
- TaskView tv = taskViews.get(j);
- Task task = tv.getTask();
- if (tv.isFocusedTask()) {
- onTaskViewClicked(stackView, tv, stack, task, false);
- return true;
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ TaskStack stack = stackView.getStack();
+ // Iterate the stack views and try and find the focused task
+ List<TaskView> taskViews = stackView.getTaskViews();
+ int taskViewCount = taskViews.size();
+ for (int j = 0; j < taskViewCount; j++) {
+ TaskView tv = taskViews.get(j);
+ Task task = tv.getTask();
+ if (tv.isFocusedTask()) {
+ onTaskViewClicked(stackView, tv, stack, task, false);
+ return true;
}
}
}
@@ -178,24 +217,22 @@
/** Launches the task that Recents was launched from, if possible */
public boolean launchPreviousTask() {
// Get the first stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- TaskStack stack = stackView.mStack;
- ArrayList<Task> tasks = stack.getTasks();
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ TaskStack stack = stackView.getStack();
+ ArrayList<Task> tasks = stack.getTasks();
- // Find the launch task in the stack
- if (!tasks.isEmpty()) {
- int taskCount = tasks.size();
- for (int j = 0; j < taskCount; j++) {
- if (tasks.get(j).isLaunchTarget) {
- Task task = tasks.get(j);
- TaskView tv = stackView.getChildViewForTask(task);
- onTaskViewClicked(stackView, tv, stack, task, false);
- return true;
- }
+ // Find the launch task in the stack
+ if (!tasks.isEmpty()) {
+ int taskCount = tasks.size();
+ for (int j = 0; j < taskCount; j++) {
+ if (tasks.get(j).isLaunchTarget) {
+ Task task = tasks.get(j);
+ TaskView tv = stackView.getChildViewForTask(task);
+ onTaskViewClicked(stackView, tv, stack, task, false);
+ return true;
}
}
}
@@ -209,13 +246,11 @@
// to ensure that it runs
ctx.postAnimationTrigger.increment();
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.startEnterRecentsAnimation(ctx);
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ stackView.startEnterRecentsAnimation(ctx);
}
ctx.postAnimationTrigger.decrement();
}
@@ -225,13 +260,11 @@
// We have to increment/decrement the post animation trigger in case there are no children
// to ensure that it runs
ctx.postAnimationTrigger.increment();
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.startExitToHomeAnimation(ctx);
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ stackView.startExitToHomeAnimation(ctx);
}
ctx.postAnimationTrigger.decrement();
@@ -287,22 +320,31 @@
}
Rect taskStackBounds = new Rect();
- mConfig.getTaskStackBounds(width, height, mConfig.systemInsets.top,
+ mConfig.getAvailableTaskStackBounds(width, height, mConfig.systemInsets.top,
mConfig.systemInsets.right, taskStackBounds);
- // Measure each TaskStackView with the full width and height of the window since the
+ // Measure each TaskStackView with the full width and height of the window since the
// transition view is a child of that stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar && child.getVisibility() != GONE) {
- TaskStackView tsv = (TaskStackView) child;
- // Set the insets to be the top/left inset + search bounds
- tsv.setStackInsetRect(taskStackBounds);
- tsv.measure(widthMeasureSpec, heightMeasureSpec);
+ List<TaskStackView> stackViews = getTaskStackViews();
+ List<Rect> stackViewsBounds = mLayoutAlgorithm.computeStackRects(stackViews,
+ taskStackBounds);
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ if (stackView.getVisibility() != GONE) {
+ // We are going to measure the TaskStackView with the whole RecentsView dimensions,
+ // but the actual stack is going to be inset to the bounds calculated by the layout
+ // algorithm
+ stackView.setStackInsetRect(stackViewsBounds.get(i));
+ stackView.measure(widthMeasureSpec, heightMeasureSpec);
}
}
+ // Measure the multistack debug view
+ if (mMultiStackDebugView != null) {
+ mMultiStackDebugView.measure(width, height);
+ }
+
setMeasuredDimension(width, height);
}
@@ -322,14 +364,27 @@
// Layout each TaskStackView with the full width and height of the window since the
// transition view is a child of that stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar && child.getVisibility() != GONE) {
- child.layout(left, top, left + child.getMeasuredWidth(),
- top + child.getMeasuredHeight());
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ if (stackView.getVisibility() != GONE) {
+ stackView.layout(left, top, left + stackView.getMeasuredWidth(),
+ top + stackView.getMeasuredHeight());
}
}
+
+ // Layout the multistack debug view
+ if (mMultiStackDebugView != null) {
+ Rect taskStackBounds = new Rect();
+ mConfig.getAvailableTaskStackBounds(getMeasuredWidth(), getMeasuredHeight(),
+ mConfig.systemInsets.top, mConfig.systemInsets.right, taskStackBounds);
+ mMultiStackDebugView.layout(left,
+ taskStackBounds.bottom - mConfig.systemInsets.bottom -
+ mMultiStackDebugView.getMeasuredHeight(),
+ left + mMultiStackDebugView.getMeasuredWidth(),
+ taskStackBounds.bottom - mConfig.systemInsets.bottom);
+ }
}
@Override
@@ -343,41 +398,29 @@
/** Notifies each task view of the user interaction. */
public void onUserInteraction() {
// Get the first stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.onUserInteraction();
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ stackView.onUserInteraction();
}
}
/** Focuses the next task in the first stack view */
public void focusNextTask(boolean forward) {
// Get the first stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.focusNextTask(forward, true);
- break;
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ if (!stackViews.isEmpty()) {
+ stackViews.get(0).focusNextTask(forward, true);
}
}
/** Dismisses the focused task. */
public void dismissFocusedTask() {
// Get the first stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.dismissFocusedTask();
- break;
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ if (!stackViews.isEmpty()) {
+ stackViews.get(0).dismissFocusedTask();
}
}
@@ -476,9 +519,16 @@
}
};
}
- opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
- b, offsetX, offsetY, transform.rect.width(), transform.rect.height(),
- sourceView.getHandler(), animStartedListener);
+ if (mConfig.multiStackEnabled) {
+ opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(),
+ R.anim.recents_from_unknown_enter,
+ R.anim.recents_from_unknown_exit,
+ sourceView.getHandler(), animStartedListener);
+ } else {
+ opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
+ b, offsetX, offsetY, transform.rect.width(), transform.rect.height(),
+ sourceView.getHandler(), animStartedListener);
+ }
}
final ActivityOptions launchOpts = opts;
@@ -561,13 +611,11 @@
/** Final callback after Recents is finally hidden. */
public void onRecentsHidden() {
// Notify each task stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.onRecentsHidden();
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ stackView.onRecentsHidden();
}
}
@@ -599,18 +647,23 @@
}
}
+ @Override
+ public void onMultiStackMoveTask(Task t) {
+ if (mCb != null) {
+ mCb.onMultiStackMoveTask(t);
+ }
+ }
+
/**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
@Override
public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) {
// Propagate this event down to each task stack view
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child != mSearchBar) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.onPackagesChanged(monitor, packageName, userId);
- }
+ List<TaskStackView> stackViews = getTaskStackViews();
+ int stackCount = stackViews.size();
+ for (int i = 0; i < stackCount; i++) {
+ TaskStackView stackView = stackViews.get(i);
+ stackView.onPackagesChanged(monitor, packageName, userId);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewLayoutAlgorithm.java
new file mode 100644
index 0000000..eea273c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewLayoutAlgorithm.java
@@ -0,0 +1,59 @@
+/*
+ * 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.recents.views;
+
+import android.graphics.Rect;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.model.TaskStack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/* The layout logic for the RecentsView. */
+public class RecentsViewLayoutAlgorithm {
+
+ RecentsConfiguration mConfig;
+
+ public RecentsViewLayoutAlgorithm(RecentsConfiguration config) {
+ mConfig = config;
+ }
+
+ /** Return the relative coordinate given coordinates in another size. */
+ private int getRelativeCoordinate(int availableOffset, int availableSize, int otherCoord, int otherSize) {
+ float relPos = (float) otherCoord / otherSize;
+ return availableOffset + (int) (relPos * availableSize);
+ }
+
+ /**
+ * Computes and returns the bounds that each of the stack views should take up.
+ */
+ List<Rect> computeStackRects(List<TaskStackView> stackViews, Rect availableBounds) {
+ ArrayList<Rect> bounds = new ArrayList<Rect>(stackViews.size());
+ int stackViewsCount = stackViews.size();
+ for (int i = 0; i < stackViewsCount; i++) {
+ TaskStack stack = stackViews.get(i).getStack();
+ Rect sb = stack.stackBounds;
+ Rect db = stack.displayBounds;
+ Rect ab = availableBounds;
+ bounds.add(new Rect(getRelativeCoordinate(ab.left, ab.width(), sb.left, db.width()),
+ getRelativeCoordinate(ab.top, ab.height(), sb.top, db.height()),
+ getRelativeCoordinate(ab.left, ab.width(), sb.right, db.width()),
+ getRelativeCoordinate(ab.top, ab.height(), sb.bottom, db.height())));
+ }
+ return bounds;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 290792a..2318319 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -60,6 +60,8 @@
public void onAllTaskViewsDismissed(ArrayList<Task> removedTasks);
public void onTaskStackFilterTriggered();
public void onTaskStackUnfilterTriggered();
+
+ public void onMultiStackMoveTask(Task t);
}
RecentsConfiguration mConfig;
@@ -149,6 +151,11 @@
requestLayout();
}
+ /** Returns the task stack. */
+ TaskStack getStack() {
+ return mStack;
+ }
+
/** Sets the debug overlay */
public void setDebugOverlay(DebugOverlayView overlay) {
mDebugOverlay = overlay;
@@ -625,6 +632,11 @@
return mTouchHandler.onGenericMotionEvent(ev);
}
+ /** Returns the region that touch gestures can be started in. */
+ Rect getTouchableRegion() {
+ return mTaskStackBounds;
+ }
+
@Override
public void computeScroll() {
mStackScroller.computeScroll();
@@ -1326,6 +1338,13 @@
}
}
+ @Override
+ public void onMultiStackMoveTask(TaskView tv) {
+ if (mCb != null) {
+ mCb.onMultiStackMoveTask(tv.getTask());
+ }
+ }
+
/**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index ccad2f1..fabc86d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -96,16 +96,6 @@
}
return false;
}
- /** Bounds the current scroll if necessary, but does not synchronize the stack view with the model. */
- public boolean boundScrollRaw() {
- float curScroll = getStackScroll();
- float newScroll = getBoundedStackScroll(curScroll);
- if (Float.compare(newScroll, curScroll) != 0) {
- setStackScrollRaw(newScroll);
- return true;
- }
- return false;
- }
/** Returns the bounded stack scroll */
float getBoundedStackScroll(float scroll) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 4a6112c..6cdddc5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -123,6 +123,16 @@
return false;
}
+ int action = ev.getAction();
+ if (mConfig.multiStackEnabled) {
+ // Check if we are within the bounds of the stack view contents
+ if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
+ if (!mSv.getTouchableRegion().contains((int) ev.getX(), (int) ev.getY())) {
+ return false;
+ }
+ }
+ }
+
// Pass through to swipe helper if we are swiping
mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
if (mInterceptedBySwipeHelper) {
@@ -131,7 +141,6 @@
boolean wasScrolling = mScroller.isScrolling() ||
(mScroller.mScrollAnimator != null && mScroller.mScrollAnimator.isRunning());
- int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
// Save the touch down info
@@ -198,6 +207,16 @@
return false;
}
+ int action = ev.getAction();
+ if (mConfig.multiStackEnabled) {
+ // Check if we are within the bounds of the stack view contents
+ if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
+ if (!mSv.getTouchableRegion().contains((int) ev.getX(), (int) ev.getY())) {
+ return false;
+ }
+ }
+ }
+
// Pass through to swipe helper if we are swiping
if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
return true;
@@ -206,7 +225,6 @@
// Update the velocity tracker
initVelocityTrackerIfNotExists();
- int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
// Save the touch down info
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 82120bf..098f2f9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -45,6 +45,8 @@
public void onTaskViewDismissed(TaskView tv);
public void onTaskViewClipStateChanged(TaskView tv);
public void onTaskViewFocusChanged(TaskView tv, boolean focused);
+
+ public void onMultiStackMoveTask(TaskView tv);
}
RecentsConfiguration mConfig;
@@ -457,6 +459,11 @@
.start();
}
+ /** Enables/disables handling touch on this task view. */
+ void setTouchEnabled(boolean enabled) {
+ setOnClickListener(enabled ? this : null);
+ }
+
/** Animates this task view if the user does not interact with the stack after a certain time. */
void startNoUserInteractionAnimation() {
mHeaderView.startNoUserInteractionAnimation();
@@ -667,6 +674,9 @@
// Rebind any listeners
mHeaderView.mApplicationIcon.setOnClickListener(this);
mHeaderView.mDismissButton.setOnClickListener(this);
+ if (mConfig.multiStackEnabled) {
+ mHeaderView.mMoveTaskButton.setOnClickListener(this);
+ }
mActionButtonView.setOnClickListener(this);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
if (mConfig.developerOptionsEnabled) {
@@ -687,6 +697,9 @@
// Unbind any listeners
mHeaderView.mApplicationIcon.setOnClickListener(null);
mHeaderView.mDismissButton.setOnClickListener(null);
+ if (mConfig.multiStackEnabled) {
+ mHeaderView.mMoveTaskButton.setOnClickListener(null);
+ }
mActionButtonView.setOnClickListener(null);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
mHeaderView.mApplicationIcon.setOnLongClickListener(null);
@@ -695,9 +708,9 @@
mTaskDataLoaded = false;
}
- /** Enables/disables handling touch on this task view. */
- void setTouchEnabled(boolean enabled) {
- setOnClickListener(enabled ? this : null);
+ @Override
+ public void onMultiStackDebugTaskStackIdChanged() {
+ mHeaderView.rebindToTask(mTask);
}
/**** View.OnClickListener Implementation ****/
@@ -717,6 +730,10 @@
}
} else if (v == mHeaderView.mDismissButton) {
dismissTask();
+ } else if (v == mHeaderView.mMoveTaskButton) {
+ if (mCb != null) {
+ mCb.onMultiStackMoveTask(tv);
+ }
}
}
}, 125);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index e13eed8..b827acc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -56,6 +56,7 @@
RecentsConfiguration mConfig;
// Header views
+ ImageView mMoveTaskButton;
ImageView mDismissButton;
ImageView mApplicationIcon;
TextView mActivityDescription;
@@ -126,6 +127,10 @@
mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
mActivityDescription = (TextView) findViewById(R.id.activity_description);
mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
+ mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
+ if (mConfig.multiStackEnabled) {
+ mMoveTaskButton.setVisibility(View.VISIBLE);
+ }
// Hide the backgrounds if they are ripple drawables
if (!Constants.DebugFlags.App.EnableTaskFiltering) {
@@ -188,7 +193,10 @@
mApplicationIcon.setImageDrawable(t.applicationIcon);
}
mApplicationIcon.setContentDescription(t.activityLabel);
- if (!mActivityDescription.getText().toString().equals(t.activityLabel)) {
+ // Always update when multi stack debugging is enabled as the stack id can change
+ if (mConfig.multiStackEnabled) {
+ mActivityDescription.setText("[" + t.key.stackId + "] " + t.activityLabel);
+ } else if (!mActivityDescription.getText().toString().equals(t.activityLabel)) {
mActivityDescription.setText(t.activityLabel);
}
// Try and apply the system ui tint
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index eaec8fa..dda52d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -507,7 +507,6 @@
ServiceManager.checkService(DreamService.DREAM_SERVICE));
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mSettingsObserver.onChange(false); // set up
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
mSettingsObserver);
@@ -557,6 +556,7 @@
createAndAddWindows();
+ mSettingsObserver.onChange(false); // set up
disable(switches[0], false /* animate */);
setSystemUiVisibility(switches[1], 0xffffffff);
topAppWindowChanged(switches[2] != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 20dd3e7..d02cd17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -147,6 +147,9 @@
}
private boolean updateDrawable(boolean withClear) {
+ if (mIcon == null) {
+ return false;
+ }
Drawable drawable = getIcon(mIcon);
if (drawable == null) {
Log.w(TAG, "No icon for slot " + mSlot);
@@ -226,6 +229,12 @@
}
@Override
+ public void onRtlPropertiesChanged(int layoutDirection) {
+ super.onRtlPropertiesChanged(layoutDirection);
+ updateDrawable();
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index fc4d7fe..262d955 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -22,6 +22,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
@@ -85,6 +86,7 @@
mKeyguardView.onResume();
mKeyguardView.startAppearAnimation();
mShowingSoon = false;
+ mKeyguardView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
};
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 a2ff64a..7513fc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -112,6 +112,7 @@
private boolean mQsFullyExpanded;
private boolean mKeyguardShowing;
private boolean mDozing;
+ private boolean mDozingOnDown;
private int mStatusBarState;
private float mInitialHeightOnTouch;
private float mInitialTouchX;
@@ -148,7 +149,8 @@
private boolean mBlockTouches;
private int mNotificationScrimWaitDistance;
- private boolean mTwoFingerQsExpand;
+ // Used for two finger gesture as well as accessibility shortcut to QS.
+ private boolean mQsExpandImmediate;
private boolean mTwoFingerQsExpandPossible;
/**
@@ -162,7 +164,7 @@
private Runnable mLaunchAnimationEndRunnable;
private boolean mOnlyAffordanceInThisMotion;
private boolean mKeyguardStatusViewAnimating;
- private boolean mHeaderAnimatingIn;
+ private boolean mHeaderAnimating;
private ObjectAnimator mQsContainerAnimator;
private ValueAnimator mQsSizeChangeAnimator;
@@ -221,9 +223,8 @@
// recompute internal state when qspanel height changes
mQsContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight,
- int oldBottom) {
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
final int height = bottom - top;
final int oldHeight = oldBottom - oldTop;
if (height != oldHeight) {
@@ -475,6 +476,13 @@
}
}
+ public void expandWithQs() {
+ if (mQsExpansionEnabled) {
+ mQsExpandImmediate = true;
+ }
+ expand();
+ }
+
@Override
public void fling(float vel, boolean expand) {
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
@@ -500,7 +508,7 @@
if (mBlockTouches) {
return false;
}
- resetDownStates(event);
+ initDownStates(event);
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -586,10 +594,11 @@
&& x < stackScrollerX + mNotificationStackScroller.getWidth();
}
- private void resetDownStates(MotionEvent event) {
+ private void initDownStates(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mOnlyAffordanceInThisMotion = false;
mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
+ mDozingOnDown = isDozing();
}
}
@@ -634,7 +643,7 @@
if (mBlockTouches) {
return false;
}
- resetDownStates(event);
+ initDownStates(event);
if ((!mIsExpanding || mHintAnimationRunning)
&& !mQsExpanded
&& mStatusBar.getBarState() != StatusBarState.SHADE) {
@@ -658,7 +667,7 @@
if (mExpandedHeight != 0) {
handleQsDown(event);
}
- if (!mTwoFingerQsExpand && mQsTracking) {
+ if (!mQsExpandImmediate && mQsTracking) {
onQsTouch(event);
if (!mConflictingQsExpansionGesture) {
return true;
@@ -675,7 +684,7 @@
if (mTwoFingerQsExpandPossible && event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN
&& event.getPointerCount() == 2
&& event.getY(event.getActionIndex()) < mStatusBarMinHeight) {
- mTwoFingerQsExpand = true;
+ mQsExpandImmediate = true;
requestPanelHeightUpdate();
// Normally, we start listening when the panel is expanded, but here we need to start
@@ -865,26 +874,28 @@
public void setBarState(int statusBarState, boolean keyguardFadingAway,
boolean goingToFullShade) {
- boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD
- || statusBarState == StatusBarState.SHADE_LOCKED;
- if (!mKeyguardShowing && keyguardShowing) {
- setQsTranslation(mQsExpansionHeight);
- mHeader.setTranslationY(0f);
- }
+ int oldState = mStatusBarState;
+ boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;
setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
- if (goingToFullShade) {
+
+ mStatusBarState = statusBarState;
+ mKeyguardShowing = keyguardShowing;
+
+ if (goingToFullShade || (oldState == StatusBarState.KEYGUARD
+ && statusBarState == StatusBarState.SHADE_LOCKED)) {
animateKeyguardStatusBarOut();
+ animateHeaderSlidingIn();
+ } else if (oldState == StatusBarState.SHADE_LOCKED
+ && statusBarState == StatusBarState.KEYGUARD) {
+ animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ animateHeaderSlidingOut();
} else {
mKeyguardStatusBar.setAlpha(1f);
mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
}
- mStatusBarState = statusBarState;
- mKeyguardShowing = keyguardShowing;
+
updateQsState();
- if (goingToFullShade) {
- animateHeaderSlidingIn();
- }
}
private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
@@ -906,7 +917,7 @@
= new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mHeaderAnimatingIn = false;
+ mHeaderAnimating = false;
mQsContainerAnimator = null;
mQsContainer.removeOnLayoutChangeListener(mQsContainerAnimatorUpdater);
}
@@ -934,10 +945,13 @@
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
+ long delay = mStatusBarState == StatusBarState.SHADE_LOCKED
+ ? 0
+ : mStatusBar.calculateGoingToFullShadeDelay();
mHeader.setTranslationY(-mHeader.getCollapsedHeight() - mQsPeekHeight);
mHeader.animate()
.translationY(0f)
- .setStartDelay(mStatusBar.calculateGoingToFullShadeDelay())
+ .setStartDelay(delay)
.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
.setInterpolator(mFastOutSlowInInterpolator)
.start();
@@ -946,7 +960,7 @@
mQsContainer.getTranslationY(),
mHeader.getCollapsedHeight() + mQsPeekHeight - mQsContainer.getHeight()
- mQsContainer.getTop());
- mQsContainerAnimator.setStartDelay(mStatusBar.calculateGoingToFullShadeDelay());
+ mQsContainerAnimator.setStartDelay(delay);
mQsContainerAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
mQsContainerAnimator.setInterpolator(mFastOutSlowInInterpolator);
mQsContainerAnimator.addListener(mAnimateHeaderSlidingInListener);
@@ -955,11 +969,33 @@
return true;
}
};
-
- private void animateHeaderSlidingIn() {
- mHeaderAnimatingIn = true;
- getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
+ private void animateHeaderSlidingIn() {
+ mHeaderAnimating = true;
+ getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
+ }
+
+ private void animateHeaderSlidingOut() {
+ mHeaderAnimating = true;
+ mHeader.animate().y(-mHeader.getHeight())
+ .setStartDelay(0)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mHeader.animate().setListener(null);
+ mHeaderAnimating = false;
+ updateQsState();
+ }
+ })
+ .start();
+ mQsContainer.animate()
+ .y(-mQsContainer.getHeight())
+ .setStartDelay(0)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .start();
}
private final Runnable mAnimateKeyguardStatusBarInvisibleEndRunnable = new Runnable() {
@@ -974,8 +1010,12 @@
private void animateKeyguardStatusBarOut() {
mKeyguardStatusBar.animate()
.alpha(0f)
- .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
- .setDuration(mStatusBar.getKeyguardFadingAwayDuration()/2)
+ .setStartDelay(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDelay()
+ : 0)
+ .setDuration(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDuration() / 2
+ : StackStateAnimator.ANIMATION_DURATION_STANDARD)
.setInterpolator(PhoneStatusBar.ALPHA_OUT)
.setUpdateListener(mStatusBarAnimateAlphaListener)
.withEndAction(mAnimateKeyguardStatusBarInvisibleEndRunnable)
@@ -990,13 +1030,13 @@
}
};
- private void animateKeyguardStatusBarIn() {
+ private void animateKeyguardStatusBarIn(long duration) {
mKeyguardStatusBar.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setAlpha(0f);
mKeyguardStatusBar.animate()
.alpha(1f)
.setStartDelay(0)
- .setDuration(DOZE_ANIMATION_DURATION)
+ .setDuration(duration)
.setInterpolator(mDozeAnimationInterpolator)
.setUpdateListener(mStatusBarAnimateAlphaListener)
.start();
@@ -1076,9 +1116,12 @@
}
private void updateQsState() {
- boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling;
- mHeader.setVisibility((mQsExpanded || !mKeyguardShowing) ? View.VISIBLE : View.INVISIBLE);
- mHeader.setExpanded(mKeyguardShowing || (mQsExpanded && !mStackScrollerOverscrolling));
+ boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
+ mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+ ? View.VISIBLE
+ : View.INVISIBLE);
+ mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+ || (mQsExpanded && !mStackScrollerOverscrolling));
mNotificationStackScroller.setScrollingEnabled(
mStatusBarState != StatusBarState.KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
@@ -1116,6 +1159,10 @@
if (mKeyguardShowing) {
updateHeaderKeyguard();
}
+ if (mStatusBarState == StatusBarState.SHADE_LOCKED
+ || mStatusBarState == StatusBarState.KEYGUARD) {
+ updateKeyguardBottomAreaAlpha();
+ }
if (mStatusBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled) {
mQsNavbarScrim.setAlpha(getQsExpansionFraction());
@@ -1156,17 +1203,17 @@
}
private void setQsTranslation(float height) {
- if (!mHeaderAnimatingIn) {
+ if (!mHeaderAnimating) {
mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation());
}
- if (mKeyguardShowing) {
+ if (mKeyguardShowing && !mHeaderAnimating) {
mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0));
}
}
private float calculateQsTopPadding() {
if (mKeyguardShowing
- && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
+ && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
// Either QS pushes the notifications down when fully expanded, or QS is fully above the
// notifications (mostly on tablets). maxNotifications denotes the normal top padding
@@ -1200,7 +1247,7 @@
mScrollView.getScrollY(),
mAnimateNextTopPaddingChange || animate,
mKeyguardShowing
- && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted));
+ && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted));
mAnimateNextTopPaddingChange = false;
}
@@ -1313,7 +1360,7 @@
min = Math.max(min, minHeight);
}
int maxHeight;
- if (mTwoFingerQsExpand || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) {
+ if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) {
maxHeight = calculatePanelHeightQsExpanded();
} else {
maxHeight = calculatePanelHeightShade();
@@ -1328,10 +1375,10 @@
@Override
protected void onHeightUpdated(float expandedHeight) {
- if (!mQsExpanded || mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted) {
+ if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) {
positionClockAndNotifications();
}
- if (mTwoFingerQsExpand || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null
+ if (mQsExpandImmediate || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null
&& !mQsExpansionFromOverscroll) {
float t;
if (mKeyguardShowing) {
@@ -1471,8 +1518,7 @@
* Hides the header when notifications are colliding with it.
*/
private void updateHeader() {
- if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
- || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
updateHeaderKeyguard();
} else {
updateHeaderShade();
@@ -1481,15 +1527,14 @@
}
private void updateHeaderShade() {
- if (!mHeaderAnimatingIn) {
+ if (!mHeaderAnimating) {
mHeader.setTranslationY(getHeaderTranslation());
}
setQsTranslation(mQsExpansionHeight);
}
private float getHeaderTranslation() {
- if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
- || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
return 0;
}
if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
@@ -1502,30 +1547,42 @@
return Math.min(0, mNotificationStackScroller.getTranslationY()) / HEADER_RUBBERBAND_FACTOR;
}
- private void updateHeaderKeyguard() {
- float alphaNotifications;
+ /**
+ * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area)
+ * during swiping up
+ */
+ private float getKeyguardContentsAlpha() {
+ float alpha;
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
// When on Keyguard, we hide the header as soon as the top card of the notification
// stack scroller is close enough (collision distance) to the bottom of the header.
- alphaNotifications = getNotificationsTopY()
+ alpha = getNotificationsTopY()
/
(mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance);
} else {
// In SHADE_LOCKED, the top card is already really close to the header. Hide it as
// soon as we start translating the stack.
- alphaNotifications = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
+ alpha = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
}
- alphaNotifications = MathUtils.constrain(alphaNotifications, 0, 1);
- alphaNotifications = (float) Math.pow(alphaNotifications, 0.75);
+ alpha = MathUtils.constrain(alpha, 0, 1);
+ alpha = (float) Math.pow(alpha, 0.75);
+ return alpha;
+ }
+
+ private void updateHeaderKeyguard() {
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
- mKeyguardStatusBar.setAlpha(Math.min(alphaNotifications, alphaQsExpansion)
+ mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha);
- mKeyguardBottomArea.setAlpha(Math.min(1 - getQsExpansionFraction(), alphaNotifications));
setQsTranslation(mQsExpansionHeight);
}
+ private void updateKeyguardBottomAreaAlpha() {
+ mKeyguardBottomArea.setAlpha(
+ Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction()));
+ }
+
private float getNotificationsTopY() {
if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
return getExpandedHeight();
@@ -1555,7 +1612,7 @@
} else {
setListening(true);
}
- mTwoFingerQsExpand = false;
+ mQsExpandImmediate = false;
mTwoFingerQsExpandPossible = false;
}
@@ -1573,7 +1630,7 @@
@Override
protected void setOverExpansion(float overExpansion, boolean isPixels) {
- if (mConflictingQsExpansionGesture || mTwoFingerQsExpand) {
+ if (mConflictingQsExpansionGesture || mQsExpandImmediate) {
return;
}
if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
@@ -1593,7 +1650,7 @@
protected void onTrackingStarted() {
super.onTrackingStarted();
if (mQsFullyExpanded) {
- mTwoFingerQsExpand = true;
+ mQsExpandImmediate = true;
}
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
@@ -1756,6 +1813,7 @@
mSecureCameraLaunchManager.onSwipingStarted();
requestDisallowInterceptTouchEvent(true);
mOnlyAffordanceInThisMotion = true;
+ mQsTracking = false;
}
@Override
@@ -1817,7 +1875,7 @@
@Override
protected boolean fullyExpandedClearAllVisible() {
return mNotificationStackScroller.isDismissViewNotGone()
- && mNotificationStackScroller.isScrolledToBottom() && !mTwoFingerQsExpand;
+ && mNotificationStackScroller.isScrolledToBottom() && !mQsExpandImmediate;
}
@Override
@@ -1897,7 +1955,7 @@
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setVisibility(View.VISIBLE);
if (animate) {
- animateKeyguardStatusBarIn();
+ animateKeyguardStatusBarIn(DOZE_ANIMATION_DURATION);
mKeyguardBottomArea.startFinishDozeAnimation();
}
}
@@ -1947,6 +2005,32 @@
onEmptySpaceClick(x);
}
+ protected boolean onMiddleClicked() {
+ switch (mStatusBar.getBarState()) {
+ case StatusBarState.KEYGUARD:
+ if (!mDozingOnDown) {
+ EventLogTags.writeSysuiLockscreenGesture(
+ EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
+ 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
+ startUnlockHintAnimation();
+ }
+ return true;
+ case StatusBarState.SHADE_LOCKED:
+ if (!mQsExpanded) {
+ mStatusBar.goToKeyguard();
+ }
+ return true;
+ case StatusBarState.SHADE:
+
+ // This gets called in the middle of the touch handling, where the state is still
+ // that we are tracking the panel. Collapse the panel after this is done.
+ post(mPostCollapseRunnable);
+ return false;
+ default:
+ return true;
+ }
+ }
+
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
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 d86ccee..47034e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -100,7 +100,6 @@
private boolean mCollapseAfterPeek;
private boolean mExpanding;
private boolean mGestureWaitForTouchSlop;
- private boolean mDozingOnDown;
private Runnable mPeekRunnable = new Runnable() {
@Override
public void run() {
@@ -247,7 +246,6 @@
mUpdateFlingOnLayout = false;
mPeekTouching = mPanelClosedOnDown;
mTouchAboveFalsingThreshold = false;
- mDozingOnDown = isDozing();
if (mVelocityTracker == null) {
initVelocityTracker();
}
@@ -431,7 +429,6 @@
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mTouchAboveFalsingThreshold = false;
- mDozingOnDown = isDozing();
initVelocityTracker();
trackMovement(event);
break;
@@ -942,35 +939,14 @@
}
}
- private final Runnable mPostCollapseRunnable = new Runnable() {
+ protected final Runnable mPostCollapseRunnable = new Runnable() {
@Override
public void run() {
collapse(false /* delayed */);
}
};
- private boolean onMiddleClicked() {
- switch (mStatusBar.getBarState()) {
- case StatusBarState.KEYGUARD:
- if (!mDozingOnDown) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
- 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
- startUnlockHintAnimation();
- }
- return true;
- case StatusBarState.SHADE_LOCKED:
- mStatusBar.goToKeyguard();
- return true;
- case StatusBarState.SHADE:
- // This gets called in the middle of the touch handling, where the state is still
- // that we are tracking the panel. Collapse the panel after this is done.
- post(mPostCollapseRunnable);
- return false;
- default:
- return true;
- }
- }
+ protected abstract boolean onMiddleClicked();
protected abstract void onEdgeClicked(boolean right);
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 25a2f93..4ffe9b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -32,7 +32,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.TimeInterpolator;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -82,14 +81,12 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
-import android.view.HardwareCanvas;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -97,23 +94,17 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
-import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
-import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
-import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
@@ -172,7 +163,6 @@
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
-import com.android.systemui.statusbar.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
import com.android.systemui.volume.VolumeComponent;
@@ -212,9 +202,6 @@
private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
- private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
- private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
-
private static final int STATUS_OR_NAV_TRANSIENT =
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
@@ -261,8 +248,7 @@
AccessibilityController mAccessibilityController;
int mNaturalBarHeight = -1;
- int mIconSize = -1;
- int mIconHPadding = -1;
+
Display mDisplay;
Point mCurrentDisplaySize = new Point();
@@ -278,23 +264,7 @@
int mPixelFormat;
Object mQueueLock = new Object();
- // viewgroup containing the normal contents of the statusbar
- LinearLayout mStatusBarContents;
-
- // right-hand icons
- LinearLayout mSystemIconArea;
- LinearLayout mSystemIcons;
-
- // left-hand icons
- LinearLayout mStatusIcons;
- LinearLayout mStatusIconsKeyguard;
-
- // the icons themselves
- IconMerger mNotificationIcons;
- View mNotificationIconArea;
-
- // [+>
- View mMoreIcon;
+ StatusBarIconController mIconController;
// expanded notifications
NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -419,7 +389,6 @@
private boolean mDozing;
private boolean mScrimSrcModeEnabled;
- private Interpolator mLinearOutSlowIn;
private Interpolator mLinearInterpolator = new LinearInterpolator();
private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
@@ -610,8 +579,6 @@
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
- mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
-
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
mStatusBarWindow.mService = this;
@@ -689,15 +656,6 @@
// figure out which pixel-format to use for the status bar.
mPixelFormat = PixelFormat.OPAQUE;
- mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
- mSystemIcons = (LinearLayout) mStatusBarView.findViewById(R.id.system_icons);
- mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
- mNotificationIconArea = mStatusBarView.findViewById(R.id.notification_icon_area_inner);
- mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
- mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
- mNotificationIcons.setOverflowIndicator(mMoreIcon);
- mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
-
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
@@ -741,7 +699,6 @@
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
mHeader.setActivityStarter(this);
mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
- mStatusIconsKeyguard = (LinearLayout) mKeyguardStatusBar.findViewById(R.id.statusIcons);
mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
mKeyguardBottomArea =
(KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
@@ -756,6 +713,9 @@
// set the inital view visibility
setAreThereNotifications();
+ mIconController = new StatusBarIconController(
+ mContext, mStatusBarView, mKeyguardStatusBar, this);
+
// Background thread for any controllers that need it.
mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
@@ -1177,49 +1137,17 @@
mWindowManager.removeView(mHeadsUpNotificationView);
}
- public void refreshAllStatusBarIcons() {
- refreshAllIconsForLayout(mStatusIcons);
- refreshAllIconsForLayout(mStatusIconsKeyguard);
- refreshAllIconsForLayout(mNotificationIcons);
- }
-
- private void refreshAllIconsForLayout(LinearLayout ll) {
- final int count = ll.getChildCount();
- for (int n = 0; n < count; n++) {
- View child = ll.getChildAt(n);
- if (child instanceof StatusBarIconView) {
- ((StatusBarIconView) child).updateDrawable();
- }
- }
- }
-
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
- if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
- + " icon=" + icon);
- StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
- view.set(icon);
- mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
- LayoutParams.WRAP_CONTENT, mIconSize));
- view = new StatusBarIconView(mContext, slot, null);
- view.set(icon);
- mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
- LayoutParams.WRAP_CONTENT, mIconSize));
+ mIconController.addSystemIcon(slot, index, viewIndex, icon);
}
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon) {
- if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
- + " old=" + old + " icon=" + icon);
- StatusBarIconView view = (StatusBarIconView) mStatusIcons.getChildAt(viewIndex);
- view.set(icon);
- view = (StatusBarIconView) mStatusIconsKeyguard.getChildAt(viewIndex);
- view.set(icon);
+ mIconController.updateSystemIcon(slot, index, viewIndex, old, icon);
}
public void removeIcon(String slot, int index, int viewIndex) {
- if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
- mStatusIcons.removeViewAt(viewIndex);
- mStatusIconsKeyguard.removeViewAt(viewIndex);
+ mIconController.removeSystemIcon(slot, index, viewIndex);
}
public UserHandle getCurrentUserHandle() {
@@ -1339,7 +1267,6 @@
if (mNavigationBarView != null) {
mNavigationBarView.setLayoutDirection(layoutDirection);
}
- refreshAllStatusBarIcons();
}
private void updateShowSearchHoldoff() {
@@ -1480,69 +1407,10 @@
@Override
protected void updateNotifications() {
- // TODO: Move this into updateNotificationIcons()?
- if (mNotificationIcons == null) return;
-
mNotificationData.filterAndSort();
updateNotificationShade();
- updateNotificationIcons();
- }
-
- private void updateNotificationIcons() {
- final LinearLayout.LayoutParams params
- = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
-
- ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
- final int N = activeNotifications.size();
- ArrayList<StatusBarIconView> toShow = new ArrayList<>(N);
-
- // Filter out notifications with low scores.
- for (int i = 0; i < N; i++) {
- Entry ent = activeNotifications.get(i);
- if (ent.notification.getScore() < HIDE_ICONS_BELOW_SCORE &&
- !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
- continue;
- }
- toShow.add(ent.icon);
- }
-
- if (DEBUG) {
- Log.d(TAG, "refreshing icons: " + toShow.size() +
- " notifications, mNotificationIcons=" + mNotificationIcons);
- }
-
- ArrayList<View> toRemove = new ArrayList<View>();
- for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
- View child = mNotificationIcons.getChildAt(i);
- if (!toShow.contains(child)) {
- toRemove.add(child);
- }
- }
-
- final int toRemoveCount = toRemove.size();
- for (int i = 0; i < toRemoveCount; i++) {
- mNotificationIcons.removeView(toRemove.get(i));
- }
-
- for (int i=0; i<toShow.size(); i++) {
- View v = toShow.get(i);
- if (v.getParent() == null) {
- mNotificationIcons.addView(v, i, params);
- }
- }
-
- // Resort notification icons
- final int childCount = mNotificationIcons.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View actual = mNotificationIcons.getChildAt(i);
- StatusBarIconView expected = toShow.get(i);
- if (actual == expected) {
- continue;
- }
- mNotificationIcons.removeView(expected);
- mNotificationIcons.addView(expected, i);
- }
+ mIconController.updateNotificationIcons(mNotificationData);
}
@Override
@@ -1826,14 +1694,6 @@
}
}
- public void showClock(boolean show) {
- if (mStatusBarView == null) return;
- View clock = mStatusBarView.findViewById(R.id.clock);
- if (clock != null) {
- clock.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- }
-
private int adjustDisableFlags(int state) {
if (!mLaunchTransitionFadingAway
&& (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
@@ -1882,17 +1742,16 @@
Log.d(TAG, flagdbg.toString());
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
- mSystemIconArea.animate().cancel();
if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
- animateStatusBarHide(mSystemIconArea, animate);
+ mIconController.hideSystemIconArea(animate);
} else {
- animateStatusBarShow(mSystemIconArea, animate);
+ mIconController.showSystemIconArea(animate);
}
}
if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
- boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
- showClock(show);
+ boolean visible = (state & StatusBarManager.DISABLE_CLOCK) == 0;
+ mIconController.setClockVisibility(visible);
}
if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
@@ -1916,9 +1775,9 @@
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
- animateStatusBarHide(mNotificationIconArea, animate);
+ mIconController.hideNotificationIconArea(animate);
} else {
- animateStatusBarShow(mNotificationIconArea, animate);
+ mIconController.showNotificationIconArea(animate);
}
}
@@ -1929,60 +1788,6 @@
}
}
- /**
- * Animates {@code v}, a view that is part of the status bar, out.
- */
- private void animateStatusBarHide(final View v, boolean animate) {
- v.animate().cancel();
- if (!animate) {
- v.setAlpha(0f);
- v.setVisibility(View.INVISIBLE);
- return;
- }
- v.animate()
- .alpha(0f)
- .setDuration(160)
- .setStartDelay(0)
- .setInterpolator(ALPHA_OUT)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- v.setVisibility(View.INVISIBLE);
- }
- });
- }
-
- /**
- * Animates {@code v}, a view that is part of the status bar, in.
- */
- private void animateStatusBarShow(View v, boolean animate) {
- v.animate().cancel();
- v.setVisibility(View.VISIBLE);
- if (!animate) {
- v.setAlpha(1f);
- return;
- }
- v.animate()
- .alpha(1f)
- .setDuration(320)
- .setInterpolator(ALPHA_IN)
- .setStartDelay(50)
-
- // We need to clean up any pending end action from animateStatusBarHide if we call
- // both hide and show in the same frame before the animation actually gets started.
- // cancel() doesn't really remove the end action.
- .withEndAction(null);
-
- // Synchronize the motion with the Keyguard fading if necessary.
- if (mKeyguardFadingAway) {
- v.animate()
- .setDuration(mKeyguardFadingAwayDuration)
- .setInterpolator(mLinearOutSlowIn)
- .setStartDelay(mKeyguardFadingAwayDelay)
- .start();
- }
- }
-
@Override
protected BaseStatusBar.H createHandler() {
return new PhoneStatusBar.H();
@@ -2206,8 +2011,7 @@
// Settings are not available in setup
if (!mUserSetup) return;
- mNotificationPanel.expand();
- mNotificationPanel.openQs();
+ mNotificationPanel.expandWithQs();
if (false) postStartTracing();
}
@@ -2668,12 +2472,7 @@
mNotificationData.dump(pw, " ");
}
- int N = mStatusIcons.getChildCount();
- pw.println(" system icons: " + N);
- for (int i=0; i<N; i++) {
- StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
- pw.println(" [" + i + "] icon=" + ic);
- }
+ mIconController.dump(pw);
if (false) {
pw.println("see the logcat for a dump of the views we have created.");
@@ -2872,10 +2671,10 @@
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
- updateClockSize();
repositionNavigationBar();
updateShowSearchHoldoff();
updateRowStates();
+ mIconController.updateResources();
mScreenPinningRequest.onConfigurationChanged();
}
@@ -2901,8 +2700,7 @@
mUserSetupObserver.onChange(false);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
- mUserSetupObserver,
- mCurrentUserId);
+ mUserSetupObserver, mCurrentUserId);
}
private void setHeadsUpVisibility(boolean vis) {
@@ -2932,8 +2730,6 @@
}
loadDimens();
- mLinearOutSlowIn = AnimationUtils.loadInterpolator(
- mContext, android.R.interpolator.linear_out_slow_in);
if (mNotificationPanel != null) {
mNotificationPanel.updateResources();
@@ -2946,31 +2742,12 @@
}
}
- private void updateClockSize() {
- if (mStatusBarView == null) return;
- TextView clock = (TextView) mStatusBarView.findViewById(R.id.clock);
- if (clock != null) {
- FontSizeUtils.updateFontSize(clock, R.dimen.status_bar_clock_size);
- }
- }
protected void loadDimens() {
final Resources res = mContext.getResources();
mNaturalBarHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
- int newIconSize = res.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_icon_size);
- int newIconHPadding = res.getDimensionPixelSize(
- R.dimen.status_bar_icon_padding);
-
- if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
-// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
- mIconHPadding = newIconHPadding;
- mIconSize = newIconSize;
- //reloadAllNotificationIcons(); // reload the tray
- }
-
mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
@@ -3179,7 +2956,6 @@
private boolean mDemoModeAllowed;
private boolean mDemoMode;
- private DemoStatusIcons mDemoStatusIcons;
@Override
public void dispatchDemoCommand(String command, Bundle args) {
@@ -3208,10 +2984,8 @@
dispatchDemoCommandToView(command, args, R.id.battery);
}
if (modeChange || command.equals(COMMAND_STATUS)) {
- if (mDemoStatusIcons == null) {
- mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
- }
- mDemoStatusIcons.dispatchDemoCommand(command, args);
+ mIconController.dispatchDemoCommand(command, args);
+
}
if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
mNetworkController.dispatchDemoCommand(command, args);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
new file mode 100644
index 0000000..6147e30
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.app.Notification;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.FontSizeUtils;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.StatusBarIconView;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controls everything regarding the icons in the status bar and on Keyguard, including, but not
+ * limited to: notification icons, signal cluster, additional status icons, and clock in the status
+ * bar.
+ */
+public class StatusBarIconController {
+
+ private Context mContext;
+ private PhoneStatusBar mPhoneStatusBar;
+ private Interpolator mLinearOutSlowIn;
+ private DemoStatusIcons mDemoStatusIcons;
+
+ private LinearLayout mSystemIconArea;
+ private LinearLayout mStatusIcons;
+ private LinearLayout mStatusIconsKeyguard;
+ private IconMerger mNotificationIcons;
+ private View mNotificationIconArea;
+ private TextView mClock;
+
+ private int mIconSize;
+ private int mIconHPadding;
+
+ public StatusBarIconController(Context context, View statusBar, View keyguardStatusBar,
+ PhoneStatusBar phoneStatusBar) {
+ mContext = context;
+ mPhoneStatusBar = phoneStatusBar;
+ mSystemIconArea = (LinearLayout) statusBar.findViewById(R.id.system_icon_area);
+ mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
+ mNotificationIconArea = statusBar.findViewById(R.id.notification_icon_area_inner);
+ mNotificationIcons = (IconMerger) statusBar.findViewById(R.id.notificationIcons);
+ View moreIcon = statusBar.findViewById(R.id.moreIcon);
+ mNotificationIcons.setOverflowIndicator(moreIcon);
+ mStatusIconsKeyguard = (LinearLayout) keyguardStatusBar.findViewById(R.id.statusIcons);
+ mClock = (TextView) statusBar.findViewById(R.id.clock);
+ mLinearOutSlowIn = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.linear_out_slow_in);
+ updateResources();
+ }
+
+ public void updateResources() {
+ mIconSize = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_icon_size);
+ mIconHPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.status_bar_icon_padding);
+ FontSizeUtils.updateFontSize(mClock, R.dimen.status_bar_clock_size);
+ }
+
+ public void addSystemIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
+ StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
+ view.set(icon);
+ mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
+ view = new StatusBarIconView(mContext, slot, null);
+ view.set(icon);
+ mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
+ }
+
+ public void updateSystemIcon(String slot, int index, int viewIndex,
+ StatusBarIcon old, StatusBarIcon icon) {
+ StatusBarIconView view = (StatusBarIconView) mStatusIcons.getChildAt(viewIndex);
+ view.set(icon);
+ view = (StatusBarIconView) mStatusIconsKeyguard.getChildAt(viewIndex);
+ view.set(icon);
+ }
+
+ public void removeSystemIcon(String slot, int index, int viewIndex) {
+ mStatusIcons.removeViewAt(viewIndex);
+ mStatusIconsKeyguard.removeViewAt(viewIndex);
+ }
+
+ public void updateNotificationIcons(NotificationData notificationData) {
+ final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+ mIconSize + 2*mIconHPadding, mPhoneStatusBar.getStatusBarHeight());
+
+ ArrayList<NotificationData.Entry> activeNotifications =
+ notificationData.getActiveNotifications();
+ final int N = activeNotifications.size();
+ ArrayList<StatusBarIconView> toShow = new ArrayList<>(N);
+
+ // Filter out ambient notifications.
+ for (int i = 0; i < N; i++) {
+ NotificationData.Entry ent = activeNotifications.get(i);
+ if (notificationData.isAmbient(ent.key)
+ && !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
+ continue;
+ }
+ toShow.add(ent.icon);
+ }
+
+ ArrayList<View> toRemove = new ArrayList<>();
+ for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
+ View child = mNotificationIcons.getChildAt(i);
+ if (!toShow.contains(child)) {
+ toRemove.add(child);
+ }
+ }
+
+ final int toRemoveCount = toRemove.size();
+ for (int i = 0; i < toRemoveCount; i++) {
+ mNotificationIcons.removeView(toRemove.get(i));
+ }
+
+ for (int i=0; i<toShow.size(); i++) {
+ View v = toShow.get(i);
+ if (v.getParent() == null) {
+ mNotificationIcons.addView(v, i, params);
+ }
+ }
+
+ // Resort notification icons
+ final int childCount = mNotificationIcons.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View actual = mNotificationIcons.getChildAt(i);
+ StatusBarIconView expected = toShow.get(i);
+ if (actual == expected) {
+ continue;
+ }
+ mNotificationIcons.removeView(expected);
+ mNotificationIcons.addView(expected, i);
+ }
+ }
+
+ public void hideSystemIconArea(boolean animate) {
+ animateHide(mSystemIconArea, animate);
+ }
+
+ public void showSystemIconArea(boolean animate) {
+ animateShow(mSystemIconArea, animate);
+ }
+
+ public void hideNotificationIconArea(boolean animate) {
+ animateHide(mNotificationIconArea, animate);
+ }
+
+ public void showNotificationIconArea(boolean animate) {
+ animateShow(mNotificationIconArea, animate);
+ }
+
+ public void setClockVisibility(boolean visible) {
+ mClock.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
+ public void dump(PrintWriter pw) {
+ int N = mStatusIcons.getChildCount();
+ pw.println(" system icons: " + N);
+ for (int i=0; i<N; i++) {
+ StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
+ pw.println(" [" + i + "] icon=" + ic);
+ }
+ }
+
+ public void dispatchDemoCommand(String command, Bundle args) {
+ if (mDemoStatusIcons == null) {
+ mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
+ }
+ mDemoStatusIcons.dispatchDemoCommand(command, args);
+ }
+
+ /**
+ * Hides a view.
+ */
+ private void animateHide(final View v, boolean animate) {
+ v.animate().cancel();
+ if (!animate) {
+ v.setAlpha(0f);
+ v.setVisibility(View.INVISIBLE);
+ return;
+ }
+ v.animate()
+ .alpha(0f)
+ .setDuration(160)
+ .setStartDelay(0)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ v.setVisibility(View.INVISIBLE);
+ }
+ });
+ }
+
+ /**
+ * Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
+ */
+ private void animateShow(View v, boolean animate) {
+ v.animate().cancel();
+ v.setVisibility(View.VISIBLE);
+ if (!animate) {
+ v.setAlpha(1f);
+ return;
+ }
+ v.animate()
+ .alpha(1f)
+ .setDuration(320)
+ .setInterpolator(PhoneStatusBar.ALPHA_IN)
+ .setStartDelay(50)
+
+ // We need to clean up any pending end action from animateHide if we call
+ // both hide and show in the same frame before the animation actually gets started.
+ // cancel() doesn't really remove the end action.
+ .withEndAction(null);
+
+ // Synchronize the motion with the Keyguard fading if necessary.
+ if (mPhoneStatusBar.isKeyguardFadingAway()) {
+ v.animate()
+ .setDuration(mPhoneStatusBar.getKeyguardFadingAwayDuration())
+ .setInterpolator(mLinearOutSlowIn)
+ .setStartDelay(mPhoneStatusBar.getKeyguardFadingAwayDelay())
+ .start();
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 5a90324..6a7201c 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -36,4 +36,6 @@
# UI it doesn't own. This is necessary to allow screenshots to be taken
LOCAL_CERTIFICATE := platform
+include frameworks/base/packages/SettingsLib/common.mk
+
include $(BUILD_PACKAGE)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index d4032cc..ac095e6 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -43,6 +43,7 @@
import android.graphics.Rect;
import android.media.AudioAttributes;
import android.media.AudioManager;
+import android.media.AudioService;
import android.media.IAudioService;
import android.media.Ringtone;
import android.media.RingtoneManager;
@@ -376,6 +377,8 @@
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
boolean mTranslucentDecorEnabled = true;
+ boolean mUseTvRouting;
+ boolean mUseMasterVolume;
int mPointerLocationMode = 0; // guarded by mLock
@@ -1262,6 +1265,10 @@
mTriplePressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_triplePressOnPowerBehavior);
+ mUseTvRouting = AudioService.getPlatformType(mContext) == AudioService.PLATFORM_TELEVISION;
+ mUseMasterVolume = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_useMasterVolume);
+
readConfigurationDependentBehaviors();
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
@@ -4534,6 +4541,10 @@
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
+ if (mUseTvRouting) {
+ // On TVs volume keys never go to the foreground app
+ result &= ~ACTION_PASS_TO_USER;
+ }
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
if (down) {
if (interactive && !mScreenshotChordVolumeDownKeyTriggered
@@ -4595,11 +4606,15 @@
}
if ((result & ACTION_PASS_TO_USER) == 0) {
- // If we aren't passing to the user and no one else
- // handled it send it to the session manager to figure
- // out.
- MediaSessionLegacyHelper.getHelper(mContext)
- .sendVolumeKeyEvent(event, true);
+ if (mUseTvRouting) {
+ dispatchDirectAudioEvent(event);
+ } else {
+ // If we aren't passing to the user and no one else
+ // handled it send it to the session manager to
+ // figure out.
+ MediaSessionLegacyHelper.getHelper(mContext)
+ .sendVolumeKeyEvent(event, true);
+ }
break;
}
}
@@ -4844,6 +4859,59 @@
return false;
}
+ private void dispatchDirectAudioEvent(KeyEvent event) {
+ if (event.getAction() != KeyEvent.ACTION_DOWN) {
+ return;
+ }
+ int keyCode = event.getKeyCode();
+ int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND;
+ String pkgName = mContext.getOpPackageName();
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ try {
+ if (mUseMasterVolume) {
+ getAudioService().adjustMasterVolume(AudioManager.ADJUST_RAISE, flags,
+ pkgName);
+ } else {
+ getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
+ AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e);
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ try {
+ if (mUseMasterVolume) {
+ getAudioService().adjustMasterVolume(AudioManager.ADJUST_LOWER, flags,
+ pkgName);
+ } else {
+ getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
+ AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e);
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ try {
+ if (event.getRepeatCount() == 0) {
+ if (mUseMasterVolume) {
+ getAudioService().adjustMasterVolume(AudioManager.ADJUST_TOGGLE_MUTE,
+ flags, pkgName);
+ } else {
+ getAudioService().adjustSuggestedStreamVolume(
+ AudioManager.ADJUST_TOGGLE_MUTE,
+ AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e);
+ }
+ break;
+ }
+ }
+
void dispatchMediaKeyWithWakeLock(KeyEvent event) {
if (DEBUG_INPUT) {
Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 289152b..c1e4994 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -382,6 +382,7 @@
// we're now good to go, so start the backup alarms
if (MORE_DEBUG) Slog.d(TAG, "Now provisioned, so starting backups");
startBackupAlarmsLocked(FIRST_BACKUP_INTERVAL);
+ scheduleNextFullBackupJob();
}
}
}
@@ -3853,6 +3854,16 @@
PackageInfo currentPackage;
try {
+ if (!mEnabled || !mProvisioned) {
+ // Backups are globally disabled, so don't proceed.
+ if (DEBUG) {
+ Slog.i(TAG, "full backup requested but e=" + mEnabled
+ + " p=" + mProvisioned + "; ignoring");
+ }
+ mUpdateSchedule = false;
+ return;
+ }
+
IBackupTransport transport = getTransport(mCurrentTransport);
if (transport == null) {
Slog.w(TAG, "Transport not present; full data backup not performed");
@@ -4150,6 +4161,17 @@
long now = System.currentTimeMillis();
FullBackupEntry entry = null;
+ if (!mEnabled || !mProvisioned) {
+ // Backups are globally disabled, so don't proceed. We also don't reschedule
+ // the job driving automatic backups; that job will be scheduled again when
+ // the user enables backup.
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "beginFullBackup but e=" + mEnabled
+ + " p=" + mProvisioned + "; ignoring");
+ }
+ return false;
+ }
+
if (DEBUG_SCHEDULING) {
Slog.i(TAG, "Beginning scheduled full backup operation");
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b5d2720..287cd6f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -87,6 +87,7 @@
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.AppTransition;
import com.android.server.wm.WindowManagerService;
+
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -1854,9 +1855,14 @@
synchronized (ActivityManagerService.this) {
if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
+ (SystemClock.uptimeMillis()-start) + "ms");
- mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
- memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
- memInfo.getKernelUsedSizeKb(), nativeTotalPss);
+ final long cachedKb = memInfo.getCachedSizeKb();
+ final long freeKb = memInfo.getFreeSizeKb();
+ final long zramKb = memInfo.getZramTotalSizeKb();
+ final long kernelKb = memInfo.getKernelUsedSizeKb();
+ EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
+ kernelKb*1024, nativeTotalPss*1024);
+ mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
+ nativeTotalPss);
}
}
@@ -5617,7 +5623,10 @@
@Override
public void showBootMessage(final CharSequence msg, final boolean always) {
- enforceNotIsolatedCaller("showBootMessage");
+ if (Binder.getCallingUid() != Process.myUid()) {
+ // These days only the core system can call this, so apps can't get in
+ // the way of what we show about running them.
+ }
mWindowManager.showBootMessage(msg, always);
}
@@ -7053,7 +7062,6 @@
return;
}
- final IPackageManager pm = AppGlobals.getPackageManager();
final String authority = uri.getAuthority();
final ProviderInfo pi = getProviderInfoLocked(authority, userId);
if (pi == null) {
@@ -8164,7 +8172,7 @@
@Override
public void resizeStack(int stackId, Rect bounds) {
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
- "resizeStackBox()");
+ "resizeStack()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (this) {
@@ -10036,7 +10044,7 @@
}
final boolean translucentChanged = r.changeWindowTranslucency(true);
if (translucentChanged) {
- r.task.stack.releaseBackgroundResources();
+ r.task.stack.releaseBackgroundResources(r);
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
}
mWindowManager.setAppFullscreen(token, true);
@@ -10063,7 +10071,7 @@
}
final boolean translucentChanged = r.changeWindowTranslucency(false);
if (translucentChanged) {
- r.task.stack.convertToTranslucent(r);
+ r.task.stack.convertActivityToTranslucent(r);
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
mWindowManager.setAppFullscreen(token, false);
@@ -10580,9 +10588,68 @@
}
}
+ final class PreBootContinuation extends IIntentReceiver.Stub {
+ final Intent intent;
+ final Runnable onFinishCallback;
+ final ArrayList<ComponentName> doneReceivers;
+ final List<ResolveInfo> ris;
+ final int[] users;
+ int lastRi = -1;
+ int curRi = 0;
+ int curUser = 0;
+
+ PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
+ ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
+ intent = _intent;
+ onFinishCallback = _onFinishCallback;
+ doneReceivers = _doneReceivers;
+ ris = _ris;
+ users = _users;
+ }
+
+ void go() {
+ if (lastRi != curRi) {
+ ActivityInfo ai = ris.get(curRi).activityInfo;
+ ComponentName comp = new ComponentName(ai.packageName, ai.name);
+ intent.setComponent(comp);
+ doneReceivers.add(comp);
+ lastRi = curRi;
+ CharSequence label = ai.loadLabel(mContext.getPackageManager());
+ showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
+ }
+ Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
+ + " for user " + users[curUser]);
+ EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
+ broadcastIntentLocked(null, null, intent, null, this,
+ 0, null, null, null, AppOpsManager.OP_NONE,
+ true, false, MY_PID, Process.SYSTEM_UID,
+ users[curUser]);
+ }
+
+ public void performReceive(Intent intent, int resultCode,
+ String data, Bundle extras, boolean ordered,
+ boolean sticky, int sendingUser) {
+ curUser++;
+ if (curUser >= users.length) {
+ curUser = 0;
+ curRi++;
+ if (curRi >= ris.size()) {
+ // All done sending broadcasts!
+ if (onFinishCallback != null) {
+ // The raw IIntentReceiver interface is called
+ // with the AM lock held, so redispatch to
+ // execute our code without the lock.
+ mHandler.post(onFinishCallback);
+ }
+ return;
+ }
+ }
+ go();
+ }
+ }
+
private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
ArrayList<ComponentName> doneReceivers, int userId) {
- boolean waitingUpdate = false;
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
List<ResolveInfo> ris = null;
try {
@@ -10590,71 +10657,51 @@
intent, null, 0, userId);
} catch (RemoteException e) {
}
- if (ris != null) {
- for (int i=ris.size()-1; i>=0; i--) {
- if ((ris.get(i).activityInfo.applicationInfo.flags
- &ApplicationInfo.FLAG_SYSTEM) == 0) {
- ris.remove(i);
- }
+ if (ris == null) {
+ return false;
+ }
+ for (int i=ris.size()-1; i>=0; i--) {
+ if ((ris.get(i).activityInfo.applicationInfo.flags
+ &ApplicationInfo.FLAG_SYSTEM) == 0) {
+ ris.remove(i);
}
- intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
+ }
+ intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
- // For User 0, load the version number. When delivering to a new user, deliver
- // to all receivers.
- if (userId == UserHandle.USER_OWNER) {
- ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
- for (int i=0; i<ris.size(); i++) {
- ActivityInfo ai = ris.get(i).activityInfo;
- ComponentName comp = new ComponentName(ai.packageName, ai.name);
- if (lastDoneReceivers.contains(comp)) {
- // We already did the pre boot receiver for this app with the current
- // platform version, so don't do it again...
- ris.remove(i);
- i--;
- // ...however, do keep it as one that has been done, so we don't
- // forget about it when rewriting the file of last done receivers.
- doneReceivers.add(comp);
- }
- }
- }
-
- // If primary user, send broadcast to all available users, else just to userId
- final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
- : new int[] { userId };
- for (int i = 0; i < ris.size(); i++) {
+ // For User 0, load the version number. When delivering to a new user, deliver
+ // to all receivers.
+ if (userId == UserHandle.USER_OWNER) {
+ ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
+ for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
- doneReceivers.add(comp);
- intent.setComponent(comp);
- for (int j=0; j<users.length; j++) {
- IIntentReceiver finisher = null;
- // On last receiver and user, set up a completion callback
- if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
- finisher = new IIntentReceiver.Stub() {
- public void performReceive(Intent intent, int resultCode,
- String data, Bundle extras, boolean ordered,
- boolean sticky, int sendingUser) {
- // The raw IIntentReceiver interface is called
- // with the AM lock held, so redispatch to
- // execute our code without the lock.
- mHandler.post(onFinishCallback);
- }
- };
- }
- Slog.i(TAG, "Sending system update to " + intent.getComponent()
- + " for user " + users[j]);
- broadcastIntentLocked(null, null, intent, null, finisher,
- 0, null, null, null, AppOpsManager.OP_NONE,
- true, false, MY_PID, Process.SYSTEM_UID,
- users[j]);
- if (finisher != null) {
- waitingUpdate = true;
- }
+ if (false && lastDoneReceivers.contains(comp)) {
+ // We already did the pre boot receiver for this app with the current
+ // platform version, so don't do it again...
+ ris.remove(i);
+ i--;
+ // ...however, do keep it as one that has been done, so we don't
+ // forget about it when rewriting the file of last done receivers.
+ doneReceivers.add(comp);
}
}
}
- return waitingUpdate;
+ if (ris.size() <= 0) {
+ return false;
+ }
+
+ // If primary user, send broadcast to all available users, else just to userId
+ final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
+ : new int[] { userId };
+ if (users.length <= 0) {
+ return false;
+ }
+
+ PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
+ ris, users);
+ cont.go();
+ return true;
}
public void systemReady(final Runnable goingCallback) {
@@ -10689,10 +10736,10 @@
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
- writeLastDonePreBootReceivers(doneReceivers);
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
+ writeLastDonePreBootReceivers(doneReceivers);
systemReady(goingCallback);
}
}, doneReceivers, UserHandle.USER_OWNER);
@@ -13860,9 +13907,14 @@
memInfo.readMemInfo();
if (nativeProcTotalPss > 0) {
synchronized (this) {
- mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
- memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
- memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
+ final long cachedKb = memInfo.getCachedSizeKb();
+ final long freeKb = memInfo.getFreeSizeKb();
+ final long zramKb = memInfo.getZramTotalSizeKb();
+ final long kernelKb = memInfo.getKernelUsedSizeKb();
+ EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
+ kernelKb*1024, nativeProcTotalPss*1024);
+ mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
+ nativeProcTotalPss);
}
}
if (!brief) {
@@ -15741,14 +15793,14 @@
callerPackage, callingPid, callingUid, resolvedType,
requiredPermission, appOp, receivers, resultTo, resultCode,
resultData, map, ordered, sticky, false, userId);
+
if (DEBUG_BROADCAST) Slog.v(
TAG, "Enqueueing ordered broadcast " + r
+ ": prev had " + queue.mOrderedBroadcasts.size());
- if (DEBUG_BROADCAST) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
- }
- boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
+ if (DEBUG_BROADCAST) Slog.i(
+ TAG, "Enqueueing broadcast " + r.intent.getAction());
+
+ boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
@@ -16079,6 +16131,15 @@
return mStackSupervisor.getFocusedStack();
}
+ @Override
+ public int getFocusedStackId() throws RemoteException {
+ ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack != null) {
+ return focusedStack.getStackId();
+ }
+ return -1;
+ }
+
public Configuration getConfiguration() {
Configuration ci;
synchronized(this) {
@@ -17056,6 +17117,7 @@
* Record new PSS sample for a process.
*/
void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
+ EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss*1024, uss*1024);
proc.lastPssTime = now;
proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
@@ -18309,8 +18371,8 @@
}
}
- private Set getProfileIdsLocked(int userId) {
- Set userIds = new HashSet<Integer>();
+ private Set<Integer> getProfileIdsLocked(int userId) {
+ Set<Integer> userIds = new HashSet<Integer>();
final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
userId, false /* enabledOnly */);
for (UserInfo user : profiles) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index dbd787b..91013ef 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -220,6 +220,9 @@
*/
boolean mConfigWillChange;
+ // Whether or not this stack covers the entire screen; by default stacks are full screen
+ boolean mFullscreen = true;
+
long mLaunchStartTime = 0;
long mFullyDrawnStartTime = 0;
@@ -1125,7 +1128,8 @@
final int numStacks = mStacks.size();
while (stackNdx < numStacks) {
- tasks = mStacks.get(stackNdx).mTaskHistory;
+ ActivityStack historyStack = mStacks.get(stackNdx);
+ tasks = historyStack.mTaskHistory;
final int numTasks = tasks.size();
while (taskNdx < numTasks) {
activities = tasks.get(taskNdx).mActivities;
@@ -1133,7 +1137,7 @@
while (activityNdx < numActivities) {
final ActivityRecord activity = activities.get(activityNdx);
if (!activity.finishing) {
- return activity.fullscreen ? null : activity;
+ return historyStack.mFullscreen && activity.fullscreen ? null : activity;
}
++activityNdx;
}
@@ -1149,7 +1153,7 @@
// Checks if any of the stacks above this one has a fullscreen activity behind it.
// If so, this stack is hidden, otherwise it is visible.
- private boolean isStackVisible() {
+ private boolean isStackVisibleLocked() {
if (!isAttached()) {
return false;
}
@@ -1164,11 +1168,18 @@
* wallpaper to be shown behind it.
*/
for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
- final ArrayList<TaskRecord> tasks = mStacks.get(i).getAllTasks();
- for (int taskNdx = 0; taskNdx < tasks.size(); taskNdx++) {
+ ActivityStack stack = mStacks.get(i);
+ // stack above isn't full screen, so, we assume we're still visible. at some point
+ // we should look at the stack bounds to see if we're occluded even if the stack
+ // isn't fullscreen
+ if (!stack.mFullscreen) {
+ continue;
+ }
+ final ArrayList<TaskRecord> tasks = stack.getAllTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = tasks.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
- for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) {
+ for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
// Conditions for an activity to obscure the stack we're
@@ -1214,7 +1225,7 @@
// If the top activity is not fullscreen, then we need to
// make sure any activities under it are now visible.
boolean aboveTop = true;
- boolean behindFullscreen = !isStackVisible();
+ boolean behindFullscreen = !isStackVisibleLocked();
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -1337,7 +1348,7 @@
// This case created for transitioning activities from
// translucent to opaque {@link Activity#convertToOpaque}.
if (getVisibleBehindActivity() == r) {
- releaseBackgroundResources();
+ releaseBackgroundResources(r);
} else {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
mStackSupervisor.mStoppingActivities.add(r);
@@ -1369,7 +1380,7 @@
}
}
- void convertToTranslucent(ActivityRecord r) {
+ void convertActivityToTranslucent(ActivityRecord r) {
mTranslucentActivityWaiting = r;
mUndrawnActivitiesBelowTopTranslucent.clear();
mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
@@ -3282,10 +3293,9 @@
}
}
- void releaseBackgroundResources() {
+ void releaseBackgroundResources(ActivityRecord r) {
if (hasVisibleBehindActivity() &&
!mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
- final ActivityRecord r = getVisibleBehindActivity();
if (r == topRunningActivityLocked(null)) {
// Don't release the top activity if it has requested to run behind the next
// activity.
@@ -4143,6 +4153,10 @@
boolean updateOverrideConfiguration(Configuration newConfig) {
Configuration oldConfig = mOverrideConfig;
mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
+ // we override the configuration only when the stack's dimensions are different from
+ // the display. in this manner, we know that if the override configuration is empty,
+ // the stack is necessarily full screen
+ mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
return !mOverrideConfig.equals(oldConfig);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4674cc2..b4455b6 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3752,6 +3752,13 @@
}
@Override
+ public int getStackId() {
+ synchronized (mService) {
+ return mStackId;
+ }
+ }
+
+ @Override
public boolean injectEvent(InputEvent event) {
final long origId = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 9b7d0b2..7ab3794 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -513,11 +513,7 @@
}
}
try {
- if (DEBUG_BROADCAST_LIGHT) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Delivering to " + filter
- + " (seq=" + seq + "): " + r);
- }
+ if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG, "Delivering to " + filter + " : " + r);
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
@@ -662,12 +658,9 @@
// result if requested...
if (r.resultTo != null) {
try {
- if (DEBUG_BROADCAST) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Finishing broadcast ["
- + mQueueName + "] " + r.intent.getAction()
- + " seq=" + seq + " app=" + r.callerApp);
- }
+ if (DEBUG_BROADCAST) Slog.i(TAG,
+ "Finishing broadcast [" + mQueueName + "] "
+ + r.intent.getAction() + " app=" + r.callerApp);
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index c376744..9a645df 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -95,3 +95,11 @@
# Home Stack brought to front or rear
30044 am_home_stack_moved (User|1|5),(To Front|1|5),(Top Stack Id|1|5),(Focused Stack Id|1|5),(Reason|3)
+
+# Running pre boot receiver
+30045 am_pre_boot (User|1|5),(Package|3)
+
+# Report collection of global memory state
+30046 am_meminfo (CachedKb|2|2),(FreeKb|2|2),(ZramKb|2|2),(KernelKb|2|2),(NativeKb|2|2)
+# Report collection of memory used by a process
+30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(PssKb|2|2),(UssKb|2|2)
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index ce52920..a8f6954 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -55,10 +55,6 @@
mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
mAddress, mService.getVendorId()));
startQueuedActions();
-
- // Switch TV input after bootup.
- setActiveSource(true);
- maySendActiveSource(Constants.ADDR_TV);
}
@Override
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 2a1f7d6..e41b3da 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -25,7 +25,6 @@
import com.android.internal.R;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -72,7 +71,6 @@
import android.provider.Telephony.Carriers;
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
@@ -91,7 +89,6 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
-import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
@@ -395,7 +392,7 @@
private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {
@Override
- public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
+ public void addGpsStatusListener(IGpsStatusListener listener) {
mListenerHelper.addListener(listener);
}
@@ -681,7 +678,7 @@
mListenerHelper = new GpsStatusListenerHelper(mHandler) {
@Override
protected boolean isAvailableInPlatform() {
- return GpsLocationProvider.isSupported();
+ return isSupported();
}
@Override
@@ -1027,6 +1024,9 @@
if (mC2KServerHost != null) {
native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
}
+
+ mGpsMeasurementsProvider.onGpsEnabledChanged();
+ mGpsNavigationMessageProvider.onGpsEnabledChanged();
} else {
synchronized (mLock) {
mEnabled = false;
@@ -1060,6 +1060,9 @@
// do this before releasing wakelock
native_cleanup();
+
+ mGpsMeasurementsProvider.onGpsEnabledChanged();
+ mGpsNavigationMessageProvider.onGpsEnabledChanged();
}
@Override
@@ -1479,9 +1482,7 @@
}
if (wasNavigating != mNavigating) {
- mListenerHelper.onGpsEnabledChanged(mNavigating);
- mGpsMeasurementsProvider.onGpsEnabledChanged(mNavigating);
- mGpsNavigationMessageProvider.onGpsEnabledChanged(mNavigating);
+ mListenerHelper.onStatusChanged(mNavigating);
// send an intent to notify that the GPS has been enabled or disabled
Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
diff --git a/services/core/java/com/android/server/location/GpsMeasurementsProvider.java b/services/core/java/com/android/server/location/GpsMeasurementsProvider.java
index 0514e0c..b327ca2 100644
--- a/services/core/java/com/android/server/location/GpsMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GpsMeasurementsProvider.java
@@ -33,7 +33,7 @@
extends RemoteListenerHelper<IGpsMeasurementsListener> {
private static final String TAG = "GpsMeasurementsProvider";
- public GpsMeasurementsProvider(Handler handler) {
+ protected GpsMeasurementsProvider(Handler handler) {
super(handler, TAG);
}
@@ -49,15 +49,19 @@
}
public void onCapabilitiesUpdated(boolean isGpsMeasurementsSupported) {
- int status = isGpsMeasurementsSupported ?
- GpsMeasurementsEvent.STATUS_READY :
- GpsMeasurementsEvent.STATUS_NOT_SUPPORTED;
- setSupported(isGpsMeasurementsSupported, new StatusChangedOperation(status));
+ setSupported(isGpsMeasurementsSupported);
+ updateResult();
+ }
+
+ public void onGpsEnabledChanged() {
+ if (tryUpdateRegistrationWithService()) {
+ updateResult();
+ }
}
@Override
protected ListenerOperation<IGpsMeasurementsListener> getHandlerOperation(int result) {
- final int status;
+ int status;
switch (result) {
case RESULT_SUCCESS:
status = GpsMeasurementsEvent.STATUS_READY;
@@ -70,6 +74,8 @@
case RESULT_GPS_LOCATION_DISABLED:
status = GpsMeasurementsEvent.STATUS_GPS_LOCATION_DISABLED;
break;
+ case RESULT_UNKNOWN:
+ return null;
default:
Log.v(TAG, "Unhandled addListener result: " + result);
return null;
@@ -77,15 +83,8 @@
return new StatusChangedOperation(status);
}
- @Override
- protected void handleGpsEnabledChanged(boolean enabled) {
- int status = enabled ?
- GpsMeasurementsEvent.STATUS_READY :
- GpsMeasurementsEvent.STATUS_GPS_LOCATION_DISABLED;
- foreach(new StatusChangedOperation(status));
- }
-
- private class StatusChangedOperation implements ListenerOperation<IGpsMeasurementsListener> {
+ private static class StatusChangedOperation
+ implements ListenerOperation<IGpsMeasurementsListener> {
private final int mStatus;
public StatusChangedOperation(int status) {
diff --git a/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java b/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
index 13d22fc..e6bbe56 100644
--- a/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
@@ -33,7 +33,7 @@
extends RemoteListenerHelper<IGpsNavigationMessageListener> {
private static final String TAG = "GpsNavigationMessageProvider";
- public GpsNavigationMessageProvider(Handler handler) {
+ protected GpsNavigationMessageProvider(Handler handler) {
super(handler, TAG);
}
@@ -50,15 +50,19 @@
}
public void onCapabilitiesUpdated(boolean isGpsNavigationMessageSupported) {
- int status = isGpsNavigationMessageSupported ?
- GpsNavigationMessageEvent.STATUS_READY :
- GpsNavigationMessageEvent.STATUS_NOT_SUPPORTED;
- setSupported(isGpsNavigationMessageSupported, new StatusChangedOperation(status));
+ setSupported(isGpsNavigationMessageSupported);
+ updateResult();
+ }
+
+ public void onGpsEnabledChanged() {
+ if (tryUpdateRegistrationWithService()) {
+ updateResult();
+ }
}
@Override
protected ListenerOperation<IGpsNavigationMessageListener> getHandlerOperation(int result) {
- final int status;
+ int status;
switch (result) {
case RESULT_SUCCESS:
status = GpsNavigationMessageEvent.STATUS_READY;
@@ -71,6 +75,8 @@
case RESULT_GPS_LOCATION_DISABLED:
status = GpsNavigationMessageEvent.STATUS_GPS_LOCATION_DISABLED;
break;
+ case RESULT_UNKNOWN:
+ return null;
default:
Log.v(TAG, "Unhandled addListener result: " + result);
return null;
@@ -78,15 +84,7 @@
return new StatusChangedOperation(status);
}
- @Override
- protected void handleGpsEnabledChanged(boolean enabled) {
- int status = enabled ?
- GpsNavigationMessageEvent.STATUS_READY :
- GpsNavigationMessageEvent.STATUS_GPS_LOCATION_DISABLED;
- foreach(new StatusChangedOperation(status));
- }
-
- private class StatusChangedOperation
+ private static class StatusChangedOperation
implements ListenerOperation<IGpsNavigationMessageListener> {
private final int mStatus;
diff --git a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java b/services/core/java/com/android/server/location/GpsStatusListenerHelper.java
index 376b4a5..53ff6c2 100644
--- a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java
+++ b/services/core/java/com/android/server/location/GpsStatusListenerHelper.java
@@ -24,14 +24,9 @@
* Implementation of a handler for {@link IGpsStatusListener}.
*/
abstract class GpsStatusListenerHelper extends RemoteListenerHelper<IGpsStatusListener> {
- public GpsStatusListenerHelper(Handler handler) {
+ protected GpsStatusListenerHelper(Handler handler) {
super(handler, "GpsStatusListenerHelper");
-
- Operation nullOperation = new Operation() {
- @Override
- public void execute(IGpsStatusListener iGpsStatusListener) throws RemoteException {}
- };
- setSupported(GpsLocationProvider.isSupported(), nullOperation);
+ setSupported(GpsLocationProvider.isSupported());
}
@Override
@@ -47,10 +42,9 @@
return null;
}
- @Override
- protected void handleGpsEnabledChanged(boolean enabled) {
+ public void onStatusChanged(boolean isNavigating) {
Operation operation;
- if (enabled) {
+ if (isNavigating) {
operation = new Operation() {
@Override
public void execute(IGpsStatusListener listener) throws RemoteException {
@@ -114,5 +108,5 @@
foreach(operation);
}
- private abstract class Operation implements ListenerOperation<IGpsStatusListener> { }
+ private interface Operation extends ListenerOperation<IGpsStatusListener> {}
}
diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java
index 402b601..ec2828b 100644
--- a/services/core/java/com/android/server/location/RemoteListenerHelper.java
+++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java
@@ -26,26 +26,31 @@
import android.util.Log;
import java.util.HashMap;
+import java.util.Map;
/**
* A helper class, that handles operations in remote listeners, and tracks for remote process death.
*/
abstract class RemoteListenerHelper<TListener extends IInterface> {
+
protected static final int RESULT_SUCCESS = 0;
protected static final int RESULT_NOT_AVAILABLE = 1;
protected static final int RESULT_NOT_SUPPORTED = 2;
protected static final int RESULT_GPS_LOCATION_DISABLED = 3;
protected static final int RESULT_INTERNAL_ERROR = 4;
+ protected static final int RESULT_UNKNOWN = 5;
private final Handler mHandler;
private final String mTag;
- private final HashMap<IBinder, LinkedListener> mListenerMap = new HashMap<>();
+ private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>();
private boolean mIsRegistered;
private boolean mHasIsSupported;
private boolean mIsSupported;
+ private int mLastReportedResult = RESULT_UNKNOWN;
+
protected RemoteListenerHelper(Handler handler, String name) {
Preconditions.checkNotNull(name);
mHandler = handler;
@@ -110,33 +115,11 @@
}
}
- public void onGpsEnabledChanged(boolean enabled) {
- // handle first the sub-class implementation, so any error in registration can take
- // precedence
- handleGpsEnabledChanged(enabled);
- synchronized (mListenerMap) {
- if (!enabled) {
- tryUnregister();
- return;
- }
- if (mListenerMap.isEmpty()) {
- return;
- }
- if (tryRegister()) {
- // registration was successful, there is no need to update the state
- return;
- }
- ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
- foreachUnsafe(operation);
- }
- }
-
protected abstract boolean isAvailableInPlatform();
protected abstract boolean isGpsEnabled();
protected abstract boolean registerWithService();
protected abstract void unregisterFromService();
protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
- protected abstract void handleGpsEnabledChanged(boolean enabled);
protected interface ListenerOperation<TListener extends IInterface> {
void execute(TListener listener) throws RemoteException;
@@ -148,11 +131,40 @@
}
}
- protected void setSupported(boolean value, ListenerOperation<TListener> notifier) {
+ protected void setSupported(boolean value) {
synchronized (mListenerMap) {
mHasIsSupported = true;
mIsSupported = value;
- foreachUnsafe(notifier);
+ }
+ }
+
+ protected boolean tryUpdateRegistrationWithService() {
+ synchronized (mListenerMap) {
+ if (!isGpsEnabled()) {
+ tryUnregister();
+ return true;
+ }
+ if (mListenerMap.isEmpty()) {
+ return true;
+ }
+ if (tryRegister()) {
+ // registration was successful, there is no need to update the state
+ return true;
+ }
+ ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
+ foreachUnsafe(operation);
+ return false;
+ }
+ }
+
+ protected void updateResult() {
+ synchronized (mListenerMap) {
+ int newResult = calculateCurrentResultUnsafe();
+ if (mLastReportedResult == newResult) {
+ return;
+ }
+ foreachUnsafe(getHandlerOperation(newResult));
+ mLastReportedResult = newResult;
}
}
@@ -183,6 +195,24 @@
mIsRegistered = false;
}
+ private int calculateCurrentResultUnsafe() {
+ // update statuses we already know about, starting from the ones that will never change
+ if (!isAvailableInPlatform()) {
+ return RESULT_NOT_AVAILABLE;
+ }
+ if (!mHasIsSupported || mListenerMap.isEmpty()) {
+ // we'll update once we have a supported status available
+ return RESULT_UNKNOWN;
+ }
+ if (!mIsSupported) {
+ return RESULT_NOT_SUPPORTED;
+ }
+ if (!isGpsEnabled()) {
+ return RESULT_GPS_LOCATION_DISABLED;
+ }
+ return RESULT_SUCCESS;
+ }
+
private class LinkedListener implements IBinder.DeathRecipient {
private final TListener mListener;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index da63caa..df31158 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -250,77 +250,37 @@
if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
- boolean isMute = direction == MediaSessionManager.DIRECTION_MUTE;
- if (direction > 1) {
- direction = 1;
- } else if (direction < -1) {
- direction = -1;
- }
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
if (mUseMasterVolume) {
// If this device only uses master volume and playback is local
// just adjust the master volume and return.
- boolean isMasterMute = mAudioManager.isMasterMute();
- if (isMute) {
- mAudioManagerInternal.setMasterMuteForUid(!isMasterMute,
- flags, packageName, mService.mICallback, uid);
- } else {
- mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName,
- uid);
- if (isMasterMute) {
- mAudioManagerInternal.setMasterMuteForUid(false,
- flags, packageName, mService.mICallback, uid);
- }
- }
+ mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName,
+ uid);
return;
}
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
- boolean isStreamMute = mAudioManager.isStreamMute(stream);
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
- if (isMute) {
- mAudioManager.setStreamMute(stream, !isStreamMute);
- } else {
- mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction,
- flags, packageName, uid);
- if (isStreamMute && direction != 0) {
- mAudioManager.setStreamMute(stream, false);
- }
- }
+ mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction,
+ flags, packageName, uid);
} else {
flags |= previousFlagPlaySound;
- isStreamMute =
- mAudioManager.isStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE);
- if (isMute) {
- mAudioManager.setStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE,
- !isStreamMute);
- } else {
- mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
- AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName,
- uid);
- if (isStreamMute && direction != 0) {
- mAudioManager.setStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE,
- false);
- }
- }
+ mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
+ AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName,
+ uid);
}
} else {
- if (isMute) {
- mAudioManager.setStreamMute(stream, !isStreamMute);
- } else {
- mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
- packageName, uid);
- if (isStreamMute && direction != 0) {
- mAudioManager.setStreamMute(stream, false);
- }
- }
+ mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
+ packageName, uid);
}
} else {
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
// Nothing to do, the volume cannot be changed
return;
}
- if (isMute) {
+ if (direction == AudioManager.ADJUST_TOGGLE_MUTE
+ || direction == AudioManager.ADJUST_MUTE
+ || direction == AudioManager.ADJUST_UNMUTE) {
Log.w(TAG, "Muting remote playback is not supported");
return;
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 667d02a..4f6b8f2 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -823,7 +823,7 @@
pw.println("User Records:");
count = mUserRecords.size();
for (int i = 0; i < count; i++) {
- UserRecord user = mUserRecords.get(i);
+ UserRecord user = mUserRecords.get(mUserRecords.keyAt(i));
user.dumpLocked(pw, "");
}
}
@@ -872,30 +872,10 @@
try {
String packageName = getContext().getOpPackageName();
if (mUseMasterVolume) {
- boolean isMasterMute = mAudioService.isMasterMute();
- if (direction == MediaSessionManager.DIRECTION_MUTE) {
- mAudioService.setMasterMute(!isMasterMute, flags, packageName, mICallback);
- } else {
mAudioService.adjustMasterVolume(direction, flags, packageName);
- // Do not call setMasterMute when direction = 0 which is used just to
- // show the UI.
- if (isMasterMute && direction != 0) {
- mAudioService.setMasterMute(false, flags, packageName, mICallback);
- }
- }
} else {
- boolean isStreamMute = mAudioService.isStreamMute(suggestedStream);
- if (direction == MediaSessionManager.DIRECTION_MUTE) {
- mAudioManager.setStreamMute(suggestedStream, !isStreamMute);
- } else {
- mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
- flags, packageName);
- // Do not call setStreamMute when direction = 0 which is used just to
- // show the UI.
- if (isStreamMute && direction != 0) {
- mAudioManager.setStreamMute(suggestedStream, false);
- }
- }
+ mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
+ flags, packageName);
}
} catch (RemoteException e) {
Log.e(TAG, "Error adjusting default volume.", e);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 5d73149..6660843 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -26,6 +26,7 @@
import android.util.EventLog;
import android.util.Slog;
import android.util.TypedValue;
+
import com.android.server.EventLogTags;
import java.io.PrintWriter;
@@ -126,6 +127,7 @@
boolean oldFullscreen = mFullscreen;
if (mDisplayContent != null) {
mDisplayContent.getLogicalDisplayRect(mTmpRect);
+ bounds.intersect(mTmpRect); // ensure bounds are entirely within the display rect
mFullscreen = mTmpRect.equals(bounds);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e4d0b77..bec0f66 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1914,12 +1914,12 @@
}
}
- public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
+ public void setPasswordQuality(ComponentName who, int quality) {
if (!mHasFeature) {
return;
}
+ final int userHandle = UserHandle.getCallingUserId();
validateQualityConstant(quality);
- enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
@@ -1963,11 +1963,11 @@
}
}
- public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumLength(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2010,11 +2010,11 @@
}
}
- public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
+ public void setPasswordHistoryLength(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2057,11 +2057,11 @@
}
}
- public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
+ public void setPasswordExpirationTimeout(ComponentName who, long timeout) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2226,11 +2226,11 @@
}
}
- public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumUpperCase(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2273,8 +2273,8 @@
}
}
- public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
- enforceCrossUserPermission(userHandle);
+ public void setPasswordMinimumLowerCase(ComponentName who, int length) {
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2317,11 +2317,11 @@
}
}
- public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumLetters(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2364,11 +2364,11 @@
}
}
- public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumNumeric(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2411,11 +2411,11 @@
}
}
- public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumSymbols(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2458,11 +2458,11 @@
}
}
- public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumNonLetter(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2522,8 +2522,7 @@
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+ getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
|| policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
return false;
@@ -2556,11 +2555,11 @@
}
}
- public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
+ public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -2632,11 +2631,11 @@
return strictestAdmin;
}
- public boolean resetPassword(String passwordOrNull, int flags, int userHandle) {
+ public boolean resetPassword(String passwordOrNull, int flags) {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "reset the password");
String password = passwordOrNull != null ? passwordOrNull : "";
@@ -2767,11 +2766,11 @@
return true;
}
- public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
+ public void setMaximumTimeToLock(ComponentName who, long timeMs) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -3231,11 +3230,10 @@
}
public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
- String exclusionList, int userHandle) {
+ String exclusionList) {
if (!mHasFeature) {
return null;
}
- enforceCrossUserPermission(userHandle);
synchronized(this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -3261,7 +3259,7 @@
// If the user is not the owner, don't set the global proxy. Fail silently.
if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
Slog.w(LOG_TAG, "Only the owner is allowed to set the global proxy. User "
- + userHandle + " is not permitted.");
+ + UserHandle.getCallingUserId() + " is not permitted.");
return null;
}
if (proxySpec == null) {
@@ -3371,11 +3369,11 @@
* Set the storage encryption request for a single admin. Returns the new total request
* status (for all admins).
*/
- public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
+ public int setStorageEncryption(ComponentName who, boolean encrypt) {
if (!mHasFeature) {
return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
// Check for permissions
if (who == null) {
@@ -3507,11 +3505,11 @@
/**
* Set whether the screen capture is disabled for the user managed by the specified admin.
*/
- public void setScreenCaptureDisabled(ComponentName who, int userHandle, boolean disabled) {
+ public void setScreenCaptureDisabled(ComponentName who, boolean disabled) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -3566,11 +3564,11 @@
/**
* Set whether auto time is required by the specified admin (must be device owner).
*/
- public void setAutoTimeRequired(ComponentName who, int userHandle, boolean required) {
+ public void setAutoTimeRequired(ComponentName who, boolean required) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -3617,11 +3615,11 @@
/**
* Disables all device cameras according to the specified admin.
*/
- public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
+ public void setCameraDisabled(ComponentName who, boolean disabled) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -3666,11 +3664,11 @@
/**
* Selectively disable keyguard features.
*/
- public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
+ public void setKeyguardDisabledFeatures(ComponentName who, int which) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "disable keyguard features");
synchronized (this) {
if (who == null) {
@@ -3920,7 +3918,7 @@
Bundle userRestrictions = mUserManager.getUserRestrictions();
mUserManager.setUserRestrictions(new Bundle(), userHandle);
if (userRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)) {
- audioManager.setMasterMute(false);
+ audioManager.adjustMasterVolume(AudioManager.ADJUST_UNMUTE, 0);
}
if (userRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE)) {
audioManager.setMicrophoneMute(false);
@@ -4216,11 +4214,11 @@
}
public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
- PersistableBundle args, int userHandle) {
+ PersistableBundle args) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "set trust agent configuration");
synchronized (this) {
if (admin == null) {
@@ -4841,7 +4839,8 @@
if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)) {
iAudioService.setMicrophoneMute(true, who.getPackageName());
} else if (UserManager.DISALLOW_ADJUST_VOLUME.equals(key)) {
- iAudioService.setMasterMute(true, 0, who.getPackageName(), null);
+ iAudioService.adjustMasterVolume(AudioManager.ADJUST_MUTE, 0,
+ who.getPackageName());
}
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to talk to AudioService.", re);
@@ -4906,7 +4905,8 @@
if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)) {
iAudioService.setMicrophoneMute(false, who.getPackageName());
} else if (UserManager.DISALLOW_ADJUST_VOLUME.equals(key)) {
- iAudioService.setMasterMute(false, 0, who.getPackageName(), null);
+ iAudioService.adjustMasterVolume(AudioManager.ADJUST_UNMUTE, 0,
+ who.getPackageName());
}
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to talk to AudioService.", re);
@@ -5361,8 +5361,6 @@
@Override
public void setMasterVolumeMuted(ComponentName who, boolean on) {
- final ContentResolver contentResolver = mContext.getContentResolver();
-
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -5372,7 +5370,9 @@
IAudioService iAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
try{
- iAudioService.setMasterMute(on, 0, who.getPackageName(), null);
+ iAudioService.adjustMasterVolume(
+ on ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE, 0,
+ who.getPackageName());
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to setMasterMute", re);
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index a180f44..108c0af 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -260,6 +260,7 @@
/** @hide */
public void onConferenceParticipantsChanged(Connection c,
List<ConferenceParticipant> participants) {}
+ public void onConferenceStarted() {}
}
/** @hide */
@@ -1001,14 +1002,11 @@
/**
* Informs listeners that this {@code Connection} has processed a character in the post-dial
* started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
- * (b) it has encountered a "wait" character; and (c) it wishes to signal Telecom to play
- * the corresponding DTMF tone locally.
+ * and (b) it wishes to signal Telecom to play the corresponding DTMF tone locally.
*
* @param nextChar The DTMF character that was just processed by the {@code Connection}.
- *
- * @hide
*/
- public final void setNextPostDialWaitChar(char nextChar) {
+ public final void setNextPostDialChar(char nextChar) {
checkImmutable();
for (Listener l : mListeners) {
l.onPostDialChar(this, nextChar);
@@ -1422,4 +1420,13 @@
l.onConferenceParticipantsChanged(this, conferenceParticipants);
}
}
+
+ /**
+ * Notifies listeners that a conference call has been started.
+ */
+ protected void notifyConferenceStarted() {
+ for (Listener l : mListeners) {
+ l.onConferenceStarted();
+ }
+ }
}
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 073dcd5f..43a92cb 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -235,8 +235,12 @@
@Override
public void setVideoProvider(String callId, IVideoProvider videoProvider) {
+ RemoteConnection.VideoProvider remoteVideoProvider = null;
+ if (videoProvider != null) {
+ remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider);
+ }
findConnectionForAction(callId, "setVideoProvider")
- .setVideoProvider(new RemoteConnection.VideoProvider(videoProvider));
+ .setVideoProvider(remoteVideoProvider);
}
@Override
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index a59505c..2d874985 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -39,8 +39,6 @@
import android.util.SparseIntArray;
import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
import java.util.Locale;
@@ -2200,8 +2198,8 @@
if (!TextUtils.isEmpty(dialStr)) {
if (isReallyDialable(dialStr.charAt(0)) &&
isNonSeparator(dialStr)) {
- String currIso = SystemProperties.get(PROPERTY_OPERATOR_ISO_COUNTRY, "");
- String defaultIso = SystemProperties.get(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
+ String currIso = TelephonyManager.getDefault().getNetworkCountryIso();
+ String defaultIso = TelephonyManager.getDefault().getSimCountryIso();
if (!TextUtils.isEmpty(currIso) && !TextUtils.isEmpty(defaultIso)) {
return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr,
getFormatTypeFromCountryCode(currIso),
@@ -2223,7 +2221,7 @@
public static String cdmaCheckAndProcessPlusCodeForSms(String dialStr) {
if (!TextUtils.isEmpty(dialStr)) {
if (isReallyDialable(dialStr.charAt(0)) && isNonSeparator(dialStr)) {
- String defaultIso = SystemProperties.get(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
+ String defaultIso = TelephonyManager.getDefault().getSimCountryIso();
if (!TextUtils.isEmpty(defaultIso)) {
int format = getFormatTypeFromCountryCode(defaultIso);
return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr, format, format);
@@ -2388,11 +2386,11 @@
private static String getCurrentIdp(boolean useNanp) {
String ps = null;
- if(useNanp)
+ if (useNanp) {
ps = NANP_IDP_STRING;
- else{
+ } else {
// in case, there is no IDD is found, we shouldn't convert it.
- ps = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, PLUS_SIGN_STRING);
+ ps = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, PLUS_SIGN_STRING);
}
return ps;
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index c67629d..aca94e9 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1101,9 +1101,7 @@
// What else can we do?
return false;
}
- // FIXME: use better way to get roaming status instead of reading from system property
- return Boolean.parseBoolean(TelephonyManager.getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null));
+ return TelephonyManager.getDefault().isNetworkRoaming(subId);
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 339fc6d..ba5a679 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1077,7 +1077,7 @@
* on a CDMA network).
*/
public String getNetworkOperator() {
- return getNetworkOperator(getDefaultSubscription());
+ return getNetworkOperatorForPhone(getDefaultPhone());
}
/**
@@ -1091,8 +1091,23 @@
* @param subId
*/
/** {@hide} */
- public String getNetworkOperator(int subId) {
+ public String getNetworkOperatorForSubscription(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
+ return getNetworkOperatorForPhone(phoneId);
+ }
+
+ /**
+ * Returns the numeric name (MCC+MNC) of current registered operator
+ * for a particular subscription.
+ * <p>
+ * Availability: Only when user is registered to a network. Result may be
+ * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
+ * on a CDMA network).
+ *
+ * @param phoneId
+ * @hide
+ **/
+ public String getNetworkOperatorForPhone(int phoneId) {
return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
}
@@ -1130,7 +1145,7 @@
* on a CDMA network).
*/
public String getNetworkCountryIso() {
- return getNetworkCountryIso(getDefaultSubscription());
+ return getNetworkCountryIsoForPhone(getDefaultPhone());
}
/**
@@ -1144,8 +1159,23 @@
* @param subId for which Network CountryIso is returned
*/
/** {@hide} */
- public String getNetworkCountryIso(int subId) {
+ public String getNetworkCountryIsoForSubscription(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
+ return getNetworkCountryIsoForPhone(phoneId);
+ }
+
+ /**
+ * Returns the ISO country code equivalent of the current registered
+ * operator's MCC (Mobile Country Code) of a subscription.
+ * <p>
+ * Availability: Only when user is registered to a network. Result may be
+ * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
+ * on a CDMA network).
+ *
+ * @param phoneId for which Network CountryIso is returned
+ */
+ /** {@hide} */
+ public String getNetworkCountryIsoForPhone(int phoneId) {
return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
}
@@ -1537,6 +1567,34 @@
* @see #getSimState
*/
public String getSimOperator() {
+ return getSimOperatorNumeric();
+ }
+
+ /**
+ * Returns the MCC+MNC (mobile country code + mobile network code) of the
+ * provider of the SIM. 5 or 6 decimal digits.
+ * <p>
+ * Availability: SIM state must be {@link #SIM_STATE_READY}
+ *
+ * @see #getSimState
+ *
+ * @param subId for which SimOperator is returned
+ * @hide
+ */
+ public String getSimOperator(int subId) {
+ return getSimOperatorNumericForSubscription(subId);
+ }
+
+ /**
+ * Returns the MCC+MNC (mobile country code + mobile network code) of the
+ * provider of the SIM. 5 or 6 decimal digits.
+ * <p>
+ * Availability: SIM state must be {@link #SIM_STATE_READY}
+ *
+ * @see #getSimState
+ * @hide
+ */
+ public String getSimOperatorNumeric() {
int subId = SubscriptionManager.getDefaultDataSubId();
if (!SubscriptionManager.isUsableSubIdValue(subId)) {
subId = SubscriptionManager.getDefaultSmsSubId();
@@ -1547,8 +1605,8 @@
}
}
}
- Rlog.d(TAG, "getSimOperator(): default subId=" + subId);
- return getSimOperator(subId);
+ Rlog.d(TAG, "getSimOperatorNumeric(): default subId=" + subId);
+ return getSimOperatorNumericForSubscription(subId);
}
/**
@@ -1560,14 +1618,24 @@
* @see #getSimState
*
* @param subId for which SimOperator is returned
+ * @hide
*/
- /** {@hide} */
- public String getSimOperator(int subId) {
+ public String getSimOperatorNumericForSubscription(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- String operator = getTelephonyProperty(phoneId,
+ return getSimOperatorNumericForPhone(phoneId);
+ }
+
+ /**
+ * Returns the MCC+MNC (mobile country code + mobile network code) of the
+ * provider of the SIM for a particular subscription. 5 or 6 decimal digits.
+ * <p>
+ *
+ * @param phoneId for which SimOperator is returned
+ * @hide
+ */
+ public String getSimOperatorNumericForPhone(int phoneId) {
+ return getTelephonyProperty(phoneId,
TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
- Rlog.d(TAG, "getSimOperator: subId=" + subId + " operator=" + operator);
- return operator;
}
/**
@@ -1578,7 +1646,7 @@
* @see #getSimState
*/
public String getSimOperatorName() {
- return getSimOperatorName(getDefaultSubscription());
+ return getSimOperatorNameForPhone(getDefaultPhone());
}
/**
@@ -1589,30 +1657,61 @@
* @see #getSimState
*
* @param subId for which SimOperatorName is returned
+ * @hide
*/
- /** {@hide} */
- public String getSimOperatorName(int subId) {
+ public String getSimOperatorNameForSubscription(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "");
+ return getSimOperatorNameForPhone(phoneId);
+ }
+
+ /**
+ * Returns the Service Provider Name (SPN).
+ *
+ * @hide
+ */
+ public String getSimOperatorNameForPhone(int phoneId) {
+ return getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "");
}
/**
* Returns the ISO country code equivalent for the SIM provider's country code.
*/
public String getSimCountryIso() {
- return getSimCountryIso(getDefaultSubscription());
+ return getSimCountryIsoForPhone(getDefaultPhone());
}
/**
* Returns the ISO country code equivalent for the SIM provider's country code.
*
* @param subId for which SimCountryIso is returned
+ *
+ * @hide
*/
- /** {@hide} */
public String getSimCountryIso(int subId) {
+ return getSimCountryIsoForSubscription(subId);
+ }
+
+ /**
+ * Returns the ISO country code equivalent for the SIM provider's country code.
+ *
+ * @param subId for which SimCountryIso is returned
+ *
+ * @hide
+ */
+ public String getSimCountryIsoForSubscription(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
- "");
+ return getSimCountryIsoForPhone(phoneId);
+ }
+
+ /**
+ * Returns the ISO country code equivalent for the SIM provider's country code.
+ *
+ * @hide
+ */
+ public String getSimCountryIsoForPhone(int phoneId) {
+ return getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
}
/**
@@ -3677,4 +3776,344 @@
return false;
}
}
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
+ *
+ * @hide
+ */
+ public void setSimOperatorNumeric(String numeric) {
+ int phoneId = getDefaultPhone();
+ setSimOperatorNumericForPhone(phoneId, numeric);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
+ *
+ * @hide
+ */
+ public void setSimOperatorNumericForPhone(int phoneId, String numeric) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, numeric);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
+ *
+ * @hide
+ */
+ public void setSimOperatorName(String name) {
+ int phoneId = getDefaultPhone();
+ setSimOperatorNameForPhone(phoneId, name);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
+ *
+ * @hide
+ */
+ public void setSimOperatorNameForPhone(int phoneId, String name) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, name);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the default phone.
+ *
+ * @hide
+ */
+ public void setSimCountryIso(String iso) {
+ int phoneId = getDefaultPhone();
+ setSimCountryIsoForPhone(phoneId, iso);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the given phone.
+ *
+ * @hide
+ */
+ public void setSimCountryIsoForPhone(int phoneId, String iso) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_SIM_STATE for the default phone.
+ *
+ * @hide
+ */
+ public void setSimState(String state) {
+ int phoneId = getDefaultPhone();
+ setSimStateForPhone(phoneId, state);
+ }
+
+ /**
+ * Set TelephonyProperties.PROPERTY_SIM_STATE for the given phone.
+ *
+ * @hide
+ */
+ public void setSimStateForPhone(int phoneId, String state) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_SIM_STATE, state);
+ }
+
+ /**
+ * Set baseband version for the default phone.
+ *
+ * @param version baseband version
+ * @hide
+ */
+ public void setBasebandVersion(String version) {
+ int phoneId = getDefaultPhone();
+ setBasebandVersionForPhone(phoneId, version);
+ }
+
+ /**
+ * Set baseband version by phone id.
+ *
+ * @param phoneId for which baseband version is set
+ * @param version baseband version
+ * @hide
+ */
+ public void setBasebandVersionForPhone(int phoneId, String version) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ String prop = TelephonyProperties.PROPERTY_BASEBAND_VERSION +
+ ((phoneId == 0) ? "" : Integer.toString(phoneId));
+ SystemProperties.set(prop, version);
+ }
+ }
+
+ /**
+ * Set phone type for the default phone.
+ *
+ * @param type phone type
+ *
+ * @hide
+ */
+ public void setPhoneType(int type) {
+ int phoneId = getDefaultPhone();
+ setPhoneType(phoneId, type);
+ }
+
+ /**
+ * Set phone type by phone id.
+ *
+ * @param phoneId for which phone type is set
+ * @param type phone type
+ *
+ * @hide
+ */
+ public void setPhoneType(int phoneId, int type) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ TelephonyManager.setTelephonyProperty(phoneId,
+ TelephonyProperties.CURRENT_ACTIVE_PHONE, String.valueOf(type));
+ }
+ }
+
+ /**
+ * Get OTASP number schema for the default phone.
+ *
+ * @param defaultValue default value
+ * @return OTA SP number schema
+ *
+ * @hide
+ */
+ public String getOtaSpNumberSchema(String defaultValue) {
+ int phoneId = getDefaultPhone();
+ return getOtaSpNumberSchemaForPhone(phoneId, defaultValue);
+ }
+
+ /**
+ * Get OTASP number schema by phone id.
+ *
+ * @param phoneId for which OTA SP number schema is get
+ * @param defaultValue default value
+ * @return OTA SP number schema
+ *
+ * @hide
+ */
+ public String getOtaSpNumberSchemaForPhone(int phoneId, String defaultValue) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ return TelephonyManager.getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Get SMS receive capable from system property for the default phone.
+ *
+ * @param defaultValue default value
+ * @return SMS receive capable
+ *
+ * @hide
+ */
+ public boolean getSmsReceiveCapable(boolean defaultValue) {
+ int phoneId = getDefaultPhone();
+ return getSmsReceiveCapableForPhone(phoneId, defaultValue);
+ }
+
+ /**
+ * Get SMS receive capable from system property by phone id.
+ *
+ * @param phoneId for which SMS receive capable is get
+ * @param defaultValue default value
+ * @return SMS receive capable
+ *
+ * @hide
+ */
+ public boolean getSmsReceiveCapableForPhone(int phoneId, boolean defaultValue) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ return Boolean.valueOf(TelephonyManager.getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_SMS_RECEIVE, String.valueOf(defaultValue)));
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Get SMS send capable from system property for the default phone.
+ *
+ * @param defaultValue default value
+ * @return SMS send capable
+ *
+ * @hide
+ */
+ public boolean getSmsSendCapable(boolean defaultValue) {
+ int phoneId = getDefaultPhone();
+ return getSmsSendCapableForPhone(phoneId, defaultValue);
+ }
+
+ /**
+ * Get SMS send capable from system property by phone id.
+ *
+ * @param phoneId for which SMS send capable is get
+ * @param defaultValue default value
+ * @return SMS send capable
+ *
+ * @hide
+ */
+ public boolean getSmsSendCapableForPhone(int phoneId, boolean defaultValue) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ return Boolean.valueOf(TelephonyManager.getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_SMS_SEND, String.valueOf(defaultValue)));
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Set the alphabetic name of current registered operator.
+ * @param name the alphabetic name of current registered operator.
+ * @hide
+ */
+ public void setNetworkOperatorName(String name) {
+ int phoneId = getDefaultPhone();
+ setNetworkOperatorNameForPhone(phoneId, name);
+ }
+
+ /**
+ * Set the alphabetic name of current registered operator.
+ * @param phoneId which phone you want to set
+ * @param name the alphabetic name of current registered operator.
+ * @hide
+ */
+ public void setNetworkOperatorNameForPhone(int phoneId, String name) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, name);
+ }
+ }
+
+ /**
+ * Set the numeric name (MCC+MNC) of current registered operator.
+ * @param operator the numeric name (MCC+MNC) of current registered operator
+ * @hide
+ */
+ public void setNetworkOperatorNumeric(String numeric) {
+ int phoneId = getDefaultPhone();
+ setNetworkOperatorNumericForPhone(phoneId, numeric);
+ }
+
+ /**
+ * Set the numeric name (MCC+MNC) of current registered operator.
+ * @param phoneId for which phone type is set
+ * @param operator the numeric name (MCC+MNC) of current registered operator
+ * @hide
+ */
+ public void setNetworkOperatorNumericForPhone(int phoneId, String numeric) {
+ setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, numeric);
+ }
+
+ /**
+ * Set roaming state of the current network, for GSM purposes.
+ * @param isRoaming is network in romaing state or not
+ * @hide
+ */
+ public void setNetworkRoaming(boolean isRoaming) {
+ int phoneId = getDefaultPhone();
+ setNetworkRoamingForPhone(phoneId, isRoaming);
+ }
+
+ /**
+ * Set roaming state of the current network, for GSM purposes.
+ * @param phoneId which phone you want to set
+ * @param isRoaming is network in romaing state or not
+ * @hide
+ */
+ public void setNetworkRoamingForPhone(int phoneId, boolean isRoaming) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
+ isRoaming ? "true" : "false");
+ }
+ }
+
+ /**
+ * Set the ISO country code equivalent of the current registered
+ * operator's MCC (Mobile Country Code).
+ * @param iso the ISO country code equivalent of the current registered
+ * @hide
+ */
+ public void setNetworkCountryIso(String iso) {
+ int phoneId = getDefaultPhone();
+ setNetworkCountryIsoForPhone(phoneId, iso);
+ }
+
+ /**
+ * Set the ISO country code equivalent of the current registered
+ * operator's MCC (Mobile Country Code).
+ * @param phoneId which phone you want to set
+ * @param iso the ISO country code equivalent of the current registered
+ * @hide
+ */
+ public void setNetworkCountryIsoForPhone(int phoneId, String iso) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
+ }
+ }
+
+ /**
+ * Set the network type currently in use on the device for data transmission.
+ * @param type the network type currently in use on the device for data transmission
+ * @hide
+ */
+ public void setDataNetworkType(int type) {
+ int phoneId = getDefaultPhone();
+ setDataNetworkTypeForPhone(phoneId, type);
+ }
+
+ /**
+ * Set the network type currently in use on the device for data transmission.
+ * @param phoneId which phone you want to set
+ * @param type the network type currently in use on the device for data transmission
+ * @hide
+ */
+ public void setDataNetworkTypeForPhone(int phoneId, int type) {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ setTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
+ ServiceState.rilRadioTechnologyToString(type));
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 6fdf121..70ac268 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -453,10 +453,6 @@
*/
void setPremiumSmsPermission(String packageName, int permission);
- /**
- * Set the SMS send permission for the specified package.
- * Requires system permission.
- */
/**
* Set the SMS send permission for the specified package.
* Requires system permission.
@@ -483,6 +479,14 @@
*/
boolean isImsSmsSupportedForSubscriber(int subId);
+ /**
+ * User needs to pick SIM for SMS if multiple SIMs present and if current subId passed in is not
+ * active/valid.
+ * @param subId current subId for sending SMS
+ * @return true if SIM for SMS sending needs to be chosen
+ */
+ boolean isSmsSimPickActivityNeeded(int subId);
+
/*
* get user prefered SMS subId
* @return subId id
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index a2bd6d7..18036927 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -614,15 +614,27 @@
int pos = value.indexOf('/');
String idName = value.substring(pos + 1);
+ boolean create = value.startsWith("@+");
+ boolean isFrameworkId =
+ mPlatformFile || value.startsWith("@android") || value.startsWith("@+android");
- // if this is a framework id
- if (mPlatformFile || value.startsWith("@android") || value.startsWith("@+android")) {
- // look for idName in the android R classes
- return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
+ // Look for the idName in project or android R class depending on isPlatform.
+ if (create) {
+ Integer idValue;
+ if (isFrameworkId) {
+ idValue = Bridge.getResourceId(ResourceType.ID, idName);
+ } else {
+ idValue = mContext.getProjectCallback().getResourceId(ResourceType.ID, idName);
+ }
+ return idValue == null ? defValue : idValue;
}
-
- // look for idName in the project R class.
- return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
+ // This calls the same method as in if(create), but doesn't create a dynamic id, if
+ // one is not found.
+ if (isFrameworkId) {
+ return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
+ } else {
+ return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
+ }
}
// not a direct id valid reference? resolve it
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 3953624..3441878 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
@@ -289,6 +289,11 @@
value = mRenderResources.resolveResValue(value);
}
+ if (value == null) {
+ // unable to find the attribute.
+ return false;
+ }
+
// check if this is a style resource
if (value instanceof StyleResourceValue) {
// get the id that will represent this style.
@@ -296,7 +301,6 @@
return true;
}
-
int a;
// if this is a framework value.
if (value.isFramework()) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
new file mode 100644
index 0000000..e5023b8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+import com.android.resources.ResourceType;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+/**
+ * Assumes that the AppCompat library is present in the project's classpath and creates an
+ * actionbar around it.
+ */
+public class AppCompatActionBar extends BridgeActionBar {
+
+ private Object mWindowDecorActionBar;
+ private static final String WINDOW_ACTION_BAR_CLASS = "android.support.v7.internal.app.WindowDecorActionBar";
+ private Class<?> mWindowActionBarClass;
+
+ /**
+ * Inflate the action bar and attach it to {@code parentView}
+ */
+ public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull ViewGroup parentView) {
+ super(context, params, parentView);
+ int contentRootId = context.getProjectResourceValue(ResourceType.ID,
+ "action_bar_activity_content", 0);
+ View contentView = getDecorContent().findViewById(contentRootId);
+ if (contentView != null) {
+ assert contentView instanceof FrameLayout;
+ setContentRoot(((FrameLayout) contentView));
+ } else {
+ // Something went wrong. Create a new FrameLayout in the enclosing layout.
+ FrameLayout contentRoot = new FrameLayout(context);
+ setMatchParent(contentRoot);
+ mEnclosingLayout.addView(contentRoot);
+ setContentRoot(contentRoot);
+ }
+ try {
+ Class[] constructorParams = {View.class};
+ Object[] constructorArgs = {getDecorContent()};
+ mWindowDecorActionBar = params.getProjectCallback().loadView(WINDOW_ACTION_BAR_CLASS,
+ constructorParams, constructorArgs);
+
+ mWindowActionBarClass = mWindowDecorActionBar == null ? null :
+ mWindowDecorActionBar.getClass();
+ setupActionBar();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected ResourceValue getLayoutResource(BridgeContext context) {
+ // We always assume that the app has requested the action bar.
+ return context.getRenderResources().getProjectResource(ResourceType.LAYOUT,
+ "abc_screen_toolbar");
+ }
+
+ @Override
+ protected void setTitle(CharSequence title) {
+ if (title != null && mWindowDecorActionBar != null) {
+ Method setTitle = getMethod(mWindowActionBarClass, "setTitle", CharSequence.class);
+ invoke(setTitle, mWindowDecorActionBar, title);
+ }
+ }
+
+ @Override
+ protected void setSubtitle(CharSequence subtitle) {
+ if (subtitle != null && mWindowDecorActionBar != null) {
+ Method setSubtitle = getMethod(mWindowActionBarClass, "setSubtitle", CharSequence.class);
+ invoke(setSubtitle, mWindowDecorActionBar, subtitle);
+ }
+ }
+
+ @Override
+ protected void setIcon(String icon) {
+ // Do this only if the action bar doesn't already have an icon.
+ if (icon != null && !icon.isEmpty() && mWindowDecorActionBar != null) {
+ if (((Boolean) invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
+ )) {
+ Drawable iconDrawable = getDrawable(icon, false);
+ if (iconDrawable != null) {
+ Method setIcon = getMethod(mWindowActionBarClass, "setIcon", Drawable.class);
+ invoke(setIcon, mWindowDecorActionBar, iconDrawable);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void setHomeAsUp(boolean homeAsUp) {
+ if (mWindowDecorActionBar != null) {
+ Method setHomeAsUp = getMethod(mWindowActionBarClass,
+ "setDefaultDisplayHomeAsUpEnabled", boolean.class);
+ invoke(setHomeAsUp, mWindowDecorActionBar, homeAsUp);
+ }
+ }
+
+ @Override
+ public void createMenuPopup() {
+ // it's hard to addd menus to appcompat's actionbar, since it'll use a lot of reflection.
+ // so we skip it for now.
+ }
+
+ @Nullable
+ private static Method getMethod(Class<?> owner, String name, Class<?>... parameterTypes) {
+ try {
+ return owner == null ? null : owner.getMethod(name, parameterTypes);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Nullable
+ private static Object invoke(Method method, Object owner, Object... args) {
+ try {
+ return method == null ? null : method.invoke(owner, args);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ // TODO: this is duplicated from FrameworkActionBarWrapper$WindowActionBarWrapper
+ @Nullable
+ private Drawable getDrawable(@NonNull String name, boolean isFramework) {
+ RenderResources res = mBridgeContext.getRenderResources();
+ ResourceValue value = res.findResValue(name, isFramework);
+ value = res.resolveResValue(value);
+ if (value != null) {
+ return ResourceHelper.getDrawable(value, mBridgeContext);
+ }
+ return null;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
new file mode 100644
index 0000000..b29d25f
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.annotations.NonNull;
+import com.android.ide.common.rendering.api.ActionBarCallback;
+import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.android.BridgeContext;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
+
+/**
+ * An abstraction over two implementations of the ActionBar - framework and appcompat.
+ */
+public abstract class BridgeActionBar {
+ // Store a reference to the context so that we don't have to cast it repeatedly.
+ @NonNull protected final BridgeContext mBridgeContext;
+ @NonNull protected final SessionParams mParams;
+ // A Layout that contains the inflated action bar. The menu popup is added to this layout.
+ @NonNull protected final ViewGroup mEnclosingLayout;
+
+ private final View mDecorContent;
+ private final ActionBarCallback mCallback;
+
+ @NonNull private FrameLayout mContentRoot;
+
+ public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull ViewGroup parentView) {
+ mBridgeContext = context;
+ mParams = params;
+ mCallback = params.getProjectCallback().getActionBarCallback();
+ ResourceValue layoutName = getLayoutResource(context);
+ if (layoutName == null) {
+ throw new RuntimeException("Unable to find the layout for Action Bar.");
+ }
+ int layoutId;
+ if (layoutName.isFramework()) {
+ layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
+ layoutName.getName(), 0);
+ } else {
+ layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
+ layoutName.getName(), 0);
+
+ }
+ if (layoutId == 0) {
+ throw new RuntimeException(
+ String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
+ layoutName.getName(), layoutName.getResourceType()));
+ }
+ if (mCallback.isOverflowPopupNeeded()) {
+ // Create a RelativeLayout around the action bar, to which the overflow popup may be
+ // added.
+ mEnclosingLayout = new RelativeLayout(mBridgeContext);
+ setMatchParent(mEnclosingLayout);
+ parentView.addView(mEnclosingLayout);
+ } else {
+ mEnclosingLayout = parentView;
+ }
+
+ // Inflate action bar layout.
+ mDecorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true);
+
+ }
+
+ /**
+ * Returns the Layout Resource that should be used to inflate the action bar. This layout
+ * should cover the complete screen, and have a FrameLayout included, where the content will
+ * be inflated.
+ */
+ protected abstract ResourceValue getLayoutResource(BridgeContext context);
+
+ protected void setContentRoot(FrameLayout contentRoot) {
+ mContentRoot = contentRoot;
+ }
+
+ @NonNull
+ public FrameLayout getContentRoot() {
+ return mContentRoot;
+ }
+
+ /**
+ * Returns the view inflated. This should contain both the ActionBar and the app content in it.
+ */
+ protected View getDecorContent() {
+ return mDecorContent;
+ }
+
+ /** Setup things like the title, subtitle, icon etc. */
+ protected void setupActionBar() {
+ setTitle();
+ setSutTitle();
+ setIcon();
+ setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP);
+ }
+
+ protected abstract void setTitle(CharSequence title);
+ protected abstract void setSubtitle(CharSequence subtitle);
+ protected abstract void setIcon(String icon);
+ protected abstract void setHomeAsUp(boolean homeAsUp);
+
+ private void setTitle() {
+ RenderResources res = mBridgeContext.getRenderResources();
+
+ String title = mParams.getAppLabel();
+ ResourceValue titleValue = res.findResValue(title, false);
+ if (titleValue != null && titleValue.getValue() != null) {
+ setTitle(titleValue.getValue());
+ } else {
+ setTitle(title);
+ }
+ }
+
+ private void setSutTitle() {
+ String subTitle = mCallback.getSubTitle();
+ if (subTitle != null) {
+ setSubtitle(subTitle);
+ }
+ }
+
+ private void setIcon() {
+ String appIcon = mParams.getAppIcon();
+ if (appIcon != null) {
+ setIcon(appIcon);
+ }
+ }
+
+ public abstract void createMenuPopup();
+
+ public ActionBarCallback getCallBack() {
+ return mCallback;
+ }
+
+ protected static void setMatchParent(View view) {
+ view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
similarity index 76%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
index 2ff8d37..a1c9065 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
@@ -31,7 +31,7 @@
import android.content.res.TypedArray;
import android.util.DisplayMetrics;
import android.util.TypedValue;
-import android.view.LayoutInflater;
+import android.view.InflateException;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
@@ -44,70 +44,30 @@
import java.util.ArrayList;
-public class ActionBarLayout {
+/**
+ * Creates the ActionBar as done by the framework.
+ */
+public class FrameworkActionBar extends BridgeActionBar {
private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
// The Action Bar
- @NonNull
- private CustomActionBarWrapper mActionBar;
-
- // Store another reference to the context so that we don't have to cast it repeatedly.
- @NonNull
- private final BridgeContext mBridgeContext;
-
- @NonNull
- private FrameLayout mContentRoot;
+ @NonNull private FrameworkActionBarWrapper mActionBar;
// A fake parent for measuring views.
- @Nullable
- private ViewGroup mMeasureParent;
-
- // A Layout that contains the inflated action bar. The menu popup is added to this layout.
- @NonNull
- private final RelativeLayout mEnclosingLayout;
+ @Nullable private ViewGroup mMeasureParent;
/**
* Inflate the action bar and attach it to {@code parentView}
*/
- public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params,
+ public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
@NonNull ViewGroup parentView) {
+ super(context, params, parentView);
- mBridgeContext = context;
+ View decorContent = getDecorContent();
- ResourceValue layoutName = context.getRenderResources()
- .findItemInTheme(LAYOUT_ATTR_NAME, true);
- if (layoutName != null) {
- // We may need to resolve the reference obtained.
- layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
- layoutName.isFramework());
- }
- int layoutId = 0;
- String error = null;
- if (layoutName == null) {
- error = "Unable to find action bar layout (" + LAYOUT_ATTR_NAME
- + ") in the current theme.";
- } else {
- layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
- layoutName.getName(), 0);
- if (layoutId == 0) {
- error = String.format("Unable to resolve attribute \"%s\" of type \"%s\"",
- layoutName.getName(), layoutName.getResourceType());
- }
- }
- if (layoutId == 0) {
- throw new RuntimeException(error);
- }
- // Create a RelativeLayout to hold the action bar. The layout is needed so that we may
- // add the menu popup to it.
- mEnclosingLayout = new RelativeLayout(mBridgeContext);
- setMatchParent(mEnclosingLayout);
- parentView.addView(mEnclosingLayout);
-
- // Inflate action bar layout.
- View decorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true);
-
- mActionBar = CustomActionBarWrapper.getActionBarWrapper(context, params, decorContent);
+ mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(),
+ decorContent);
FrameLayout contentRoot = (FrameLayout) mEnclosingLayout.findViewById(android.R.id.content);
@@ -117,27 +77,62 @@
contentRoot = new FrameLayout(context);
setMatchParent(contentRoot);
mEnclosingLayout.addView(contentRoot);
- mContentRoot = contentRoot;
+ setContentRoot(contentRoot);
} else {
- mContentRoot = contentRoot;
- mActionBar.setupActionBar();
+ setContentRoot(contentRoot);
+ setupActionBar();
mActionBar.inflateMenus();
}
}
- private void setMatchParent(View view) {
- view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
+ @Override
+ protected ResourceValue getLayoutResource(BridgeContext context) {
+ ResourceValue layoutName =
+ context.getRenderResources().findItemInTheme(LAYOUT_ATTR_NAME, true);
+ if (layoutName != null) {
+ // We may need to resolve the reference obtained.
+ layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
+ layoutName.isFramework());
+ }
+ if (layoutName == null) {
+ throw new InflateException("Unable to find action bar layout (" + LAYOUT_ATTR_NAME
+ + ") in the current theme.");
+ }
+ return layoutName;
+ }
+
+ @Override
+ protected void setupActionBar() {
+ super.setupActionBar();
+ mActionBar.setupActionBar();
+ }
+
+ @Override
+ protected void setHomeAsUp(boolean homeAsUp) {
+ mActionBar.setHomeAsUp(homeAsUp);
+ }
+
+ @Override
+ protected void setTitle(CharSequence title) {
+ mActionBar.setTitle(title);
+ }
+
+ @Override
+ protected void setSubtitle(CharSequence subtitle) {
+ mActionBar.setSubTitle(subtitle);
+ }
+
+ @Override
+ protected void setIcon(String icon) {
+ mActionBar.setIcon(icon);
}
/**
* Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
* the content frame which shall serve as the new content root.
*/
+ @Override
public void createMenuPopup() {
- assert mEnclosingLayout.getChildCount() == 1
- : "Action Bar Menus have already been created.";
-
if (!isOverflowPopupNeeded()) {
return;
}
@@ -193,11 +188,6 @@
return needed;
}
- @NonNull
- public FrameLayout getContentRoot() {
- return mContentRoot;
- }
-
// Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth()
private int measureContentWidth(@NonNull ListAdapter adapter) {
// Menus don't tend to be long, so this is more sane than it looks.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
similarity index 81%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
index 6db722e..44c2cd8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
@@ -19,10 +19,8 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
import com.android.internal.R;
import com.android.internal.app.ToolbarActionBar;
import com.android.internal.app.WindowDecorActionBar;
@@ -54,10 +52,9 @@
/**
* A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
*/
-public abstract class CustomActionBarWrapper {
+public abstract class FrameworkActionBarWrapper {
@NonNull protected ActionBar mActionBar;
- @NonNull protected SessionParams mParams;
@NonNull protected ActionBarCallback mCallback;
@NonNull protected BridgeContext mContext;
@@ -68,49 +65,48 @@
* ?attr/windowActionBarFullscreenDecorLayout
*/
@NonNull
- public static CustomActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
- @NonNull SessionParams params, @NonNull View decorContent) {
+ public static FrameworkActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
+ @NonNull ActionBarCallback callback, @NonNull View decorContent) {
View view = decorContent.findViewById(R.id.action_bar);
if (view instanceof Toolbar) {
- return new ToolbarWrapper(context, params, ((Toolbar) view));
+ return new ToolbarWrapper(context, callback, (Toolbar) view);
} else if (view instanceof ActionBarView) {
- return new WindowActionBarWrapper(context, params, decorContent,
- ((ActionBarView) view));
+ return new WindowActionBarWrapper(context, callback, decorContent,
+ (ActionBarView) view);
} else {
throw new IllegalStateException("Can't make an action bar out of " +
view.getClass().getSimpleName());
}
}
- CustomActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+ FrameworkActionBarWrapper(@NonNull BridgeContext context, ActionBarCallback callback,
@NonNull ActionBar actionBar) {
mActionBar = actionBar;
- mParams = params;
- mCallback = params.getProjectCallback().getActionBarCallback();
+ mCallback = callback;
mContext = context;
}
+ /** A call to setup any custom properties. */
protected void setupActionBar() {
- // Do the things that are common to all implementations.
- RenderResources res = mContext.getRenderResources();
+ // Nothing to do here.
+ }
- String title = mParams.getAppLabel();
- ResourceValue titleValue = res.findResValue(title, false);
- if (titleValue != null && titleValue.getValue() != null) {
- mActionBar.setTitle(titleValue.getValue());
- } else {
- mActionBar.setTitle(title);
- }
+ public void setTitle(CharSequence title) {
+ mActionBar.setTitle(title);
+ }
- String subTitle = mCallback.getSubTitle();
+ public void setSubTitle(CharSequence subTitle) {
if (subTitle != null) {
mActionBar.setSubtitle(subTitle);
}
+ }
- // Add show home as up icon.
- if (mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP) {
- mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
- }
+ public void setHomeAsUp(boolean homeAsUp) {
+ mActionBar.setDisplayHomeAsUpEnabled(homeAsUp);
+ }
+
+ public void setIcon(String icon) {
+ // Nothing to do.
}
protected boolean isSplit() {
@@ -186,15 +182,14 @@
* Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
* Toolbar using a common API.
*/
- private static class ToolbarWrapper extends CustomActionBarWrapper {
+ private static class ToolbarWrapper extends FrameworkActionBarWrapper {
@NonNull
private final Toolbar mToolbar; // This is the view.
- ToolbarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+ ToolbarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
@NonNull Toolbar toolbar) {
- super(context, params, new ToolbarActionBar(toolbar, "", new WindowCallback())
- );
+ super(context, callback, new ToolbarActionBar(toolbar, "", new WindowCallback()));
mToolbar = toolbar;
}
@@ -248,19 +243,17 @@
* Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
* access to it using a common API.
*/
- private static class WindowActionBarWrapper extends CustomActionBarWrapper {
+ private static class WindowActionBarWrapper extends FrameworkActionBarWrapper {
- @NonNull
- private final WindowDecorActionBar mActionBar;
- @NonNull
- private final ActionBarView mActionBarView;
- @NonNull
- private final View mDecorContentRoot;
+ @NonNull private final WindowDecorActionBar mActionBar;
+ @NonNull private final ActionBarView mActionBarView;
+ @NonNull private final View mDecorContentRoot;
private MenuBuilder mMenuBuilder;
- public WindowActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
- @NonNull View decorContentRoot, @NonNull ActionBarView actionBarView) {
- super(context, params, new WindowDecorActionBar(decorContentRoot));
+ public WindowActionBarWrapper(@NonNull BridgeContext context,
+ @NonNull ActionBarCallback callback, @NonNull View decorContentRoot,
+ @NonNull ActionBarView actionBarView) {
+ super(context, callback, new WindowDecorActionBar(decorContentRoot));
mActionBarView = actionBarView;
mActionBar = ((WindowDecorActionBar) super.mActionBar);
mDecorContentRoot = decorContentRoot;
@@ -268,7 +261,6 @@
@Override
protected void setupActionBar() {
- super.setupActionBar();
// Set the navigation mode.
int navMode = mCallback.getNavigationMode();
@@ -278,16 +270,6 @@
setupTabs(3);
}
- String icon = mParams.getAppIcon();
- // If the action bar style doesn't specify an icon, set the icon obtained from the
- // session params.
- if (!mActionBar.hasIcon() && icon != null) {
- Drawable iconDrawable = getDrawable(icon, false);
- if (iconDrawable != null) {
- mActionBar.setIcon(iconDrawable);
- }
- }
-
// Set action bar to be split, if needed.
ViewGroup splitView = (ViewGroup) mDecorContentRoot.findViewById(R.id.split_action_bar);
if (splitView != null) {
@@ -300,6 +282,17 @@
}
@Override
+ public void setIcon(String icon) {
+ // Set the icon only if the action bar doesn't specify an icon.
+ if (!mActionBar.hasIcon() && icon != null) {
+ Drawable iconDrawable = getDrawable(icon, false);
+ if (iconDrawable != null) {
+ mActionBar.setIcon(iconDrawable);
+ }
+ }
+ }
+
+ @Override
protected void inflateMenus() {
super.inflateMenus();
// The super implementation doesn't set the menu on the view. Set it here.
@@ -340,7 +333,7 @@
@Override
int getMenuPopupMargin() {
- return -ActionBarLayout.getPixelValue("10dp", mContext.getMetrics());
+ return -FrameworkActionBar.getPixelValue("10dp", mContext.getMetrics());
}
// TODO: Use an adapter, like List View to set up tabs.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index fd976af..84ee914 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -51,11 +51,13 @@
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.SessionParamsFlags;
+import com.android.layoutlib.bridge.bars.BridgeActionBar;
+import com.android.layoutlib.bridge.bars.AppCompatActionBar;
import com.android.layoutlib.bridge.bars.Config;
import com.android.layoutlib.bridge.bars.NavigationBar;
import com.android.layoutlib.bridge.bars.StatusBar;
import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.layoutlib.bridge.bars.ActionBarLayout;
+import com.android.layoutlib.bridge.bars.FrameworkActionBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.resources.Density;
@@ -354,7 +356,7 @@
// if the theme says no title/action bar, then the size will be 0
if (mActionBarSize > 0) {
- ActionBarLayout actionBar = createActionBar(context, params, backgroundLayout);
+ BridgeActionBar actionBar = createActionBar(context, params, backgroundLayout);
actionBar.createMenuPopup();
mContentRoot = actionBar.getContentRoot();
} else if (mTitleBarSize > 0) {
@@ -1190,8 +1192,22 @@
// android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
if (mIsThemeAppCompat == null) {
StyleResourceValue defaultTheme = resources.getDefaultTheme();
- StyleResourceValue val = resources.getStyle("Theme.AppCompat", false);
- mIsThemeAppCompat = defaultTheme == val || resources.themeIsParentOf(val, defaultTheme);
+ // We can't simply check for parent using resources.themeIsParentOf() since the
+ // inheritance structure isn't really what one would expect. The first common parent
+ // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
+ boolean isThemeAppCompat = false;
+ for (int i = 0; i < 50; i++) {
+ // for loop ensures that we don't run into cyclic theme inheritance.
+ if (defaultTheme.getName().startsWith("Theme.AppCompat")) {
+ isThemeAppCompat = true;
+ break;
+ }
+ defaultTheme = resources.getParent(defaultTheme);
+ if (defaultTheme == null) {
+ break;
+ }
+ }
+ mIsThemeAppCompat = isThemeAppCompat;
}
return mIsThemeAppCompat;
}
@@ -1647,9 +1663,13 @@
/**
* Creates the action bar. Also queries the project callback for missing information.
*/
- private ActionBarLayout createActionBar(BridgeContext context, SessionParams params,
+ private BridgeActionBar createActionBar(BridgeContext context, SessionParams params,
ViewGroup parentView) {
- return new ActionBarLayout(context, params, parentView);
+ if (mIsThemeAppCompat == Boolean.TRUE) {
+ return new AppCompatActionBar(context, params, parentView);
+ } else {
+ return new FrameworkActionBar(context, params, parentView);
+ }
}
public BufferedImage getImage() {