Merge "Making the content resolver work with result intents."
diff --git a/api/current.txt b/api/current.txt
index 05a3072..a2a8661 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1243,6 +1243,8 @@
field public static final int transition = 16843743; // 0x10103df
field public static final int transitionGroup = 16843803; // 0x101041b
field public static final int transitionOrdering = 16843744; // 0x10103e0
+ field public static final int translateX = 16843869; // 0x101045d
+ field public static final int translateY = 16843870; // 0x101045e
field public static final int translationX = 16843554; // 0x1010322
field public static final int translationY = 16843555; // 0x1010323
field public static final int translationZ = 16843796; // 0x1010414
@@ -4691,6 +4693,7 @@
method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
method public android.app.Notification.WearableExtender setStartScrollBottom(boolean);
field public static final int SIZE_DEFAULT = 0; // 0x0
+ field public static final int SIZE_FULL_SCREEN = 5; // 0x5
field public static final int SIZE_LARGE = 4; // 0x4
field public static final int SIZE_MEDIUM = 3; // 0x3
field public static final int SIZE_SMALL = 2; // 0x2
@@ -10173,8 +10176,8 @@
method public boolean clipRect(float, float, float, float, android.graphics.Region.Op);
method public boolean clipRect(float, float, float, float);
method public boolean clipRect(int, int, int, int);
- method public boolean clipRegion(android.graphics.Region, android.graphics.Region.Op);
- method public boolean clipRegion(android.graphics.Region);
+ method public deprecated boolean clipRegion(android.graphics.Region, android.graphics.Region.Op);
+ method public deprecated boolean clipRegion(android.graphics.Region);
method public void concat(android.graphics.Matrix);
method public void drawARGB(int, int, int, int);
method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
@@ -12207,7 +12210,9 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_SCENE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AWB_AVAILABLE_MODES;
- field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AE;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AF;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AWB;
field public static final android.hardware.camera2.CameraCharacteristics.Key EDGE_AVAILABLE_EDGE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key FLASH_INFO_AVAILABLE;
field public static final android.hardware.camera2.CameraCharacteristics.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
@@ -12221,11 +12226,12 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_FOCUS_DISTANCE_CALIBRATION;
field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_HYPERFOCAL_DISTANCE;
field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
- field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_SHADING_MAP_SIZE;
field public static final android.hardware.camera2.CameraCharacteristics.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_AVAILABLE_CAPABILITIES;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_INPUT_STREAMS;
- field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_STREAMS;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_RAW;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PARTIAL_RESULT_COUNT;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PIPELINE_MAX_DEPTH;
field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
@@ -12445,6 +12451,7 @@
field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DNG = 5; // 0x5
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2; // 0x2
field public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4; // 0x4
field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
@@ -12538,9 +12545,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key EDGE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key FLASH_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key HOT_PIXEL_MODE;
- field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_COORDINATES;
- field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_PROCESSING_METHOD;
- field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_TIMESTAMP;
+ field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_LOCATION;
field public static final android.hardware.camera2.CaptureRequest.Key JPEG_ORIENTATION;
field public static final android.hardware.camera2.CaptureRequest.Key JPEG_QUALITY;
field public static final android.hardware.camera2.CaptureRequest.Key JPEG_THUMBNAIL_QUALITY;
@@ -12561,9 +12566,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_FACE_DETECT_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_HOT_PIXEL_MAP_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_LENS_SHADING_MAP_MODE;
- field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_BLUE;
- field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_GREEN;
- field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_RED;
+ field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE;
field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_MODE;
}
@@ -12616,9 +12619,7 @@
field public static final android.hardware.camera2.CaptureResult.Key FLASH_MODE;
field public static final android.hardware.camera2.CaptureResult.Key FLASH_STATE;
field public static final android.hardware.camera2.CaptureResult.Key HOT_PIXEL_MODE;
- field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_COORDINATES;
- field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_PROCESSING_METHOD;
- field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_TIMESTAMP;
+ field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_LOCATION;
field public static final android.hardware.camera2.CaptureResult.Key JPEG_ORIENTATION;
field public static final android.hardware.camera2.CaptureResult.Key JPEG_QUALITY;
field public static final android.hardware.camera2.CaptureResult.Key JPEG_THUMBNAIL_QUALITY;
@@ -12647,12 +12648,10 @@
field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_FACE_DETECT_MODE;
field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP;
field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP_MODE;
- field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_MAP;
+ field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_CORRECTION_MAP;
field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_MAP_MODE;
field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_SCENE_FLICKER;
- field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_BLUE;
- field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_GREEN;
- field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_RED;
+ field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE;
field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_MODE;
}
@@ -21764,10 +21763,6 @@
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
- field public static final int CRYPT_TYPE_DEFAULT = 1; // 0x1
- field public static final int CRYPT_TYPE_PASSWORD = 0; // 0x0
- field public static final int CRYPT_TYPE_PATTERN = 2; // 0x2
- field public static final int CRYPT_TYPE_PIN = 3; // 0x3
}
}
@@ -23514,6 +23509,13 @@
field public static final java.lang.String URL = "data1";
}
+ public static final class ContactsContract.ContactCounts {
+ ctor public ContactsContract.ContactCounts();
+ field public static final java.lang.String ADDRESS_BOOK_INDEX_EXTRAS = "address_book_index_extras";
+ field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "address_book_index_counts";
+ field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "address_book_index_titles";
+ }
+
protected static abstract interface ContactsContract.ContactNameColumns {
field public static final java.lang.String DISPLAY_NAME_ALTERNATIVE = "display_name_alt";
field public static final java.lang.String DISPLAY_NAME_PRIMARY = "display_name";
@@ -26443,7 +26445,7 @@
field public static final int TOUCHABLE_INSETS_CONTENT = 1; // 0x1
field public static final int TOUCHABLE_INSETS_FRAME = 0; // 0x0
field public static final int TOUCHABLE_INSETS_REGION = 3; // 0x3
- field public int contentTopInsets;
+ field public final android.graphics.Rect contentInsets;
field public int touchableInsets;
field public final android.graphics.Region touchableRegion;
}
@@ -35941,10 +35943,14 @@
public class ActionMenuView extends android.widget.LinearLayout {
ctor public ActionMenuView(android.content.Context);
ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+ method public void dismissPopupMenus();
method public android.view.Menu getMenu();
+ method public boolean hideOverflowMenu();
+ method public boolean isOverflowMenuShowing();
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDetachedFromWindow();
method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener);
+ method public boolean showOverflowMenu();
}
public static class ActionMenuView.LayoutParams extends android.widget.LinearLayout.LayoutParams {
@@ -38126,6 +38132,8 @@
ctor public Toolbar(android.content.Context, android.util.AttributeSet);
ctor public Toolbar(android.content.Context, android.util.AttributeSet, int);
ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
+ method public void collapseActionView();
+ method public void dismissPopupMenus();
method public int getContentInsetEnd();
method public int getContentInsetLeft();
method public int getContentInsetRight();
@@ -38136,7 +38144,10 @@
method public android.graphics.drawable.Drawable getNavigationIcon();
method public java.lang.CharSequence getSubtitle();
method public java.lang.CharSequence getTitle();
+ method public boolean hasExpandedActionView();
+ method public boolean hideOverflowMenu();
method public void inflateMenu(int);
+ method public boolean isOverflowMenuShowing();
method protected void onLayout(boolean, int, int, int, int);
method public void setContentInsetsAbsolute(int, int);
method public void setContentInsetsRelative(int, int);
@@ -38144,6 +38155,8 @@
method public void setLogo(android.graphics.drawable.Drawable);
method public void setLogoDescription(int);
method public void setLogoDescription(java.lang.CharSequence);
+ method public void setNavigationContentDescription(java.lang.CharSequence);
+ method public void setNavigationContentDescription(int);
method public void setNavigationDescription(int);
method public void setNavigationDescription(java.lang.CharSequence);
method public void setNavigationIcon(int);
@@ -38154,17 +38167,18 @@
method public void setSubtitle(java.lang.CharSequence);
method public void setTitle(int);
method public void setTitle(java.lang.CharSequence);
+ method public boolean showOverflowMenu();
}
- public static class Toolbar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ public static class Toolbar.LayoutParams extends android.app.ActionBar.LayoutParams {
ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet);
ctor public Toolbar.LayoutParams(int, int);
ctor public Toolbar.LayoutParams(int, int, int);
ctor public Toolbar.LayoutParams(int);
ctor public Toolbar.LayoutParams(android.widget.Toolbar.LayoutParams);
+ ctor public Toolbar.LayoutParams(android.app.ActionBar.LayoutParams);
ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams);
- field public int gravity;
}
public static abstract interface Toolbar.OnMenuItemClickListener {
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 2efe4d3..6296dd1 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -141,7 +141,7 @@
ScreenshotClient screenshot;
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
- if (display != NULL && screenshot.update(display, false) == NO_ERROR) {
+ if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) {
base = screenshot.getPixels();
w = screenshot.getWidth();
h = screenshot.getHeight();
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 3c3df01..f05f4c7 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -1291,6 +1291,7 @@
public LayoutParams(int width, int height) {
super(width, height);
+ this.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
}
public LayoutParams(int width, int height, int gravity) {
@@ -1305,6 +1306,7 @@
public LayoutParams(LayoutParams source) {
super(source);
+ this.gravity = source.gravity;
}
public LayoutParams(ViewGroup.LayoutParams source) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 07de85c..b5281ff 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4194,7 +4194,11 @@
*/
public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
int requestCode) {
- startActivityFromFragment(fragment, intent, requestCode, null);
+ Bundle options = null;
+ if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+ options = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
+ }
+ startActivityFromFragment(fragment, intent, requestCode, options);
}
/**
@@ -4219,6 +4223,9 @@
*/
public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
int requestCode, @Nullable Bundle options) {
+ if (options != null) {
+ mActivityTransitionState.startExitOutTransition(this, options);
+ }
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, fragment,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 70f270f..90aeaae 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3355,6 +3355,14 @@
*/
public static final int SIZE_LARGE = 4;
+ /**
+ * Size value for use with {@link #setCustomSizePreset} to show this notification
+ * full screen.
+ * <p>This value is only applicable for custom display notifications created using
+ * {@link #setDisplayIntent}.
+ */
+ public static final int SIZE_FULL_SCREEN = 5;
+
/** Notification extra which contains wearable extensions */
private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
@@ -3708,7 +3716,7 @@
* this notification. This action will no longer display separately from the
* notification's content.
*
- * <p>For notifications with multiple pages, child pages can also have content action's
+ * <p>For notifications with multiple pages, child pages can also have content actions
* set, although the list of available actions comes from the main notification and not
* from the child page's notification.
*
@@ -3723,16 +3731,18 @@
}
/**
- * Get the action index from this notification's actions to be clickable with the
- * content of this notification. This action will no longer display separately
+ * Get the index of the notification action, if any, that was specified as being clickable
+ * with the content of this notification. This action will no longer display separately
* from the notification's content.
*
- * <p>For notifications with multiple pages, child pages can also have content action's
+ * <p>For notifications with multiple pages, child pages can also have content actions
* set, although the list of available actions comes from the main notification and not
* from the child page's notification.
*
* <p>If wearable specific actions were added to the main notification, this index will
* apply to that list, otherwise it will apply to the regular actions list.
+ *
+ * @return the action index or {@link #UNSET_ACTION_INDEX} if no action was selected.
*/
public int getContentAction() {
return mContentActionIndex;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d3e9089..e5bf7d0 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -317,9 +317,9 @@
public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
/**
- * Sent to providers after AppWidget state related to the provider has been restored from
- * backup. The intent contains information about how to translate AppWidget ids from the
- * restored data to their new equivalents.
+ * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has
+ * been restored from backup. The intent contains information about how to translate AppWidget
+ * ids from the restored data to their new equivalents.
*
* <p>The intent will contain the following extras:
*
@@ -343,7 +343,7 @@
* <p class="note">This is a protected intent that can only be sent
* by the system.
*
- * @see {@link #ACTION_APPWIDGET_HOST_RESTORED} for the corresponding host broadcast
+ * @see #ACTION_APPWIDGET_HOST_RESTORED
*/
public static final String ACTION_APPWIDGET_RESTORED
= "android.appwidget.action.APPWIDGET_RESTORED";
@@ -352,7 +352,7 @@
* Sent to widget hosts after AppWidget state related to the host has been restored from
* backup. The intent contains information about how to translate AppWidget ids from the
* restored data to their new equivalents. If an application maintains multiple separate
- * widget hosts instances, it will receive this broadcast separately for each one.
+ * widget host instances, it will receive this broadcast separately for each one.
*
* <p>The intent will contain the following extras:
*
@@ -380,7 +380,7 @@
* <p class="note">This is a protected intent that can only be sent
* by the system.
*
- * @see {@link #ACTION_APPWIDGET_RESTORED} for the corresponding provider broadcast
+ * @see #ACTION_APPWIDGET_RESTORED
*/
public static final String ACTION_APPWIDGET_HOST_RESTORED
= "android.appwidget.action.APPWIDGET_HOST_RESTORED";
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 1574090..d898060 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -104,6 +104,12 @@
public static final int MAP = 9;
/**
+ * A2DP Sink Profile
+ * @hide
+ */
+ public static final int A2DP_SINK = 10;
+
+ /**
* Default priority for devices that we try to auto-connect to and
* and allow incoming connections for the profile
* @hide
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1c838c3..ab8bf61 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2174,7 +2174,6 @@
}
final int innerDepth = parser.getDepth();
-
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
@@ -2548,13 +2547,13 @@
com.android.internal.R.styleable.AndroidManifestActivity_singleUser,
false)) {
a.info.flags |= ActivityInfo.FLAG_SINGLE_USER;
- if (a.info.exported) {
+ if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
Slog.w(TAG, "Activity exported request ignored due to singleUser: "
+ a.className + " at " + mArchiveSourcePath + " "
+ parser.getPositionDescription());
a.info.exported = false;
+ setExported = true;
}
- setExported = true;
}
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestActivity_primaryUserOnly,
@@ -2907,7 +2906,7 @@
com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
false)) {
p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
- if (p.info.exported) {
+ if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
Slog.w(TAG, "Provider exported request ignored due to singleUser: "
+ p.className + " at " + mArchiveSourcePath + " "
+ parser.getPositionDescription());
@@ -3181,13 +3180,13 @@
com.android.internal.R.styleable.AndroidManifestService_singleUser,
false)) {
s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
- if (s.info.exported) {
+ if (s.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
Slog.w(TAG, "Service exported request ignored due to singleUser: "
+ s.className + " at " + mArchiveSourcePath + " "
+ parser.getPositionDescription());
s.info.exported = false;
+ setExported = true;
}
- setExported = true;
}
sa.recycle();
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index c08424a..cea68d2 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -296,8 +296,8 @@
* valid anti-banding modes that the application may request
* for this camera device; they must include AUTO.</p>
*/
- public static final Key<byte[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =
- new Key<byte[]>("android.control.aeAvailableAntibandingModes", byte[].class);
+ public static final Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =
+ new Key<int[]>("android.control.aeAvailableAntibandingModes", int[].class);
/**
* <p>The set of auto-exposure modes that are supported by this
@@ -315,15 +315,15 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
*/
- public static final Key<byte[]> CONTROL_AE_AVAILABLE_MODES =
- new Key<byte[]>("android.control.aeAvailableModes", byte[].class);
+ public static final Key<int[]> CONTROL_AE_AVAILABLE_MODES =
+ new Key<int[]>("android.control.aeAvailableModes", int[].class);
/**
* <p>List of frame rate ranges supported by the
* AE algorithm/hardware</p>
*/
- public static final Key<int[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =
- new Key<int[]>("android.control.aeAvailableTargetFpsRanges", int[].class);
+ public static final Key<android.util.Range<Integer>[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =
+ new Key<android.util.Range<Integer>[]>("android.control.aeAvailableTargetFpsRanges", new TypeReference<android.util.Range<Integer>[]>() {{ }});
/**
* <p>Maximum and minimum exposure compensation
@@ -332,8 +332,8 @@
*
* @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
*/
- public static final Key<int[]> CONTROL_AE_COMPENSATION_RANGE =
- new Key<int[]>("android.control.aeCompensationRange", int[].class);
+ public static final Key<android.util.Range<Integer>> CONTROL_AE_COMPENSATION_RANGE =
+ new Key<android.util.Range<Integer>>("android.control.aeCompensationRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
* <p>Smallest step by which exposure compensation
@@ -355,8 +355,8 @@
* @see CaptureRequest#CONTROL_AF_MODE
* @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
*/
- public static final Key<byte[]> CONTROL_AF_AVAILABLE_MODES =
- new Key<byte[]>("android.control.afAvailableModes", byte[].class);
+ public static final Key<int[]> CONTROL_AF_AVAILABLE_MODES =
+ new Key<int[]>("android.control.afAvailableModes", int[].class);
/**
* <p>List containing the subset of color effects
@@ -374,8 +374,8 @@
* @see CaptureRequest#CONTROL_EFFECT_MODE
* @see CaptureRequest#CONTROL_MODE
*/
- public static final Key<byte[]> CONTROL_AVAILABLE_EFFECTS =
- new Key<byte[]>("android.control.availableEffects", byte[].class);
+ public static final Key<int[]> CONTROL_AVAILABLE_EFFECTS =
+ new Key<int[]>("android.control.availableEffects", int[].class);
/**
* <p>List containing a subset of scene modes
@@ -388,15 +388,15 @@
*
* @see CaptureRequest#CONTROL_SCENE_MODE
*/
- public static final Key<byte[]> CONTROL_AVAILABLE_SCENE_MODES =
- new Key<byte[]>("android.control.availableSceneModes", byte[].class);
+ public static final Key<int[]> CONTROL_AVAILABLE_SCENE_MODES =
+ new Key<int[]>("android.control.availableSceneModes", int[].class);
/**
* <p>List of video stabilization modes that can
* be supported</p>
*/
- public static final Key<byte[]> CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =
- new Key<byte[]>("android.control.availableVideoStabilizationModes", byte[].class);
+ public static final Key<int[]> CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =
+ new Key<int[]>("android.control.availableVideoStabilizationModes", int[].class);
/**
* <p>The set of auto-white-balance modes ({@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode})
@@ -414,8 +414,8 @@
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
- public static final Key<byte[]> CONTROL_AWB_AVAILABLE_MODES =
- new Key<byte[]>("android.control.awbAvailableModes", byte[].class);
+ public static final Key<int[]> CONTROL_AWB_AVAILABLE_MODES =
+ new Key<int[]>("android.control.awbAvailableModes", int[].class);
/**
* <p>List of the maximum number of regions that can be used for metering in
@@ -427,19 +427,53 @@
* @see CaptureRequest#CONTROL_AE_REGIONS
* @see CaptureRequest#CONTROL_AF_REGIONS
* @see CaptureRequest#CONTROL_AWB_REGIONS
+ * @hide
*/
public static final Key<int[]> CONTROL_MAX_REGIONS =
new Key<int[]>("android.control.maxRegions", int[].class);
/**
+ * <p>List of the maximum number of regions that can be used for metering in
+ * auto-exposure (AE);
+ * this corresponds to the the maximum number of elements in
+ * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_REGIONS
+ */
+ public static final Key<Integer> CONTROL_MAX_REGIONS_AE =
+ new Key<Integer>("android.control.maxRegionsAe", int.class);
+
+ /**
+ * <p>List of the maximum number of regions that can be used for metering in
+ * auto-white balance (AWB);
+ * this corresponds to the the maximum number of elements in
+ * {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}.</p>
+ *
+ * @see CaptureRequest#CONTROL_AWB_REGIONS
+ */
+ public static final Key<Integer> CONTROL_MAX_REGIONS_AWB =
+ new Key<Integer>("android.control.maxRegionsAwb", int.class);
+
+ /**
+ * <p>List of the maximum number of regions that can be used for metering in
+ * auto-focus (AF);
+ * this corresponds to the the maximum number of elements in
+ * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_REGIONS
+ */
+ public static final Key<Integer> CONTROL_MAX_REGIONS_AF =
+ new Key<Integer>("android.control.maxRegionsAf", int.class);
+
+ /**
* <p>The set of edge enhancement modes supported by this camera device.</p>
* <p>This tag lists the valid modes for {@link CaptureRequest#EDGE_MODE android.edge.mode}.</p>
* <p>Full-capability camera devices must always support OFF and FAST.</p>
*
* @see CaptureRequest#EDGE_MODE
*/
- public static final Key<byte[]> EDGE_AVAILABLE_EDGE_MODES =
- new Key<byte[]>("android.edge.availableEdgeModes", byte[].class);
+ public static final Key<int[]> EDGE_AVAILABLE_EDGE_MODES =
+ new Key<int[]>("android.edge.availableEdgeModes", int[].class);
/**
* <p>Whether this camera device has a
@@ -458,8 +492,8 @@
*
* @see CaptureRequest#HOT_PIXEL_MODE
*/
- public static final Key<byte[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
- new Key<byte[]>("android.hotPixel.availableHotPixelModes", byte[].class);
+ public static final Key<int[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
+ new Key<int[]>("android.hotPixel.availableHotPixelModes", int[].class);
/**
* <p>Supported resolutions for the JPEG thumbnail</p>
@@ -526,8 +560,8 @@
*
* @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
*/
- public static final Key<byte[]> LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =
- new Key<byte[]>("android.lens.info.availableOpticalStabilization", byte[].class);
+ public static final Key<int[]> LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =
+ new Key<int[]>("android.lens.info.availableOpticalStabilization", int[].class);
/**
* <p>Optional. Hyperfocal distance for this lens.</p>
@@ -553,6 +587,7 @@
* <p>Dimensions of lens shading map.</p>
* <p>The map should be on the order of 30-40 rows and columns, and
* must be smaller than 64x64.</p>
+ * @hide
*/
public static final Key<android.util.Size> LENS_INFO_SHADING_MAP_SIZE =
new Key<android.util.Size>("android.lens.info.shadingMapSize", android.util.Size.class);
@@ -591,8 +626,8 @@
*
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
- public static final Key<byte[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =
- new Key<byte[]>("android.noiseReduction.availableNoiseReductionModes", byte[].class);
+ public static final Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =
+ new Key<int[]>("android.noiseReduction.availableNoiseReductionModes", int[].class);
/**
* <p>If set to 1, the HAL will always split result
@@ -621,7 +656,7 @@
* number is 3, and max JPEG stream number is 2, then this tuple should be <code>(1, 3, 2)</code>.</p>
* <p>This lists the upper bound of the number of output streams supported by
* the camera device. Using more streams simultaneously may require more hardware and
- * CPU resources that will consume more power. The image format for a output stream can
+ * CPU resources that will consume more power. The image format for an output stream can
* be any supported format provided by android.scaler.availableStreamConfigurations.
* The formats defined in android.scaler.availableStreamConfigurations can be catergorized
* into the 3 stream types as below:</p>
@@ -632,11 +667,79 @@
* <li>Processed (but not-stalling): any non-RAW format without a stall duration.
* Typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12.</li>
* </ul>
+ * @hide
*/
public static final Key<int[]> REQUEST_MAX_NUM_OUTPUT_STREAMS =
new Key<int[]>("android.request.maxNumOutputStreams", int[].class);
/**
+ * <p>The maximum numbers of different types of output streams
+ * that can be configured and used simultaneously by a camera device
+ * for any <code>RAW</code> formats.</p>
+ * <p>This value contains the max number of output simultaneous
+ * streams from the raw sensor.</p>
+ * <p>This lists the upper bound of the number of output streams supported by
+ * the camera device. Using more streams simultaneously may require more hardware and
+ * CPU resources that will consume more power. The image format for this kind of an output stream can
+ * be any <code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
+ * <p>In particular, a <code>RAW</code> format is typically one of:</p>
+ * <ul>
+ * <li>ImageFormat#RAW_SENSOR</li>
+ * <li>Opaque <code>RAW</code></li>
+ * </ul>
+ *
+ * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+ */
+ public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_RAW =
+ new Key<Integer>("android.request.maxNumOutputRaw", int.class);
+
+ /**
+ * <p>The maximum numbers of different types of output streams
+ * that can be configured and used simultaneously by a camera device
+ * for any processed (but not-stalling) formats.</p>
+ * <p>This value contains the max number of output simultaneous
+ * streams for any processed (but not-stalling) formats.</p>
+ * <p>This lists the upper bound of the number of output streams supported by
+ * the camera device. Using more streams simultaneously may require more hardware and
+ * CPU resources that will consume more power. The image format for this kind of an output stream can
+ * be any non-<code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
+ * <p>Processed (but not-stalling) is defined as any non-RAW format without a stall duration.
+ * Typically:</p>
+ * <ul>
+ * <li>ImageFormat#YUV_420_888</li>
+ * <li>ImageFormat#NV21</li>
+ * <li>ImageFormat#YV12</li>
+ * <li>Implementation-defined formats, i.e. StreamConfiguration#isOutputSupportedFor(Class)</li>
+ * </ul>
+ * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
+ * a processed format -- it will return 0 for a non-stalling stream.</p>
+ *
+ * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+ */
+ public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_PROC =
+ new Key<Integer>("android.request.maxNumOutputProc", int.class);
+
+ /**
+ * <p>The maximum numbers of different types of output streams
+ * that can be configured and used simultaneously by a camera device
+ * for any processed (and stalling) formats.</p>
+ * <p>This value contains the max number of output simultaneous
+ * streams for any processed (but not-stalling) formats.</p>
+ * <p>This lists the upper bound of the number of output streams supported by
+ * the camera device. Using more streams simultaneously may require more hardware and
+ * CPU resources that will consume more power. The image format for this kind of an output stream can
+ * be any non-<code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
+ * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations > 0.
+ * Typically only the <code>JPEG</code> format (ImageFormat#JPEG)</p>
+ * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
+ * a processed format -- it will return a non-0 value for a stalling stream.</p>
+ *
+ * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+ */
+ public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_PROC_STALLING =
+ new Key<Integer>("android.request.maxNumOutputProcStalling", int.class);
+
+ /**
* <p>The maximum numbers of any type of input streams
* that can be configured and used simultaneously by a camera device.</p>
* <p>When set to 0, it means no input stream is supported.</p>
@@ -707,7 +810,6 @@
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> FULL devices:</p>
* <ul>
* <li>MANUAL_SENSOR</li>
- * <li>ZSL</li>
* </ul>
* <p>Other capabilities may be available on either FULL or LIMITED
* devices, but the app. should query this field to be sure.</p>
@@ -716,7 +818,7 @@
* @see #REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
* @see #REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
- * @see #REQUEST_AVAILABLE_CAPABILITIES_GCAM
+ * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_ZSL
* @see #REQUEST_AVAILABLE_CAPABILITIES_DNG
*/
@@ -750,7 +852,7 @@
* value.</p>
* <p>The following keys may return <code>null</code> unless they are enabled:</p>
* <ul>
- * <li>{@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} (non-null iff {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON)</li>
+ * <li>android.statistics.lensShadingMap (non-null iff {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON)</li>
* </ul>
* <p>(Those sometimes-null keys should nevertheless be listed here
* if they are available.)</p>
@@ -761,7 +863,6 @@
* <p>TODO: This should be used by #getAvailableCaptureResultKeys.</p>
*
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @hide
*/
@@ -1229,8 +1330,8 @@
/**
* <p>Range of valid sensitivities</p>
*/
- public static final Key<int[]> SENSOR_INFO_SENSITIVITY_RANGE =
- new Key<int[]>("android.sensor.info.sensitivityRange", int[].class);
+ public static final Key<android.util.Range<Integer>> SENSOR_INFO_SENSITIVITY_RANGE =
+ new Key<android.util.Range<Integer>>("android.sensor.info.sensitivityRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
* <p>Arrangement of color filters on sensor;
@@ -1251,8 +1352,8 @@
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
- public static final Key<long[]> SENSOR_INFO_EXPOSURE_TIME_RANGE =
- new Key<long[]>("android.sensor.info.exposureTimeRange", long[].class);
+ public static final Key<android.util.Range<Long>> SENSOR_INFO_EXPOSURE_TIME_RANGE =
+ new Key<android.util.Range<Long>>("android.sensor.info.exposureTimeRange", new TypeReference<android.util.Range<Long>>() {{ }});
/**
* <p>Maximum possible frame duration (minimum frame
@@ -1276,8 +1377,8 @@
* array</p>
* <p>Needed for FOV calculation for old API</p>
*/
- public static final Key<float[]> SENSOR_INFO_PHYSICAL_SIZE =
- new Key<float[]>("android.sensor.info.physicalSize", float[].class);
+ public static final Key<android.util.SizeF> SENSOR_INFO_PHYSICAL_SIZE =
+ new Key<android.util.SizeF>("android.sensor.info.physicalSize", android.util.SizeF.class);
/**
* <p>Dimensions of full pixel array, possibly
@@ -1383,8 +1484,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
- public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM1 =
- new Key<Rational[]>("android.sensor.calibrationTransform1", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_CALIBRATION_TRANSFORM1 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.calibrationTransform1", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A per-device calibration transform matrix that maps from the
@@ -1404,8 +1505,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
- public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM2 =
- new Key<Rational[]>("android.sensor.calibrationTransform2", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_CALIBRATION_TRANSFORM2 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.calibrationTransform2", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A matrix that transforms color values from CIE XYZ color space to
@@ -1426,8 +1527,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
- public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM1 =
- new Key<Rational[]>("android.sensor.colorTransform1", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_COLOR_TRANSFORM1 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.colorTransform1", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A matrix that transforms color values from CIE XYZ color space to
@@ -1450,8 +1551,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
- public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM2 =
- new Key<Rational[]>("android.sensor.colorTransform2", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_COLOR_TRANSFORM2 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.colorTransform2", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A matrix that transforms white balanced camera colors from the reference
@@ -1470,8 +1571,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
- public static final Key<Rational[]> SENSOR_FORWARD_MATRIX1 =
- new Key<Rational[]>("android.sensor.forwardMatrix1", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX1 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.forwardMatrix1", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A matrix that transforms white balanced camera colors from the reference
@@ -1492,8 +1593,8 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
- public static final Key<Rational[]> SENSOR_FORWARD_MATRIX2 =
- new Key<Rational[]>("android.sensor.forwardMatrix2", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX2 =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.forwardMatrix2", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>A fixed black level offset for each of the color filter arrangement
@@ -1560,8 +1661,8 @@
* android.statistics.faceIds and
* android.statistics.faceLandmarks outputs.</p>
*/
- public static final Key<byte[]> STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =
- new Key<byte[]>("android.statistics.info.availableFaceDetectModes", byte[].class);
+ public static final Key<int[]> STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =
+ new Key<int[]>("android.statistics.info.availableFaceDetectModes", int[].class);
/**
* <p>Maximum number of simultaneously detectable
@@ -1584,19 +1685,16 @@
/**
* <p>Maximum number of supported points in the
- * tonemap curve that can be used for {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}, or
- * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, or {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.</p>
+ * tonemap curve that can be used for {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}.</p>
* <p>If the actual number of points provided by the application (in
- * android.tonemap.curve*) is less than max, the camera device will
+ * {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}*) is less than max, the camera device will
* resample the curve to its internal representation, using linear
* interpolation.</p>
* <p>The output curves in the result metadata may have a different number
* of points than the input curves, and will represent the actual
* hardware curves used as closely as possible when linearly interpolated.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_BLUE
- * @see CaptureRequest#TONEMAP_CURVE_GREEN
- * @see CaptureRequest#TONEMAP_CURVE_RED
+ * @see CaptureRequest#TONEMAP_CURVE
*/
public static final Key<Integer> TONEMAP_MAX_CURVE_POINTS =
new Key<Integer>("android.tonemap.maxCurvePoints", int.class);
@@ -1609,8 +1707,8 @@
*
* @see CaptureRequest#TONEMAP_MODE
*/
- public static final Key<byte[]> TONEMAP_AVAILABLE_TONE_MAP_MODES =
- new Key<byte[]>("android.tonemap.availableToneMapModes", byte[].class);
+ public static final Key<int[]> TONEMAP_AVAILABLE_TONE_MAP_MODES =
+ new Key<int[]>("android.tonemap.availableToneMapModes", int[].class);
/**
* <p>A list of camera LEDs that are available on this system.</p>
@@ -1626,15 +1724,16 @@
* <p>A FULL device has the most support possible and will enable the
* widest range of use cases such as:</p>
* <ul>
- * <li>30 FPS at maximum resolution (== sensor resolution)</li>
- * <li>Per frame control</li>
- * <li>Manual sensor control</li>
- * <li>Zero Shutter Lag (ZSL)</li>
+ * <li>30fps at maximum resolution (== sensor resolution) is preferred, more than 20fps is required.</li>
+ * <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li>
+ * <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR)</li>
+ * <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_POST_PROCESSING)</li>
* </ul>
* <p>A LIMITED device may have some or none of the above characteristics.
* To find out more refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
*
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ * @see CameraCharacteristics#SYNC_MAX_LATENCY
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
*/
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index accceb1..4a89fe7 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -219,6 +219,7 @@
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateListener listener, Handler handler)
throws CameraAccessException {
+ CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
try {
@@ -230,7 +231,8 @@
new android.hardware.camera2.impl.CameraDevice(
cameraId,
listener,
- handler);
+ handler,
+ characteristics);
BinderHolder holder = new BinderHolder();
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 4cde601..b3e165e 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -236,9 +236,17 @@
/**
* <p>The camera device can be manually controlled (3A algorithms such
- * as auto exposure, and auto focus can be
- * bypassed), this includes but is not limited to:</p>
+ * as auto exposure, and auto focus can be bypassed).
+ * The camera device supports basic manual control of the sensor image
+ * acquisition related stages. This means the following controls are
+ * guaranteed to be supported:</p>
* <ul>
+ * <li>Manual frame duration control<ul>
+ * <li>{@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}</li>
+ * <li>{@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li>
+ * <li>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}</li>
+ * </ul>
+ * </li>
* <li>Manual exposure control<ul>
* <li>{@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}</li>
* <li>{@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
@@ -265,10 +273,15 @@
* <p>If any of the above 3A algorithms are enabled, then the camera
* device will accurately report the values applied by 3A in the
* result.</p>
+ * <p>A given camera device may also support additional manual sensor controls,
+ * but this capability only covers the above list of controls.</p>
*
* @see CaptureRequest#BLACK_LEVEL_LOCK
+ * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
+ * @see CaptureRequest#SENSOR_FRAME_DURATION
* @see CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE
+ * @see CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION
* @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
* @see CaptureRequest#SENSOR_SENSITIVITY
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
@@ -276,12 +289,12 @@
public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2;
/**
- * <p>TODO: This should be @hide</p>
+ * <p>The camera device post-processing stages can be manually controlled.
+ * The camera device supports basic manual control of the image post-processing
+ * stages. This means the following controls are guaranteed to be supported:</p>
* <ul>
* <li>Manual tonemap control<ul>
- * <li>{@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}</li>
- * <li>{@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}</li>
- * <li>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}</li>
+ * <li>{@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}</li>
* <li>{@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}</li>
* <li>{@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</li>
* </ul>
@@ -292,8 +305,8 @@
* </ul>
* </li>
* <li>Lens shading map information<ul>
- * <li>{@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}</li>
- * <li>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}</li>
+ * <li>android.statistics.lensShadingMap</li>
+ * <li>android.lens.info.shadingMapSize</li>
* </ul>
* </li>
* </ul>
@@ -301,19 +314,17 @@
* will accurately report the values applied by AWB in the result.</p>
* <p>The camera device will also support everything in MANUAL_SENSOR
* except manual lens control and manual flash control.</p>
+ * <p>A given camera device may also support additional post-processing
+ * controls, but this capability only covers the above list of controls.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
- * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
- * @see CaptureRequest#TONEMAP_CURVE_BLUE
- * @see CaptureRequest#TONEMAP_CURVE_GREEN
- * @see CaptureRequest#TONEMAP_CURVE_RED
+ * @see CaptureRequest#TONEMAP_CURVE
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
- public static final int REQUEST_AVAILABLE_CAPABILITIES_GCAM = 3;
+ public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 3;
/**
* <p>The camera device supports the Zero Shutter Lag use case.</p>
@@ -1548,17 +1559,14 @@
/**
* <p>Use the tone mapping curve specified in
- * the android.tonemap.curve* entries.</p>
+ * the {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}* entries.</p>
* <p>All color enhancement and tonemapping must be disabled, except
* for applying the tonemapping curve specified by
- * {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}, {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}, or
- * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}.</p>
+ * {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}.</p>
* <p>Must not slow down frame rate relative to raw
* sensor output.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_BLUE
- * @see CaptureRequest#TONEMAP_CURVE_GREEN
- * @see CaptureRequest#TONEMAP_CURVE_RED
+ * @see CaptureRequest#TONEMAP_CURVE
* @see CaptureRequest#TONEMAP_MODE
*/
public static final int TONEMAP_MODE_CONTRAST_CURVE = 0;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a4aa296..6aa24e6 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -537,30 +537,24 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
- public static final Key<Rational[]> COLOR_CORRECTION_TRANSFORM =
- new Key<Rational[]>("android.colorCorrection.transform", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.colorCorrection.transform", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>Gains applying to Bayer raw color channels for
* white-balance.</p>
- * <p>The 4-channel white-balance gains are defined in
- * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
- * for green pixels on even rows of the output, and <code>G_odd</code>
- * is the gain for green pixels on the odd rows. if a HAL
- * does not support a separate gain for even/odd green channels,
- * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
- * <code>G_even</code> in the output result metadata.</p>
- * <p>This array is either set by the camera device when the request
- * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
- * directly by the application in the request when the
- * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
- * <p>The output should be the gains actually applied by the camera device to
- * the current frame.</p>
+ * <p>These per-channel gains are either set by the camera device
+ * when the request {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not
+ * TRANSFORM_MATRIX, or directly by the application in the
+ * request when the {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is
+ * TRANSFORM_MATRIX.</p>
+ * <p>The gains in the result metadata are the gains actually
+ * applied by the camera device to the current frame.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
- public static final Key<float[]> COLOR_CORRECTION_GAINS =
- new Key<float[]>("android.colorCorrection.gains", float[].class);
+ public static final Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS =
+ new Key<android.hardware.camera2.params.RggbChannelVector>("android.colorCorrection.gains", android.hardware.camera2.params.RggbChannelVector.class);
/**
* <p>The desired setting for the camera device's auto-exposure
@@ -693,9 +687,6 @@
/**
* <p>List of areas to use for
* metering.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -711,8 +702,8 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AE_REGIONS =
- new Key<int[]>("android.control.aeRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.aeRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Range over which fps can be adjusted to
@@ -722,8 +713,8 @@
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
- public static final Key<int[]> CONTROL_AE_TARGET_FPS_RANGE =
- new Key<int[]>("android.control.aeTargetFpsRange", int[].class);
+ public static final Key<android.util.Range<Integer>> CONTROL_AE_TARGET_FPS_RANGE =
+ new Key<android.util.Range<Integer>>("android.control.aeTargetFpsRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
* <p>Whether the camera device will trigger a precapture
@@ -768,26 +759,23 @@
/**
* <p>List of areas to use for focus
* estimation.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific focus area
- * needs to be used by the camera device. If the focusing region is
- * outside the the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture
- * result metadata, the camera device will ignore the sections outside
- * the region and output the used sections in the result metadata.</p>
+ * <p>If all regions have 0 weight, then no specific metering area
+ * needs to be used by the camera device. If the metering region is
+ * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
+ * the camera device will ignore the sections outside the region and output the
+ * used sections in the result metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AF_REGIONS =
- new Key<int[]>("android.control.afRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.afRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Whether the camera device will trigger autofocus for this request.</p>
@@ -854,27 +842,23 @@
/**
* <p>List of areas to use for illuminant
* estimation.</p>
- * <p>Only used in AUTO mode.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
- * needs to be used by the camera device. If the AWB region is
- * outside the the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
+ * <p>If all regions have 0 weight, then no specific metering area
+ * needs to be used by the camera device. If the metering region is
+ * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AWB_REGIONS =
- new Key<int[]>("android.control.awbRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.awbRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Information to the camera device 3A (auto-exposure,
@@ -1068,8 +1052,15 @@
new Key<Integer>("android.hotPixel.mode", int.class);
/**
+ * <p>A location object to use when generating image GPS metadata.</p>
+ */
+ public static final Key<android.location.Location> JPEG_GPS_LOCATION =
+ new Key<android.location.Location>("android.jpeg.gpsLocation", android.location.Location.class);
+
+ /**
* <p>GPS coordinates to include in output JPEG
* EXIF</p>
+ * @hide
*/
public static final Key<double[]> JPEG_GPS_COORDINATES =
new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
@@ -1077,6 +1068,7 @@
/**
* <p>32 characters describing GPS algorithm to
* include in EXIF</p>
+ * @hide
*/
public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
@@ -1084,6 +1076,7 @@
/**
* <p>Time GPS fix was made to include in
* EXIF</p>
+ * @hide
*/
public static final Key<Long> JPEG_GPS_TIMESTAMP =
new Key<Long>("android.jpeg.gpsTimestamp", long.class);
@@ -1116,6 +1109,12 @@
* but the captured JPEG will still be a valid image.</p>
* <p>When a jpeg image capture is issued, the thumbnail size selected should have
* the same aspect ratio as the jpeg image.</p>
+ * <p>If the thumbnail image aspect ratio differs from the JPEG primary image aspect
+ * ratio, the camera device creates the thumbnail by cropping it from the primary image.
+ * For example, if the primary image has 4:3 aspect ratio, the thumbnail image has
+ * 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
+ * generate the thumbnail image. The thumbnail image will always have a smaller Field
+ * Of View (FOV) than the primary image when aspect ratios differ.</p>
*/
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
@@ -1432,8 +1431,8 @@
* <p>When set to OFF mode, no lens shading correction will be applied by the
* camera device, and an identity lens shading map data will be provided
* if <code>{@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON</code>. For example, for lens
- * shading map with size specified as <code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]</code>,
- * the output {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} for this case will be an identity map
+ * shading map with size specified as <code>android.lens.info.shadingMapSize = [ 4, 3 ]</code>,
+ * the output android.statistics.lensShadingMap for this case will be an identity map
* shown below:</p>
* <pre><code>[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
* 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
@@ -1445,8 +1444,8 @@
* <p>When set to other modes, lens shading correction will be applied by the
* camera device. Applications can request lens shading map data by setting
* {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} to ON, and then the camera device will provide
- * lens shading map data in {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}, with size specified
- * by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}; the returned shading map data will be the one
+ * lens shading map data in android.statistics.lensShadingMap, with size specified
+ * by android.lens.info.shadingMapSize; the returned shading map data will be the one
* applied by the camera device for this capture request.</p>
* <p>The shading map data may depend on the AE and AWB statistics, therefore the reliability
* of the map data may be affected by the AE and AWB algorithms. When AE and AWB are in
@@ -1456,8 +1455,6 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureRequest#CONTROL_AWB_MODE
- * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @see #SHADING_MODE_OFF
* @see #SHADING_MODE_FAST
@@ -1498,10 +1495,8 @@
* <p>Whether the camera device will output the lens
* shading map in output result metadata.</p>
* <p>When set to ON,
- * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
+ * android.statistics.lensShadingMap must be provided in
* the output result metadata.</p>
- *
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
*/
@@ -1512,10 +1507,10 @@
* <p>Tonemapping / contrast / gamma curve for the blue
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
- * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+ * <p>See android.tonemap.curveRed for more details.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_BLUE =
new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -1524,10 +1519,10 @@
* <p>Tonemapping / contrast / gamma curve for the green
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
- * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+ * <p>See android.tonemap.curveRed for more details.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_GREEN =
new Key<float[]>("android.tonemap.curveGreen", float[].class);
@@ -1537,7 +1532,7 @@
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
* <p>Each channel's curve is defined by an array of control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
+ * <pre><code>android.tonemap.curveRed =
* [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
* 2 <= N <= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
* <p>These are sorted in order of increasing <code>Pin</code>; it is always
@@ -1553,15 +1548,15 @@
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
* <p>Linear mapping:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 0, 1.0, 1.0 ]
+ * <pre><code>android.tonemap.curveRed = [ 0, 0, 1.0, 1.0 ]
* </code></pre>
* <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
* <p>Invert mapping:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 1.0, 1.0, 0 ]
+ * <pre><code>android.tonemap.curveRed = [ 0, 1.0, 1.0, 0 ]
* </code></pre>
* <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
* <p>Gamma 1/2.2 mapping, with 16 control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+ * <pre><code>android.tonemap.curveRed = [
* 0.0000, 0.0000, 0.0667, 0.2920, 0.1333, 0.4002, 0.2000, 0.4812,
* 0.2667, 0.5484, 0.3333, 0.6069, 0.4000, 0.6594, 0.4667, 0.7072,
* 0.5333, 0.7515, 0.6000, 0.7928, 0.6667, 0.8317, 0.7333, 0.8685,
@@ -1569,7 +1564,7 @@
* </code></pre>
* <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
* <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+ * <pre><code>android.tonemap.curveRed = [
* 0.0000, 0.0000, 0.0667, 0.2864, 0.1333, 0.4007, 0.2000, 0.4845,
* 0.2667, 0.5532, 0.3333, 0.6125, 0.4000, 0.6652, 0.4667, 0.7130,
* 0.5333, 0.7569, 0.6000, 0.7977, 0.6667, 0.8360, 0.7333, 0.8721,
@@ -1577,14 +1572,67 @@
* </code></pre>
* <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_RED =
new Key<float[]>("android.tonemap.curveRed", float[].class);
/**
+ * <p>Tonemapping / contrast / gamma curve to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}
+ * is CONTRAST_CURVE.</p>
+ * <p>The tonemapCurve consist of three curves for each of red, green, and blue
+ * channels respectively. The following example uses the red channel as an
+ * example. The same logic applies to green and blue channel.
+ * Each channel's curve is defined by an array of control points:</p>
+ * <pre><code>curveRed =
+ * [ P0(in, out), P1(in, out), P2(in, out), P3(in, out), ..., PN(in, out) ]
+ * 2 <= N <= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+ * <p>These are sorted in order of increasing <code>Pin</code>; it is always
+ * guaranteed that input values 0.0 and 1.0 are included in the list to
+ * define a complete mapping. For input values between control points,
+ * the camera device must linearly interpolate between the control
+ * points.</p>
+ * <p>Each curve can have an independent number of points, and the number
+ * of points can be less than max (that is, the request doesn't have to
+ * always provide a curve with number of points equivalent to
+ * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
+ * <p>A few examples, and their corresponding graphical mappings; these
+ * only specify the red channel and the precision is limited to 4
+ * digits, for conciseness.</p>
+ * <p>Linear mapping:</p>
+ * <pre><code>curveRed = [ (0, 0), (1.0, 1.0) ]
+ * </code></pre>
+ * <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
+ * <p>Invert mapping:</p>
+ * <pre><code>curveRed = [ (0, 1.0), (1.0, 0) ]
+ * </code></pre>
+ * <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
+ * <p>Gamma 1/2.2 mapping, with 16 control points:</p>
+ * <pre><code>curveRed = [
+ * (0.0000, 0.0000), (0.0667, 0.2920), (0.1333, 0.4002), (0.2000, 0.4812),
+ * (0.2667, 0.5484), (0.3333, 0.6069), (0.4000, 0.6594), (0.4667, 0.7072),
+ * (0.5333, 0.7515), (0.6000, 0.7928), (0.6667, 0.8317), (0.7333, 0.8685),
+ * (0.8000, 0.9035), (0.8667, 0.9370), (0.9333, 0.9691), (1.0000, 1.0000) ]
+ * </code></pre>
+ * <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
+ * <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
+ * <pre><code>curveRed = [
+ * (0.0000, 0.0000), (0.0667, 0.2864), (0.1333, 0.4007), (0.2000, 0.4845),
+ * (0.2667, 0.5532), (0.3333, 0.6125), (0.4000, 0.6652), (0.4667, 0.7130),
+ * (0.5333, 0.7569), (0.6000, 0.7977), (0.6667, 0.8360), (0.7333, 0.8721),
+ * (0.8000, 0.9063), (0.8667, 0.9389), (0.9333, 0.9701), (1.0000, 1.0000) ]
+ * </code></pre>
+ * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+ *
+ * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
+ * @see CaptureRequest#TONEMAP_MODE
+ */
+ public static final Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE =
+ new Key<android.hardware.camera2.params.TonemapCurve>("android.tonemap.curve", android.hardware.camera2.params.TonemapCurve.class);
+
+ /**
* <p>High-level global contrast/gamma/tonemapping control.</p>
* <p>When switching to an application-defined contrast curve by setting
* {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} to CONTRAST_CURVE, the curve is defined
@@ -1600,8 +1648,7 @@
* <p>This must be set to a valid mode in
* {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}.</p>
* <p>When using either FAST or HIGH_QUALITY, the camera device will
- * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed},
- * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, and {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.
+ * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}.
* These values are always available, and as close as possible to the
* actually used nonlinear/nonglobal transforms.</p>
* <p>If a request is sent with CONTRAST_CURVE with the camera device's
@@ -1609,9 +1656,7 @@
* roughly the same.</p>
*
* @see CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES
- * @see CaptureRequest#TONEMAP_CURVE_BLUE
- * @see CaptureRequest#TONEMAP_CURVE_GREEN
- * @see CaptureRequest#TONEMAP_CURVE_RED
+ * @see CaptureRequest#TONEMAP_CURVE
* @see CaptureRequest#TONEMAP_MODE
* @see #TONEMAP_MODE_CONTRAST_CURVE
* @see #TONEMAP_MODE_FAST
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 9aa56cf..42020eb 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -383,30 +383,24 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
- public static final Key<Rational[]> COLOR_CORRECTION_TRANSFORM =
- new Key<Rational[]>("android.colorCorrection.transform", Rational[].class);
+ public static final Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM =
+ new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.colorCorrection.transform", android.hardware.camera2.params.ColorSpaceTransform.class);
/**
* <p>Gains applying to Bayer raw color channels for
* white-balance.</p>
- * <p>The 4-channel white-balance gains are defined in
- * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
- * for green pixels on even rows of the output, and <code>G_odd</code>
- * is the gain for green pixels on the odd rows. if a HAL
- * does not support a separate gain for even/odd green channels,
- * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
- * <code>G_even</code> in the output result metadata.</p>
- * <p>This array is either set by the camera device when the request
- * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
- * directly by the application in the request when the
- * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
- * <p>The output should be the gains actually applied by the camera device to
- * the current frame.</p>
+ * <p>These per-channel gains are either set by the camera device
+ * when the request {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not
+ * TRANSFORM_MATRIX, or directly by the application in the
+ * request when the {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is
+ * TRANSFORM_MATRIX.</p>
+ * <p>The gains in the result metadata are the gains actually
+ * applied by the camera device to the current frame.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
- public static final Key<float[]> COLOR_CORRECTION_GAINS =
- new Key<float[]>("android.colorCorrection.gains", float[].class);
+ public static final Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS =
+ new Key<android.hardware.camera2.params.RggbChannelVector>("android.colorCorrection.gains", android.hardware.camera2.params.RggbChannelVector.class);
/**
* <p>The desired setting for the camera device's auto-exposure
@@ -539,9 +533,6 @@
/**
* <p>List of areas to use for
* metering.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -557,8 +548,8 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AE_REGIONS =
- new Key<int[]>("android.control.aeRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.aeRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Range over which fps can be adjusted to
@@ -568,8 +559,8 @@
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
- public static final Key<int[]> CONTROL_AE_TARGET_FPS_RANGE =
- new Key<int[]>("android.control.aeTargetFpsRange", int[].class);
+ public static final Key<android.util.Range<Integer>> CONTROL_AE_TARGET_FPS_RANGE =
+ new Key<android.util.Range<Integer>>("android.control.aeTargetFpsRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
* <p>Whether the camera device will trigger a precapture
@@ -812,26 +803,23 @@
/**
* <p>List of areas to use for focus
* estimation.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific focus area
- * needs to be used by the camera device. If the focusing region is
- * outside the the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture
- * result metadata, the camera device will ignore the sections outside
- * the region and output the used sections in the result metadata.</p>
+ * <p>If all regions have 0 weight, then no specific metering area
+ * needs to be used by the camera device. If the metering region is
+ * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
+ * the camera device will ignore the sections outside the region and output the
+ * used sections in the result metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AF_REGIONS =
- new Key<int[]>("android.control.afRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.afRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Whether the camera device will trigger autofocus for this request.</p>
@@ -1295,27 +1283,23 @@
/**
* <p>List of areas to use for illuminant
* estimation.</p>
- * <p>Only used in AUTO mode.</p>
- * <p>Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight. The rectangle is defined to be inclusive of the
- * specified coordinates.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
- * needs to be used by the camera device. If the AWB region is
- * outside the the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
+ * <p>If all regions have 0 weight, then no specific metering area
+ * needs to be used by the camera device. If the metering region is
+ * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
- public static final Key<int[]> CONTROL_AWB_REGIONS =
- new Key<int[]>("android.control.awbRegions", int[].class);
+ public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
+ new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.awbRegions", android.hardware.camera2.params.MeteringRectangle[].class);
/**
* <p>Information to the camera device 3A (auto-exposure,
@@ -1656,8 +1640,15 @@
new Key<Integer>("android.hotPixel.mode", int.class);
/**
+ * <p>A location object to use when generating image GPS metadata.</p>
+ */
+ public static final Key<android.location.Location> JPEG_GPS_LOCATION =
+ new Key<android.location.Location>("android.jpeg.gpsLocation", android.location.Location.class);
+
+ /**
* <p>GPS coordinates to include in output JPEG
* EXIF</p>
+ * @hide
*/
public static final Key<double[]> JPEG_GPS_COORDINATES =
new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
@@ -1665,6 +1656,7 @@
/**
* <p>32 characters describing GPS algorithm to
* include in EXIF</p>
+ * @hide
*/
public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
@@ -1672,6 +1664,7 @@
/**
* <p>Time GPS fix was made to include in
* EXIF</p>
+ * @hide
*/
public static final Key<Long> JPEG_GPS_TIMESTAMP =
new Key<Long>("android.jpeg.gpsTimestamp", long.class);
@@ -1704,6 +1697,12 @@
* but the captured JPEG will still be a valid image.</p>
* <p>When a jpeg image capture is issued, the thumbnail size selected should have
* the same aspect ratio as the jpeg image.</p>
+ * <p>If the thumbnail image aspect ratio differs from the JPEG primary image aspect
+ * ratio, the camera device creates the thumbnail by cropping it from the primary image.
+ * For example, if the primary image has 4:3 aspect ratio, the thumbnail image has
+ * 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
+ * generate the thumbnail image. The thumbnail image will always have a smaller Field
+ * Of View (FOV) than the primary image when aspect ratios differ.</p>
*/
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
@@ -1793,8 +1792,8 @@
* <p>If variable focus not supported, can still report
* fixed depth of field range</p>
*/
- public static final Key<float[]> LENS_FOCUS_RANGE =
- new Key<float[]>("android.lens.focusRange", float[].class);
+ public static final Key<android.util.Range<Float>> LENS_FOCUS_RANGE =
+ new Key<android.util.Range<Float>>("android.lens.focusRange", new TypeReference<android.util.Range<Float>>() {{ }});
/**
* <p>Sets whether the camera device uses optical image stabilization (OIS)
@@ -2161,8 +2160,8 @@
* <p>When set to OFF mode, no lens shading correction will be applied by the
* camera device, and an identity lens shading map data will be provided
* if <code>{@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON</code>. For example, for lens
- * shading map with size specified as <code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]</code>,
- * the output {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} for this case will be an identity map
+ * shading map with size specified as <code>android.lens.info.shadingMapSize = [ 4, 3 ]</code>,
+ * the output android.statistics.lensShadingMap for this case will be an identity map
* shown below:</p>
* <pre><code>[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
* 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
@@ -2174,8 +2173,8 @@
* <p>When set to other modes, lens shading correction will be applied by the
* camera device. Applications can request lens shading map data by setting
* {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} to ON, and then the camera device will provide
- * lens shading map data in {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}, with size specified
- * by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}; the returned shading map data will be the one
+ * lens shading map data in android.statistics.lensShadingMap, with size specified
+ * by android.lens.info.shadingMapSize; the returned shading map data will be the one
* applied by the camera device for this capture request.</p>
* <p>The shading map data may depend on the AE and AWB statistics, therefore the reliability
* of the map data may be affected by the AE and AWB algorithms. When AE and AWB are in
@@ -2185,8 +2184,6 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureRequest#CONTROL_AWB_MODE
- * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @see #SHADING_MODE_OFF
* @see #SHADING_MODE_FAST
@@ -2276,13 +2273,12 @@
* The map is assumed to be bilinearly interpolated between the sample points.</p>
* <p>The channel order is [R, Geven, Godd, B], where Geven is the green
* channel for the even rows of a Bayer pattern, and Godd is the odd rows.
- * The shading map is stored in a fully interleaved format, and its size
- * is provided in the camera static metadata by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}.</p>
+ * The shading map is stored in a fully interleaved format.</p>
* <p>The shading map should have on the order of 30-40 rows and columns,
* and must be smaller than 64x64.</p>
* <p>As an example, given a very small map defined as:</p>
- * <pre><code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]
- * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} =
+ * <pre><code>width,height = [ 4, 3 ]
+ * values =
* [ 1.3, 1.2, 1.15, 1.2, 1.2, 1.2, 1.15, 1.2,
* 1.1, 1.2, 1.2, 1.2, 1.3, 1.2, 1.3, 1.3,
* 1.2, 1.2, 1.25, 1.1, 1.1, 1.1, 1.1, 1.0,
@@ -2301,8 +2297,54 @@
* <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
- * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+ */
+ public static final Key<android.hardware.camera2.params.LensShadingMap> STATISTICS_LENS_SHADING_CORRECTION_MAP =
+ new Key<android.hardware.camera2.params.LensShadingMap>("android.statistics.lensShadingCorrectionMap", android.hardware.camera2.params.LensShadingMap.class);
+
+ /**
+ * <p>The shading map is a low-resolution floating-point map
+ * that lists the coefficients used to correct for vignetting, for each
+ * Bayer color channel.</p>
+ * <p>The least shaded section of the image should have a gain factor
+ * of 1; all other sections should have gains above 1.</p>
+ * <p>When {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} = TRANSFORM_MATRIX, the map
+ * must take into account the colorCorrection settings.</p>
+ * <p>The shading map is for the entire active pixel array, and is not
+ * affected by the crop region specified in the request. Each shading map
+ * entry is the value of the shading compensation map over a specific
+ * pixel on the sensor. Specifically, with a (N x M) resolution shading
+ * map, and an active pixel array size (W x H), shading map entry
+ * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
+ * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
+ * The map is assumed to be bilinearly interpolated between the sample points.</p>
+ * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
+ * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+ * The shading map is stored in a fully interleaved format, and its size
+ * is provided in the camera static metadata by android.lens.info.shadingMapSize.</p>
+ * <p>The shading map should have on the order of 30-40 rows and columns,
+ * and must be smaller than 64x64.</p>
+ * <p>As an example, given a very small map defined as:</p>
+ * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ]
+ * android.statistics.lensShadingMap =
+ * [ 1.3, 1.2, 1.15, 1.2, 1.2, 1.2, 1.15, 1.2,
+ * 1.1, 1.2, 1.2, 1.2, 1.3, 1.2, 1.3, 1.3,
+ * 1.2, 1.2, 1.25, 1.1, 1.1, 1.1, 1.1, 1.0,
+ * 1.0, 1.0, 1.0, 1.0, 1.2, 1.3, 1.25, 1.2,
+ * 1.3, 1.2, 1.2, 1.3, 1.2, 1.15, 1.1, 1.2,
+ * 1.2, 1.1, 1.0, 1.2, 1.3, 1.15, 1.2, 1.3 ]
+ * </code></pre>
+ * <p>The low-resolution scaling map images for each channel are
+ * (displayed using nearest-neighbor interpolation):</p>
+ * <p><img alt="Red lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png" />
+ * <img alt="Green (even rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png" />
+ * <img alt="Green (odd rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png" />
+ * <img alt="Blue lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png" /></p>
+ * <p>As a visualization only, inverting the full-color map to recover an
+ * image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p>
+ * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ * @hide
*/
public static final Key<float[]> STATISTICS_LENS_SHADING_MAP =
new Key<float[]>("android.statistics.lensShadingMap", float[].class);
@@ -2402,17 +2444,15 @@
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
*/
- public static final Key<int[]> STATISTICS_HOT_PIXEL_MAP =
- new Key<int[]>("android.statistics.hotPixelMap", int[].class);
+ public static final Key<android.graphics.Point[]> STATISTICS_HOT_PIXEL_MAP =
+ new Key<android.graphics.Point[]>("android.statistics.hotPixelMap", android.graphics.Point[].class);
/**
* <p>Whether the camera device will output the lens
* shading map in output result metadata.</p>
* <p>When set to ON,
- * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
+ * android.statistics.lensShadingMap must be provided in
* the output result metadata.</p>
- *
- * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
*/
@@ -2423,10 +2463,10 @@
* <p>Tonemapping / contrast / gamma curve for the blue
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
- * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+ * <p>See android.tonemap.curveRed for more details.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_BLUE =
new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -2435,10 +2475,10 @@
* <p>Tonemapping / contrast / gamma curve for the green
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
- * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+ * <p>See android.tonemap.curveRed for more details.</p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_GREEN =
new Key<float[]>("android.tonemap.curveGreen", float[].class);
@@ -2448,7 +2488,7 @@
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
* <p>Each channel's curve is defined by an array of control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
+ * <pre><code>android.tonemap.curveRed =
* [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
* 2 <= N <= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
* <p>These are sorted in order of increasing <code>Pin</code>; it is always
@@ -2464,15 +2504,15 @@
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
* <p>Linear mapping:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 0, 1.0, 1.0 ]
+ * <pre><code>android.tonemap.curveRed = [ 0, 0, 1.0, 1.0 ]
* </code></pre>
* <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
* <p>Invert mapping:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 1.0, 1.0, 0 ]
+ * <pre><code>android.tonemap.curveRed = [ 0, 1.0, 1.0, 0 ]
* </code></pre>
* <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
* <p>Gamma 1/2.2 mapping, with 16 control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+ * <pre><code>android.tonemap.curveRed = [
* 0.0000, 0.0000, 0.0667, 0.2920, 0.1333, 0.4002, 0.2000, 0.4812,
* 0.2667, 0.5484, 0.3333, 0.6069, 0.4000, 0.6594, 0.4667, 0.7072,
* 0.5333, 0.7515, 0.6000, 0.7928, 0.6667, 0.8317, 0.7333, 0.8685,
@@ -2480,7 +2520,7 @@
* </code></pre>
* <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
* <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
- * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+ * <pre><code>android.tonemap.curveRed = [
* 0.0000, 0.0000, 0.0667, 0.2864, 0.1333, 0.4007, 0.2000, 0.4845,
* 0.2667, 0.5532, 0.3333, 0.6125, 0.4000, 0.6652, 0.4667, 0.7130,
* 0.5333, 0.7569, 0.6000, 0.7977, 0.6667, 0.8360, 0.7333, 0.8721,
@@ -2488,14 +2528,67 @@
* </code></pre>
* <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
*
- * @see CaptureRequest#TONEMAP_CURVE_RED
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
+ * @hide
*/
public static final Key<float[]> TONEMAP_CURVE_RED =
new Key<float[]>("android.tonemap.curveRed", float[].class);
/**
+ * <p>Tonemapping / contrast / gamma curve to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}
+ * is CONTRAST_CURVE.</p>
+ * <p>The tonemapCurve consist of three curves for each of red, green, and blue
+ * channels respectively. The following example uses the red channel as an
+ * example. The same logic applies to green and blue channel.
+ * Each channel's curve is defined by an array of control points:</p>
+ * <pre><code>curveRed =
+ * [ P0(in, out), P1(in, out), P2(in, out), P3(in, out), ..., PN(in, out) ]
+ * 2 <= N <= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+ * <p>These are sorted in order of increasing <code>Pin</code>; it is always
+ * guaranteed that input values 0.0 and 1.0 are included in the list to
+ * define a complete mapping. For input values between control points,
+ * the camera device must linearly interpolate between the control
+ * points.</p>
+ * <p>Each curve can have an independent number of points, and the number
+ * of points can be less than max (that is, the request doesn't have to
+ * always provide a curve with number of points equivalent to
+ * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
+ * <p>A few examples, and their corresponding graphical mappings; these
+ * only specify the red channel and the precision is limited to 4
+ * digits, for conciseness.</p>
+ * <p>Linear mapping:</p>
+ * <pre><code>curveRed = [ (0, 0), (1.0, 1.0) ]
+ * </code></pre>
+ * <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
+ * <p>Invert mapping:</p>
+ * <pre><code>curveRed = [ (0, 1.0), (1.0, 0) ]
+ * </code></pre>
+ * <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
+ * <p>Gamma 1/2.2 mapping, with 16 control points:</p>
+ * <pre><code>curveRed = [
+ * (0.0000, 0.0000), (0.0667, 0.2920), (0.1333, 0.4002), (0.2000, 0.4812),
+ * (0.2667, 0.5484), (0.3333, 0.6069), (0.4000, 0.6594), (0.4667, 0.7072),
+ * (0.5333, 0.7515), (0.6000, 0.7928), (0.6667, 0.8317), (0.7333, 0.8685),
+ * (0.8000, 0.9035), (0.8667, 0.9370), (0.9333, 0.9691), (1.0000, 1.0000) ]
+ * </code></pre>
+ * <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
+ * <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
+ * <pre><code>curveRed = [
+ * (0.0000, 0.0000), (0.0667, 0.2864), (0.1333, 0.4007), (0.2000, 0.4845),
+ * (0.2667, 0.5532), (0.3333, 0.6125), (0.4000, 0.6652), (0.4667, 0.7130),
+ * (0.5333, 0.7569), (0.6000, 0.7977), (0.6667, 0.8360), (0.7333, 0.8721),
+ * (0.8000, 0.9063), (0.8667, 0.9389), (0.9333, 0.9701), (1.0000, 1.0000) ]
+ * </code></pre>
+ * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+ *
+ * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
+ * @see CaptureRequest#TONEMAP_MODE
+ */
+ public static final Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE =
+ new Key<android.hardware.camera2.params.TonemapCurve>("android.tonemap.curve", android.hardware.camera2.params.TonemapCurve.class);
+
+ /**
* <p>High-level global contrast/gamma/tonemapping control.</p>
* <p>When switching to an application-defined contrast curve by setting
* {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} to CONTRAST_CURVE, the curve is defined
@@ -2511,8 +2604,7 @@
* <p>This must be set to a valid mode in
* {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}.</p>
* <p>When using either FAST or HIGH_QUALITY, the camera device will
- * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed},
- * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, and {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.
+ * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}.
* These values are always available, and as close as possible to the
* actually used nonlinear/nonglobal transforms.</p>
* <p>If a request is sent with CONTRAST_CURVE with the camera device's
@@ -2520,9 +2612,7 @@
* roughly the same.</p>
*
* @see CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES
- * @see CaptureRequest#TONEMAP_CURVE_BLUE
- * @see CaptureRequest#TONEMAP_CURVE_GREEN
- * @see CaptureRequest#TONEMAP_CURVE_RED
+ * @see CaptureRequest#TONEMAP_CURVE
* @see CaptureRequest#TONEMAP_MODE
* @see #TONEMAP_MODE_CONTRAST_CURVE
* @see #TONEMAP_MODE_FAST
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 7b24976..9a4c531 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -20,6 +20,8 @@
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.ICameraDeviceCallbacks;
@@ -73,6 +75,7 @@
private final SparseArray<Surface> mConfiguredOutputs = new SparseArray<Surface>();
private final String mCameraId;
+ private final CameraCharacteristics mCharacteristics;
/**
* A list tracking request and its expected last frame.
@@ -151,13 +154,15 @@
}
};
- public CameraDevice(String cameraId, StateListener listener, Handler handler) {
+ public CameraDevice(String cameraId, StateListener listener, Handler handler,
+ CameraCharacteristics characteristics) {
if (cameraId == null || listener == null || handler == null) {
throw new IllegalArgumentException("Null argument given");
}
mCameraId = cameraId;
mDeviceListener = listener;
mDeviceHandler = handler;
+ mCharacteristics = characteristics;
final int MAX_TAG_LEN = 23;
String tag = String.format("CameraDevice-JV-%s", mCameraId);
@@ -851,11 +856,18 @@
@Override
public void onResultReceived(CameraMetadataNative result,
CaptureResultExtras resultExtras) throws RemoteException {
+
int requestId = resultExtras.getRequestId();
if (DEBUG) {
Log.v(TAG, "Received result frame " + resultExtras.getFrameNumber() + " for id "
+ requestId);
}
+
+
+ // TODO: Handle CameraCharacteristics access from CaptureResult correctly.
+ result.set(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE,
+ getCharacteristics().get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE));
+
final CaptureListenerHolder holder;
synchronized (mLock) {
holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
@@ -965,4 +977,8 @@
return (mRemoteDevice == null);
}
}
+
+ private CameraCharacteristics getCharacteristics() {
+ return mCharacteristics;
+ }
}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index ab2c49a..dc0c652 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -43,13 +43,19 @@
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
import android.hardware.camera2.marshal.impl.MarshalQueryableString;
import android.hardware.camera2.params.Face;
+import android.hardware.camera2.params.LensShadingMap;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.params.TonemapCurve;
import android.hardware.camera2.utils.TypeReference;
+import android.location.Location;
+import android.location.LocationManager;
import android.os.Parcelable;
import android.os.Parcel;
import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
import com.android.internal.util.Preconditions;
@@ -57,6 +63,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* Implementation of camera metadata marshal/unmarshal across Binder to
@@ -209,6 +216,37 @@
// this should be in sync with HAL_PIXEL_FORMAT_BLOB defined in graphics.h
public static final int NATIVE_JPEG_FORMAT = 0x21;
+ private static final String CELLID_PROCESS = "CELLID";
+ private static final String GPS_PROCESS = "GPS";
+
+ private static String translateLocationProviderToProcess(final String provider) {
+ if (provider == null) {
+ return null;
+ }
+ switch(provider) {
+ case LocationManager.GPS_PROVIDER:
+ return GPS_PROCESS;
+ case LocationManager.NETWORK_PROVIDER:
+ return CELLID_PROCESS;
+ default:
+ return null;
+ }
+ }
+
+ private static String translateProcessToLocationProvider(final String process) {
+ if (process == null) {
+ return null;
+ }
+ switch(process) {
+ case GPS_PROCESS:
+ return LocationManager.GPS_PROVIDER;
+ case CELLID_PROCESS:
+ return LocationManager.NETWORK_PROVIDER;
+ default:
+ return null;
+ }
+ }
+
public CameraMetadataNative() {
super();
mMetadataPtr = nativeAllocate();
@@ -297,9 +335,9 @@
public <T> T get(Key<T> key) {
Preconditions.checkNotNull(key, "key must not be null");
- T value = getOverride(key);
- if (value != null) {
- return value;
+ Pair<T, Boolean> override = getOverride(key);
+ if (override.second) {
+ return override.first;
}
return getBase(key);
@@ -409,23 +447,44 @@
ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
return marshaler.unmarshal(buffer);
}
-
// Need overwrite some metadata that has different definitions between native
// and managed sides.
@SuppressWarnings("unchecked")
- private <T> T getOverride(Key<T> key) {
+ private <T> Pair<T, Boolean> getOverride(Key<T> key) {
+ T value = null;
+ boolean override = true;
+
if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_FORMATS)) {
- return (T) getAvailableFormats();
+ value = (T) getAvailableFormats();
} else if (key.equals(CaptureResult.STATISTICS_FACES)) {
- return (T) getFaces();
+ value = (T) getFaces();
} else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
- return (T) getFaceRectangles();
+ value = (T) getFaceRectangles();
} else if (key.equals(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)) {
- return (T) getStreamConfigurationMap();
+ value = (T) getStreamConfigurationMap();
+ } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AE)) {
+ value = (T) getMaxRegions(key);
+ } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB)) {
+ value = (T) getMaxRegions(key);
+ } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AF)) {
+ value = (T) getMaxRegions(key);
+ } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW)) {
+ value = (T) getMaxNumOutputs(key);
+ } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC)) {
+ value = (T) getMaxNumOutputs(key);
+ } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING)) {
+ value = (T) getMaxNumOutputs(key);
+ } else if (key.equals(CaptureRequest.TONEMAP_CURVE)) {
+ value = (T) getTonemapCurve();
+ } else if (key.equals(CaptureResult.JPEG_GPS_LOCATION)) {
+ value = (T) getGpsLocation();
+ } else if (key.equals(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP)) {
+ value = (T) getLensShadingMap();
+ } else {
+ override = false;
}
- // For other keys, get() falls back to getBase()
- return null;
+ return Pair.create(value, override);
}
private int[] getAvailableFormats() {
@@ -541,6 +600,62 @@
return fixedFaceRectangles;
}
+ private LensShadingMap getLensShadingMap() {
+ float[] lsmArray = getBase(CaptureResult.STATISTICS_LENS_SHADING_MAP);
+ if (lsmArray == null) {
+ Log.w(TAG, "getLensShadingMap - Lens shading map was null.");
+ return null;
+ }
+ Size s = get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE);
+ LensShadingMap map = new LensShadingMap(lsmArray, s.getHeight(), s.getWidth());
+ return map;
+ }
+
+ private Location getGpsLocation() {
+ String processingMethod = get(CaptureResult.JPEG_GPS_PROCESSING_METHOD);
+ Location l = new Location(translateProcessToLocationProvider(processingMethod));
+
+ double[] coords = get(CaptureResult.JPEG_GPS_COORDINATES);
+ Long timeStamp = get(CaptureResult.JPEG_GPS_TIMESTAMP);
+
+ if (timeStamp != null) {
+ l.setTime(timeStamp);
+ } else {
+ Log.w(TAG, "getGpsLocation - No timestamp for GPS location.");
+ }
+
+ if (coords != null) {
+ l.setLatitude(coords[0]);
+ l.setLongitude(coords[1]);
+ l.setAltitude(coords[2]);
+ } else {
+ Log.w(TAG, "getGpsLocation - No coordinates for GPS location");
+ }
+
+ return l;
+ }
+
+ private boolean setGpsLocation(Location l) {
+ if (l == null) {
+ return false;
+ }
+
+ double[] coords = { l.getLatitude(), l.getLongitude(), l.getAltitude() };
+ String processMethod = translateLocationProviderToProcess(l.getProvider());
+ long timestamp = l.getTime();
+
+ set(CaptureRequest.JPEG_GPS_TIMESTAMP, timestamp);
+ set(CaptureRequest.JPEG_GPS_COORDINATES, coords);
+
+ if (processMethod == null) {
+ Log.w(TAG, "setGpsLocation - No process method, Location is not from a GPS or NETWORK" +
+ "provider");
+ } else {
+ setBase(CaptureRequest.JPEG_GPS_PROCESSING_METHOD, processMethod);
+ }
+ return true;
+ }
+
private StreamConfigurationMap getStreamConfigurationMap() {
StreamConfiguration[] configurations = getBase(
CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
@@ -552,6 +667,63 @@
return new StreamConfigurationMap(configurations, minFrameDurations, stallDurations);
}
+ private <T> Integer getMaxRegions(Key<T> key) {
+ final int AE = 0;
+ final int AWB = 1;
+ final int AF = 2;
+
+ // The order of the elements is: (AE, AWB, AF)
+ int[] maxRegions = getBase(CameraCharacteristics.CONTROL_MAX_REGIONS);
+
+ if (maxRegions == null) {
+ return null;
+ }
+
+ if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AE)) {
+ return maxRegions[AE];
+ } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB)) {
+ return maxRegions[AWB];
+ } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AF)) {
+ return maxRegions[AF];
+ } else {
+ throw new AssertionError("Invalid key " + key);
+ }
+ }
+
+ private <T> Integer getMaxNumOutputs(Key<T> key) {
+ final int RAW = 0;
+ final int PROC = 1;
+ final int PROC_STALLING = 2;
+
+ // The order of the elements is: (raw, proc+nonstalling, proc+stalling)
+ int[] maxNumOutputs = getBase(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS);
+
+ if (maxNumOutputs == null) {
+ return null;
+ }
+
+ if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW)) {
+ return maxNumOutputs[RAW];
+ } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC)) {
+ return maxNumOutputs[PROC];
+ } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING)) {
+ return maxNumOutputs[PROC_STALLING];
+ } else {
+ throw new AssertionError("Invalid key " + key);
+ }
+ }
+
+ private <T> TonemapCurve getTonemapCurve() {
+ float[] red = getBase(CaptureRequest.TONEMAP_CURVE_RED);
+ float[] green = getBase(CaptureRequest.TONEMAP_CURVE_GREEN);
+ float[] blue = getBase(CaptureRequest.TONEMAP_CURVE_BLUE);
+ if (red == null || green == null || blue == null) {
+ return null;
+ }
+ TonemapCurve tc = new TonemapCurve(red, green, blue);
+ return tc;
+ }
+
private <T> void setBase(CameraCharacteristics.Key<T> key, T value) {
setBase(key.getNativeKey(), value);
}
@@ -591,8 +763,11 @@
return setAvailableFormats((int[]) value);
} else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
return setFaceRectangles((Rect[]) value);
+ } else if (key.equals(CaptureRequest.TONEMAP_CURVE)) {
+ return setTonemapCurve((TonemapCurve) value);
+ } else if (key.equals(CaptureResult.JPEG_GPS_LOCATION)) {
+ return setGpsLocation((Location) value);
}
-
// For other keys, set() falls back to setBase().
return false;
}
@@ -646,6 +821,24 @@
return true;
}
+ private <T> boolean setTonemapCurve(TonemapCurve tc) {
+ if (tc == null) {
+ return false;
+ }
+
+ float[][] curve = new float[3][];
+ for (int i = TonemapCurve.CHANNEL_RED; i <= TonemapCurve.CHANNEL_BLUE; i++) {
+ int pointCount = tc.getPointCount(i);
+ curve[i] = new float[pointCount * TonemapCurve.POINT_SIZE];
+ tc.copyColorCurve(i, curve[i], 0);
+ }
+ setBase(CaptureRequest.TONEMAP_CURVE_RED, curve[0]);
+ setBase(CaptureRequest.TONEMAP_CURVE_GREEN, curve[1]);
+ setBase(CaptureRequest.TONEMAP_CURVE_BLUE, curve[2]);
+
+ return true;
+ }
+
private long mMetadataPtr; // native CameraMetadata*
private native long nativeAllocate();
diff --git a/core/java/android/hardware/camera2/params/ColorSpaceTransform.java b/core/java/android/hardware/camera2/params/ColorSpaceTransform.java
index fa8c8ea..b4289db2 100644
--- a/core/java/android/hardware/camera2/params/ColorSpaceTransform.java
+++ b/core/java/android/hardware/camera2/params/ColorSpaceTransform.java
@@ -139,8 +139,8 @@
throw new IllegalArgumentException("row out of range");
}
- int numerator = mElements[row * ROWS * RATIONAL_SIZE + column + OFFSET_NUMERATOR];
- int denominator = mElements[row * ROWS * RATIONAL_SIZE + column + OFFSET_DENOMINATOR];
+ int numerator = mElements[(row * COLUMNS + column) * RATIONAL_SIZE + OFFSET_NUMERATOR];
+ int denominator = mElements[(row * COLUMNS + column) * RATIONAL_SIZE + OFFSET_DENOMINATOR];
return new Rational(numerator, denominator);
}
@@ -162,7 +162,7 @@
public void copyElements(Rational[] destination, int offset) {
checkArgumentNonnegative(offset, "offset must not be negative");
checkNotNull(destination, "destination must not be null");
- if (destination.length + offset < COUNT) {
+ if (destination.length - offset < COUNT) {
throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
}
@@ -197,7 +197,7 @@
public void copyElements(int[] destination, int offset) {
checkArgumentNonnegative(offset, "offset must not be negative");
checkNotNull(destination, "destination must not be null");
- if (destination.length + offset < COUNT_INT) {
+ if (destination.length - offset < COUNT_INT) {
throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
}
diff --git a/core/java/android/hardware/camera2/params/LensShadingMap.java b/core/java/android/hardware/camera2/params/LensShadingMap.java
index b328f578..9bbc33a 100644
--- a/core/java/android/hardware/camera2/params/LensShadingMap.java
+++ b/core/java/android/hardware/camera2/params/LensShadingMap.java
@@ -28,7 +28,7 @@
/**
* Immutable class for describing a {@code 4 x N x M} lens shading map of floats.
*
- * @see CameraCharacteristics#LENS_SHADING_MAP
+ * @see CaptureResult#STATISTICS_LENS_SHADING_CORRECTION_MAP
*/
public final class LensShadingMap {
@@ -62,12 +62,12 @@
public LensShadingMap(final float[] elements, final int rows, final int columns) {
mRows = checkArgumentPositive(rows, "rows must be positive");
- mColumns = checkArgumentPositive(rows, "columns must be positive");
+ mColumns = checkArgumentPositive(columns, "columns must be positive");
mElements = checkNotNull(elements, "elements must not be null");
if (elements.length != getGainFactorCount()) {
throw new IllegalArgumentException("elements must be " + getGainFactorCount() +
- " length");
+ " length, received " + elements.length);
}
// Every element must be finite and >= 1.0f
@@ -242,4 +242,4 @@
private final int mRows;
private final int mColumns;
private final float[] mElements;
-};
+}
diff --git a/core/java/android/hardware/camera2/params/MeteringRectangle.java b/core/java/android/hardware/camera2/params/MeteringRectangle.java
index a26c57d..a7a3b59 100644
--- a/core/java/android/hardware/camera2/params/MeteringRectangle.java
+++ b/core/java/android/hardware/camera2/params/MeteringRectangle.java
@@ -57,7 +57,7 @@
* @param height height >= 0
* @param meteringWeight weight >= 0
*
- * @throws IllegalArgumentException if any of the parameters were non-negative
+ * @throws IllegalArgumentException if any of the parameters were negative
*/
public MeteringRectangle(int x, int y, int width, int height, int meteringWeight) {
mX = checkArgumentNonnegative(x, "x must be nonnegative");
@@ -74,7 +74,7 @@
* @param dimensions a non-{@code null} {@link android.util.Size Size} with width, height >= 0
* @param meteringWeight weight >= 0
*
- * @throws IllegalArgumentException if any of the parameters were non-negative
+ * @throws IllegalArgumentException if any of the parameters were negative
* @throws NullPointerException if any of the arguments were null
*/
public MeteringRectangle(Point xy, Size dimensions, int meteringWeight) {
@@ -94,7 +94,7 @@
* @param rect a non-{@code null} rectangle with all x,y,w,h dimensions >= 0
* @param meteringWeight weight >= 0
*
- * @throws IllegalArgumentException if any of the parameters were non-negative
+ * @throws IllegalArgumentException if any of the parameters were negative
* @throws NullPointerException if any of the arguments were null
*/
public MeteringRectangle(Rect rect, int meteringWeight) {
@@ -210,7 +210,7 @@
&& mY == other.mY
&& mWidth == other.mWidth
&& mHeight == other.mHeight
- && mWidth == other.mWidth);
+ && mWeight == other.mWeight);
}
/**
diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
index 83da29a..f0bd237 100644
--- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
+++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
@@ -90,7 +90,7 @@
public void queryDisplayStatus(DisplayStatusCallback callback) {
// TODO: PendingResult.
try {
- mService.oneTouchPlay(getCallbackWrapper(callback));
+ mService.queryDisplayStatus(getCallbackWrapper(callback));
} catch (RemoteException e) {
Log.e(TAG, "queryDisplayStatus threw exception ", e);
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4bccaf1..3417de1 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -39,6 +39,7 @@
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
+import android.view.Gravity;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -679,7 +680,7 @@
mInflater = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
- false);
+ WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false);
if (mHardwareAccelerated) {
mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index a9bace1..38a65c5 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -37,6 +37,8 @@
final Callback mCallback;
final KeyEvent.Callback mKeyEventCallback;
final KeyEvent.DispatcherState mDispatcherState;
+ final int mWindowType;
+ final int mGravity;
final boolean mTakesFocus;
private final Rect mBounds = new Rect();
@@ -64,12 +66,14 @@
*/
public SoftInputWindow(Context context, String name, int theme, Callback callback,
KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState,
- boolean takesFocus) {
+ int windowType, int gravity, boolean takesFocus) {
super(context, theme);
mName = name;
mCallback = callback;
mKeyEventCallback = keyEventCallback;
mDispatcherState = dispatcherState;
+ mWindowType = windowType;
+ mGravity = gravity;
mTakesFocus = takesFocus;
initDockWindow();
}
@@ -97,47 +101,6 @@
}
/**
- * Get the size of the DockWindow.
- *
- * @return If the DockWindow sticks to the top or bottom of the screen, the
- * return value is the height of the DockWindow, and its width is
- * equal to the width of the screen; If the DockWindow sticks to the
- * left or right of the screen, the return value is the width of the
- * DockWindow, and its height is equal to the height of the screen.
- */
- public int getSize() {
- WindowManager.LayoutParams lp = getWindow().getAttributes();
-
- if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
- return lp.height;
- } else {
- return lp.width;
- }
- }
-
- /**
- * Set the size of the DockWindow.
- *
- * @param size If the DockWindow sticks to the top or bottom of the screen,
- * <var>size</var> is the height of the DockWindow, and its width is
- * equal to the width of the screen; If the DockWindow sticks to the
- * left or right of the screen, <var>size</var> is the width of the
- * DockWindow, and its height is equal to the height of the screen.
- */
- public void setSize(int size) {
- WindowManager.LayoutParams lp = getWindow().getAttributes();
-
- if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
- lp.width = -1;
- lp.height = size;
- } else {
- lp.width = size;
- lp.height = -1;
- }
- getWindow().setAttributes(lp);
- }
-
- /**
* Set which boundary of the screen the DockWindow sticks to.
*
* @param gravity The boundary of the screen to stick. See {#link
@@ -147,18 +110,18 @@
*/
public void setGravity(int gravity) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
-
- boolean oldIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM);
-
lp.gravity = gravity;
+ updateWidthHeight(lp);
+ getWindow().setAttributes(lp);
+ }
- boolean newIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM);
-
- if (oldIsVertical != newIsVertical) {
- int tmp = lp.width;
- lp.width = lp.height;
- lp.height = tmp;
- getWindow().setAttributes(lp);
+ private void updateWidthHeight(WindowManager.LayoutParams lp) {
+ if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
+ lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+ lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ } else {
+ lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ lp.height = WindowManager.LayoutParams.MATCH_PARENT;
}
}
@@ -201,14 +164,11 @@
private void initDockWindow() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
- lp.type = WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+ lp.type = mWindowType;
lp.setTitle(mName);
- lp.gravity = Gravity.BOTTOM;
- lp.width = -1;
- // Let the input method window's orientation follow sensor based rotation
- // Turn this off for now, it is very problematic.
- //lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
+ lp.gravity = mGravity;
+ updateWidthHeight(lp);
getWindow().setAttributes(lp);
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index e489e05..64516e6 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -94,11 +94,26 @@
mNetId = netId;
}
+ private void connectToHost(Socket socket, String host, int port) throws IOException {
+ // Lookup addresses only on this Network.
+ InetAddress[] hostAddresses = getAllByName(host);
+ // Try all but last address ignoring exceptions.
+ for (int i = 0; i < hostAddresses.length - 1; i++) {
+ try {
+ socket.connect(new InetSocketAddress(hostAddresses[i], port));
+ return;
+ } catch (IOException e) {
+ }
+ }
+ // Try last address. Do throw exceptions.
+ socket.connect(new InetSocketAddress(hostAddresses[hostAddresses.length - 1], port));
+ }
+
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
Socket socket = createSocket();
socket.bind(new InetSocketAddress(localHost, localPort));
- socket.connect(new InetSocketAddress(host, port));
+ connectToHost(socket, host, port);
return socket;
}
@@ -121,7 +136,7 @@
@Override
public Socket createSocket(String host, int port) throws IOException {
Socket socket = createSocket();
- socket.connect(new InetSocketAddress(host, port));
+ connectToHost(socket, host, port);
return socket;
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 57ed979..474192fd 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -70,6 +70,8 @@
public static final long TRACE_TAG_DALVIK = 1L << 14;
/** @hide */
public static final long TRACE_TAG_RS = 1L << 15;
+ /** @hide */
+ public static final long TRACE_TAG_BIONIC = 1L << 16;
private static final long TRACE_TAG_NOT_READY = 1L << 63;
private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 4963991..68b91cb 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -58,24 +58,6 @@
* argument of {@link android.content.Context#STORAGE_SERVICE}.
*/
public class StorageManager {
-
- /// Consts to match the password types in cryptfs.h
- /** Master key is encrypted with a password.
- */
- public static final int CRYPT_TYPE_PASSWORD = 0;
-
- /** Master key is encrypted with the default password.
- */
- public static final int CRYPT_TYPE_DEFAULT = 1;
-
- /** Master key is encrypted with a pattern.
- */
- public static final int CRYPT_TYPE_PATTERN = 2;
-
- /** Master key is encrypted with a pin.
- */
- public static final int CRYPT_TYPE_PIN = 3;
-
private static final String TAG = "StorageManager";
private final ContentResolver mResolver;
@@ -663,4 +645,14 @@
return Settings.Global.getLong(mResolver, Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
DEFAULT_FULL_THRESHOLD_BYTES);
}
+
+ /// Consts to match the password types in cryptfs.h
+ /** @hide */
+ public static final int CRYPT_TYPE_PASSWORD = 0;
+ /** @hide */
+ public static final int CRYPT_TYPE_DEFAULT = 1;
+ /** @hide */
+ public static final int CRYPT_TYPE_PATTERN = 2;
+ /** @hide */
+ public static final int CRYPT_TYPE_PIN = 3;
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b53ea81..6db78f4 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1152,8 +1152,6 @@
* address book index, which is usually the first letter of the sort key.
* When this parameter is supplied, the row counts are returned in the
* cursor extras bundle.
- *
- * @hide
*/
public final static class ContactCounts {
@@ -1163,7 +1161,24 @@
* first letter of the sort key. This parameter does not affect the main
* content of the cursor.
*
- * @hide
+ * <p>
+ * <pre>
+ * Example:
+ * Uri uri = Contacts.CONTENT_URI.buildUpon()
+ * .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true")
+ * .build();
+ * Cursor cursor = getContentResolver().query(uri,
+ * new String[] {Contacts.DISPLAY_NAME},
+ * null, null, null);
+ * Bundle bundle = cursor.getExtras();
+ * if (bundle.containsKey(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES) &&
+ * bundle.containsKey(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) {
+ * String sections[] =
+ * bundle.getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
+ * int counts[] = bundle.getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
+ * }
+ * </pre>
+ * </p>
*/
public static final String ADDRESS_BOOK_INDEX_EXTRAS = "address_book_index_extras";
@@ -1171,8 +1186,6 @@
* The array of address book index titles, which are returned in the
* same order as the data in the cursor.
* <p>TYPE: String[]</p>
- *
- * @hide
*/
public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "address_book_index_titles";
@@ -1180,8 +1193,6 @@
* The array of group counts for the corresponding group. Contains the same number
* of elements as the EXTRA_ADDRESS_BOOK_INDEX_TITLES array.
* <p>TYPE: int[]</p>
- *
- * @hide
*/
public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "address_book_index_counts";
}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index a83544d..cd357b7 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Rect;
import android.graphics.Region;
import android.inputmethodservice.SoftInputWindow;
import android.os.Binder;
@@ -32,6 +33,7 @@
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -262,14 +264,14 @@
*/
public static final class Insets {
/**
- * This is the top part of the UI that is the main content. It is
+ * This is the part of the UI that is the main content. It is
* used to determine the basic space needed, to resize/pan the
* application behind. It is assumed that this inset does not
* change very much, since any change will cause a full resize/pan
* of the application behind. This value is relative to the top edge
* of the input method window.
*/
- public int contentTopInsets;
+ public final Rect contentInsets = new Rect();
/**
* This is the region of the UI that is touchable. It is used when
@@ -311,7 +313,8 @@
new ViewTreeObserver.OnComputeInternalInsetsListener() {
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
onComputeInsets(mTmpInsets);
- info.contentInsets.top = info.visibleInsets.top = mTmpInsets.contentTopInsets;
+ info.contentInsets.set(mTmpInsets.contentInsets);
+ info.visibleInsets.set(mTmpInsets.contentInsets);
info.touchableRegion.set(mTmpInsets.touchableRegion);
info.setTouchableInsets(mTmpInsets.touchableInsets);
}
@@ -428,6 +431,8 @@
throw new IllegalStateException("Can't call before onCreate()");
}
try {
+ intent.migrateExtraStreamToClipData();
+ intent.prepareToLeaveProcess();
int res = mSystemService.startVoiceActivity(mToken, intent,
intent.resolveType(mContext.getContentResolver()));
Instrumentation.checkStartActivityResult(res, intent);
@@ -460,7 +465,8 @@
mInflater = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
- mCallbacks, this, mDispatcherState, true);
+ mCallbacks, this, mDispatcherState,
+ WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.TOP, true);
mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
initViews();
mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
@@ -517,7 +523,10 @@
int[] loc = mTmpLocation;
View decor = getWindow().getWindow().getDecorView();
decor.getLocationInWindow(loc);
- outInsets.contentTopInsets = loc[1];
+ outInsets.contentInsets.top = 0;
+ outInsets.contentInsets.left = 0;
+ outInsets.contentInsets.right = 0;
+ outInsets.contentInsets.bottom = 0;
outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
outInsets.touchableRegion.setEmpty();
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 7d13399..af16185 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -79,7 +79,7 @@
void removeWindowToken(IBinder token);
void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
- int configChanges);
+ int configChanges, boolean voiceInteraction);
void setAppGroupId(IBinder token, int groupId);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
int getAppOrientation(IApplicationToken token);
@@ -120,6 +120,7 @@
boolean isKeyguardSecure();
boolean inKeyguardRestrictedInputMode();
void dismissKeyguard();
+ void keyguardGoingAway();
void closeSystemDialogs(String reason);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index c15ce44..5cd3d62 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -38,11 +38,11 @@
private static native void nativeDestroy(long nativeObject);
private static native Bitmap nativeScreenshot(IBinder displayToken,
- int width, int height, int minLayer, int maxLayer, boolean allLayers,
- boolean useIdentityTransform);
+ Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
+ boolean allLayers, boolean useIdentityTransform);
private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
- int width, int height, int minLayer, int maxLayer, boolean allLayers,
- boolean useIdentityTransform);
+ Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
+ boolean allLayers, boolean useIdentityTransform);
private static native void nativeOpenTransaction();
private static native void nativeCloseTransaction();
@@ -597,8 +597,8 @@
public static void screenshot(IBinder display, Surface consumer,
int width, int height, int minLayer, int maxLayer,
boolean useIdentityTransform) {
- screenshot(display, consumer, width, height, minLayer, maxLayer, false,
- useIdentityTransform);
+ screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
+ false, useIdentityTransform);
}
/**
@@ -613,7 +613,7 @@
*/
public static void screenshot(IBinder display, Surface consumer,
int width, int height) {
- screenshot(display, consumer, width, height, 0, 0, true, false);
+ screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
}
/**
@@ -623,7 +623,7 @@
* @param consumer The {@link Surface} to take the screenshot into.
*/
public static void screenshot(IBinder display, Surface consumer) {
- screenshot(display, consumer, 0, 0, 0, 0, true, false);
+ screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
}
/**
@@ -634,6 +634,8 @@
* the versions that use a {@link Surface} instead, such as
* {@link SurfaceControl#screenshot(IBinder, Surface)}.
*
+ * @param sourceCrop The portion of the screen to capture into the Bitmap;
+ * caller may pass in 'new Rect()' if no cropping is desired.
* @param width The desired width of the returned bitmap; the raw
* screen will be scaled down to this size.
* @param height The desired height of the returned bitmap; the raw
@@ -649,13 +651,13 @@
* if an error occurs. Make sure to call Bitmap.recycle() as soon as
* possible, once its content is not needed anymore.
*/
- public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer,
- boolean useIdentityTransform) {
+ public static Bitmap screenshot(Rect sourceCrop, int width, int height,
+ int minLayer, int maxLayer, boolean useIdentityTransform) {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false,
- useIdentityTransform);
+ return nativeScreenshot(displayToken, sourceCrop, width, height,
+ minLayer, maxLayer, false, useIdentityTransform);
}
/**
@@ -674,10 +676,10 @@
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, 0, 0, true, false);
+ return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false);
}
- private static void screenshot(IBinder display, Surface consumer,
+ private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
int width, int height, int minLayer, int maxLayer, boolean allLayers,
boolean useIdentityTransform) {
if (display == null) {
@@ -686,7 +688,7 @@
if (consumer == null) {
throw new IllegalArgumentException("consumer must not be null");
}
- nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers,
- useIdentityTransform);
+ nativeScreenshot(display, consumer, sourceCrop, width, height,
+ minLayer, maxLayer, allLayers, useIdentityTransform);
}
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 8417887..9c9a939 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -33,8 +33,6 @@
/**
* Hardware renderer that proxies the rendering to a render thread. Most calls
* are currently synchronous.
- * TODO: Make draw() async.
- * TODO: Figure out how to share the DisplayList between two threads (global lock?)
*
* The UI thread can block on the RenderThread, but RenderThread must never
* block on the UI thread.
@@ -117,7 +115,7 @@
@Override
void destroyHardwareResources(View view) {
destroyResources(view);
- // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+ nFlushCaches(mNativeProxy, GLES20Canvas.FLUSH_CACHES_LAYERS);
}
private static void destroyResources(View view) {
@@ -368,6 +366,8 @@
private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
private static native void nDestroyLayer(long nativeProxy, long layer);
+ private static native void nFlushCaches(long nativeProxy, int flushMode);
+
private static native void nFence(long nativeProxy);
private static native void nNotifyFramePending(long nativeProxy);
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b821a3e..0f40ee7 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -456,6 +456,10 @@
// views during a transition when they otherwise would have become gone/invisible
private ArrayList<View> mVisibilityChangingChildren;
+ // Temporary holder of presorted children, only used for
+ // input/software draw dispatch for correctly Z ordering.
+ private ArrayList<View> mPreSortedChildren;
+
// Indicates how many of this container's child subtrees contain transient state
@ViewDebug.ExportedProperty(category = "layout")
private int mChildCountWithTransientState = 0;
@@ -1499,13 +1503,15 @@
final float y = event.getY();
final int childrenCount = mChildrenCount;
if (childrenCount != 0) {
- final boolean customChildOrder = isChildrenDrawingOrderEnabled();
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
HoverTarget lastHoverTarget = null;
for (int i = childrenCount - 1; i >= 0; i--) {
- final int childIndex = customChildOrder
- ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = children[childIndex];
+ int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? children[childIndex] : preorderedList.get(childIndex);
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -1572,6 +1578,7 @@
break;
}
}
+ if (preorderedList != null) preorderedList.clear();
}
}
@@ -1778,23 +1785,28 @@
// Send the event to the child under the pointer.
final int childrenCount = mChildrenCount;
if (childrenCount != 0) {
- final View[] children = mChildren;
final float x = event.getX();
final float y = event.getY();
- final boolean customOrder = isChildrenDrawingOrderEnabled();
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
+ final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
- final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = children[childIndex];
+ int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? children[childIndex] : preorderedList.get(childIndex);
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
}
if (dispatchTransformedGenericPointerEvent(event, child)) {
+ if (preorderedList != null) preorderedList.clear();
return true;
}
}
+ if (preorderedList != null) preorderedList.clear();
}
// No child handled the event. Send it to this view group.
@@ -1910,13 +1922,15 @@
final float y = ev.getY(actionIndex);
// Find a child that can receive the event.
// Scan children from front to back.
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
-
- final boolean customOrder = isChildrenDrawingOrderEnabled();
for (int i = childrenCount - 1; i >= 0; i--) {
- final int childIndex = customOrder ?
- getChildDrawingOrder(childrenCount, i) : i;
- final View child = children[childIndex];
+ final int childIndex = customOrder
+ ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? children[childIndex] : preorderedList.get(childIndex);
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -1934,7 +1948,17 @@
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// Child wants to receive touch within its bounds.
mLastTouchDownTime = ev.getDownTime();
- mLastTouchDownIndex = childIndex;
+ if (preorderedList != null) {
+ // childIndex points into presorted list, find original index
+ for (int j = 0; j < childrenCount; j++) {
+ if (children[childIndex] == mChildren[j]) {
+ mLastTouchDownIndex = j;
+ break;
+ }
+ }
+ } else {
+ mLastTouchDownIndex = childIndex;
+ }
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
newTouchTarget = addTouchTarget(child, idBitsToAssign);
@@ -1942,6 +1966,7 @@
break;
}
}
+ if (preorderedList != null) preorderedList.clear();
}
if (newTouchTarget == null && mFirstTouchTarget != null) {
@@ -2928,7 +2953,7 @@
*/
@Override
protected void dispatchDraw(Canvas canvas) {
- final int count = mChildrenCount;
+ final int childrenCount = mChildrenCount;
final View[] children = mChildren;
int flags = mGroupFlags;
@@ -2936,15 +2961,15 @@
final boolean cache = (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
final boolean buildCache = !isHardwareAccelerated();
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < childrenCount; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
final LayoutParams params = child.getLayoutParams();
- attachLayoutAnimationParameters(child, params, i, count);
+ attachLayoutAnimationParameters(child, params, i, childrenCount);
bindLayoutAnimation(child);
if (cache) {
child.setDrawingCacheEnabled(true);
- if (buildCache) {
+ if (buildCache) {
child.buildDrawingCache(true);
}
}
@@ -2997,21 +3022,22 @@
boolean more = false;
final long drawingTime = getDrawingTime();
- if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {
- for (int i = 0; i < count; i++) {
- final View child = children[i];
- if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
- more |= drawChild(canvas, child, drawingTime);
- }
- }
- } else {
- for (int i = 0; i < count; i++) {
- final View child = children[getChildDrawingOrder(count, i)];
- if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
- more |= drawChild(canvas, child, drawingTime);
- }
+
+ // Only use the preordered list if not HW accelerated, since the HW pipeline will do the
+ // draw reordering internally
+ final ArrayList<View> preorderedList = canvas.isHardwareAccelerated()
+ ? null : buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < childrenCount; i++) {
+ int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? children[childIndex] : preorderedList.get(childIndex);
+ if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
+ more |= drawChild(canvas, child, drawingTime);
}
}
+ if (preorderedList != null) preorderedList.clear();
// Draw any disappearing views that have animations
if (mDisappearingChildren != null) {
@@ -3096,6 +3122,47 @@
return i;
}
+ private boolean hasChildWithZ() {
+ for (int i = 0; i < mChildrenCount; i++) {
+ if (mChildren[i].getZ() != 0) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Populates (and returns) mPreSortedChildren with a pre-ordered list of the View's children,
+ * sorted first by Z, then by child drawing order (if applicable).
+ *
+ * Uses a stable, insertion sort which is commonly O(n) for ViewGroups with very few elevated
+ * children.
+ */
+ private ArrayList<View> buildOrderedChildList() {
+ final int count = mChildrenCount;
+ if (count <= 1 || !hasChildWithZ()) return null;
+
+ if (mPreSortedChildren == null) {
+ mPreSortedChildren = new ArrayList<View>(count);
+ } else {
+ mPreSortedChildren.ensureCapacity(count);
+ }
+
+ final boolean useCustomOrder = isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < mChildrenCount; i++) {
+ // add next child (in child order) to end of list
+ int childIndex = useCustomOrder ? getChildDrawingOrder(mChildrenCount, i) : i;
+ View nextChild = mChildren[childIndex];
+ float currentZ = nextChild.getZ();
+
+ // insert ahead of any Views with greater Z
+ int insertIndex = i;
+ while (insertIndex > 0 && mPreSortedChildren.get(insertIndex - 1).getZ() > currentZ) {
+ insertIndex--;
+ }
+ mPreSortedChildren.add(insertIndex, nextChild);
+ }
+ return mPreSortedChildren;
+ }
+
private void notifyAnimationListener() {
mGroupFlags &= ~FLAG_NOTIFY_ANIMATION_LISTENER;
mGroupFlags |= FLAG_ANIMATION_DONE;
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 3104862..af1de78 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -253,9 +253,10 @@
ViewPropertyAnimator(View view) {
mView = view;
view.ensureTransformationInfo();
- if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
- mRTBackend = new ViewPropertyAnimatorRT(view);
- }
+ // TODO: Disabled because of b/15287046
+ //if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+ // mRTBackend = new ViewPropertyAnimatorRT(view);
+ //}
}
/**
@@ -1142,7 +1143,8 @@
// Shouldn't happen, but just to play it safe
return;
}
- boolean useRenderNodeProperties = mView.mRenderNode != null;
+
+ boolean hardwareAccelerated = mView.isHardwareAccelerated();
// alpha requires slightly different treatment than the other (transform) properties.
// The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
@@ -1150,13 +1152,13 @@
// We track what kinds of properties are set, and how alpha is handled when it is
// set, and perform the invalidation steps appropriately.
boolean alphaHandled = false;
- if (!useRenderNodeProperties) {
+ if (!hardwareAccelerated) {
mView.invalidateParentCaches();
}
float fraction = animation.getAnimatedFraction();
int propertyMask = propertyBundle.mPropertyMask;
if ((propertyMask & TRANSFORM_MASK) != 0) {
- mView.invalidateViewProperty(false, false);
+ mView.invalidateViewProperty(hardwareAccelerated, false);
}
ArrayList<NameValuesHolder> valueList = propertyBundle.mNameValuesHolder;
if (valueList != null) {
@@ -1172,7 +1174,7 @@
}
}
if ((propertyMask & TRANSFORM_MASK) != 0) {
- if (!useRenderNodeProperties) {
+ if (!hardwareAccelerated) {
mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 031ad80..4eecc6a0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -218,7 +218,8 @@
@ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL"),
@ViewDebug.IntToString(from = TYPE_DISPLAY_OVERLAY, to = "TYPE_DISPLAY_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_MAGNIFICATION_OVERLAY, to = "TYPE_MAGNIFICATION_OVERLAY"),
- @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION")
+ @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION"),
+ @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION, to = "TYPE_VOICE_INTERACTION"),
})
public int type;
@@ -541,6 +542,12 @@
public static final int TYPE_PRIVATE_PRESENTATION = FIRST_SYSTEM_WINDOW+30;
/**
+ * Window type: Windows in the voice interaction layer.
+ * @hide
+ */
+ public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1bb20c9..d45d686 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -274,6 +274,11 @@
public IApplicationToken getAppToken();
/**
+ * Return true if this window is participating in voice interaction.
+ */
+ public boolean isVoiceInteraction();
+
+ /**
* Return true if, at any point, the application token associated with
* this window has actually displayed any windows. This is most useful
* with the "starting up" window to determine if any windows were
@@ -603,8 +608,15 @@
* Return whether the given window should forcibly hide everything
* behind it. Typically returns true for the keyguard.
*/
- public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs);
-
+ public boolean doesForceHide(WindowManager.LayoutParams attrs);
+
+
+ /**
+ * Return whether the given window can become one that passes doesForceHide() test.
+ * Typically returns true for the StatusBar.
+ */
+ public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs);
+
/**
* Determine if a window that is behind one that is force hiding
* (as determined by {@link #doesForceHide}) should actually be hidden.
@@ -613,7 +625,7 @@
* will conflict with what you set.
*/
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
-
+
/**
* Called when the system would like to show a UI to indicate that an
* application is starting. You can use this to add a
@@ -1144,12 +1156,6 @@
public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
/**
- * Show the recents task list app.
- * @hide
- */
- public void showRecentApps();
-
- /**
* @return The current height of the input method window.
*/
public int getInputMethodWindowVisibleHeightLw();
@@ -1190,4 +1196,9 @@
* @return True if the window is a top level one.
*/
public boolean isTopLevelWindow(int windowType);
+
+ /**
+ * Notifies the keyguard to start fading out.
+ */
+ public void startKeyguardExitAnimation(long fadeoutDuration);
}
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 51759c5..1fddf3e 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -544,6 +544,7 @@
public void setMenuView(ActionMenuView menuView) {
mMenuView = menuView;
+ menuView.initialize(mMenu);
}
private static class SavedState implements Parcelable {
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 3975edf..a9a5eae 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -69,6 +69,7 @@
/** @hide */
public void setPresenter(ActionMenuPresenter presenter) {
mPresenter = presenter;
+ mPresenter.setMenuView(this);
}
@Override
@@ -488,7 +489,7 @@
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mPresenter.dismissPopupMenus();
+ dismissPopupMenus();
}
/** @hide */
@@ -578,6 +579,56 @@
}
/**
+ * Returns the current menu or null if one has not yet been configured.
+ * @hide Internal use only for action bar integration
+ */
+ public MenuBuilder peekMenu() {
+ return mMenu;
+ }
+
+ /**
+ * Show the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be shown, false otherwise
+ */
+ public boolean showOverflowMenu() {
+ return mPresenter != null && mPresenter.showOverflowMenu();
+ }
+
+ /**
+ * Hide the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be hidden, false otherwise
+ */
+ public boolean hideOverflowMenu() {
+ return mPresenter != null && mPresenter.hideOverflowMenu();
+ }
+
+ /**
+ * Check whether the overflow menu is currently showing. This may not reflect
+ * a pending show operation in progress.
+ *
+ * @return true if the overflow menu is currently showing
+ */
+ public boolean isOverflowMenuShowing() {
+ return mPresenter != null && mPresenter.isOverflowMenuShowing();
+ }
+
+ /** @hide */
+ public boolean isOverflowMenuShowPending() {
+ return mPresenter != null && mPresenter.isOverflowMenuShowPending();
+ }
+
+ /**
+ * Dismiss any popups associated with this menu view.
+ */
+ public void dismissPopupMenus() {
+ if (mPresenter != null) {
+ mPresenter.dismissPopupMenus();
+ }
+ }
+
+ /**
* @hide Private LinearLayout (superclass) API. Un-hide if LinearLayout API is made public.
*/
@Override
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index f903346..8c67bb7 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -18,13 +18,17 @@
package android.widget;
import android.annotation.NonNull;
+import android.app.ActionBar;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.Log;
+import android.view.CollapsibleActionView;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
@@ -32,7 +36,15 @@
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.Window;
import com.android.internal.R;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
+import com.android.internal.widget.DecorToolbar;
+import com.android.internal.widget.ToolbarWidgetWrapper;
import java.util.ArrayList;
import java.util.List;
@@ -80,14 +92,25 @@
* layout is discouraged on API 21 devices and newer.</p>
*/
public class Toolbar extends ViewGroup {
+ private static final String TAG = "Toolbar";
+
private ActionMenuView mMenuView;
private TextView mTitleTextView;
private TextView mSubtitleTextView;
private ImageButton mNavButtonView;
private ImageView mLogoView;
+ private Drawable mCollapseIcon;
+ private ImageButton mCollapseButtonView;
+ View mExpandedActionView;
+
private int mTitleTextAppearance;
private int mSubtitleTextAppearance;
+ private int mNavButtonStyle;
+
+ private int mButtonGravity;
+
+ private int mMaxButtonHeight;
private int mTitleMarginStart;
private int mTitleMarginEnd;
@@ -117,6 +140,10 @@
}
};
+ private ToolbarWidgetWrapper mWrapper;
+ private ActionMenuPresenter mOuterActionMenuPresenter;
+ private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
+
public Toolbar(Context context) {
this(context, null);
}
@@ -137,7 +164,9 @@
mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);
+ mNavButtonStyle = a.getResourceId(R.styleable.Toolbar_navigationButtonStyle, 0);
mGravity = a.getInteger(R.styleable.Toolbar_gravity, mGravity);
+ mButtonGravity = a.getInteger(R.styleable.Toolbar_buttonGravity, Gravity.TOP);
mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =
a.getDimensionPixelOffset(R.styleable.Toolbar_titleMargins, 0);
@@ -162,6 +191,8 @@
mTitleMarginBottom = marginBottom;
}
+ mMaxButtonHeight = a.getDimensionPixelSize(R.styleable.Toolbar_maxButtonHeight, -1);
+
final int contentInsetStart =
a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetStart,
RtlSpacingHelper.UNDEFINED);
@@ -180,6 +211,8 @@
mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
}
+ mCollapseIcon = a.getDrawable(R.styleable.Toolbar_collapseIcon);
+
final CharSequence title = a.getText(R.styleable.Toolbar_title);
if (!TextUtils.isEmpty(title)) {
setTitle(title);
@@ -211,6 +244,110 @@
setLogo(getContext().getDrawable(resId));
}
+ /** @hide */
+ public boolean canShowOverflowMenu() {
+ return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
+ }
+
+ /**
+ * Check whether the overflow menu is currently showing. This may not reflect
+ * a pending show operation in progress.
+ *
+ * @return true if the overflow menu is currently showing
+ */
+ public boolean isOverflowMenuShowing() {
+ return mMenuView != null && mMenuView.isOverflowMenuShowing();
+ }
+
+ /** @hide */
+ public boolean isOverflowMenuShowPending() {
+ return mMenuView != null && mMenuView.isOverflowMenuShowPending();
+ }
+
+ /**
+ * Show the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be shown, false otherwise
+ */
+ public boolean showOverflowMenu() {
+ return mMenuView != null && mMenuView.showOverflowMenu();
+ }
+
+ /**
+ * Hide the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be hidden, false otherwise
+ */
+ public boolean hideOverflowMenu() {
+ return mMenuView != null && mMenuView.hideOverflowMenu();
+ }
+
+ /** @hide */
+ public void setMenu(MenuBuilder menu, ActionMenuPresenter outerPresenter) {
+ if (menu == null && mMenuView == null) {
+ return;
+ }
+
+ ensureMenuView();
+ final MenuBuilder oldMenu = mMenuView.peekMenu();
+ if (oldMenu == menu) {
+ return;
+ }
+
+ if (oldMenu != null) {
+ oldMenu.removeMenuPresenter(mOuterActionMenuPresenter);
+ oldMenu.removeMenuPresenter(mExpandedMenuPresenter);
+ }
+
+ final Context context = getContext();
+
+ if (mExpandedMenuPresenter == null) {
+ mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
+ }
+
+ outerPresenter.setExpandedActionViewsExclusive(true);
+ if (menu != null) {
+ menu.addMenuPresenter(outerPresenter);
+ menu.addMenuPresenter(mExpandedMenuPresenter);
+ } else {
+ outerPresenter.initForMenu(context, null);
+ mExpandedMenuPresenter.initForMenu(context, null);
+ outerPresenter.updateMenuView(true);
+ mExpandedMenuPresenter.updateMenuView(true);
+ }
+ mMenuView.setPresenter(outerPresenter);
+ mOuterActionMenuPresenter = outerPresenter;
+ }
+
+ /**
+ * Dismiss all currently showing popup menus, including overflow or submenus.
+ */
+ public void dismissPopupMenus() {
+ if (mMenuView != null) {
+ mMenuView.dismissPopupMenus();
+ }
+ }
+
+ /** @hide */
+ public boolean isTitleTruncated() {
+ if (mTitleTextView == null) {
+ return false;
+ }
+
+ final Layout titleLayout = mTitleTextView.getLayout();
+ if (titleLayout == null) {
+ return false;
+ }
+
+ final int lineCount = titleLayout.getLineCount();
+ for (int i = 0; i < lineCount; i++) {
+ if (titleLayout.getEllipsisCount(i) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Set a logo drawable.
*
@@ -222,9 +359,7 @@
*/
public void setLogo(Drawable drawable) {
if (drawable != null) {
- if (mLogoView == null) {
- mLogoView = new ImageView(getContext());
- }
+ ensureLogoView();
if (mLogoView.getParent() == null) {
addSystemView(mLogoView);
}
@@ -268,8 +403,8 @@
* @param description Description to set
*/
public void setLogoDescription(CharSequence description) {
- if (!TextUtils.isEmpty(description) && mLogoView == null) {
- mLogoView = new ImageView(getContext());
+ if (!TextUtils.isEmpty(description)) {
+ ensureLogoView();
}
if (mLogoView != null) {
mLogoView.setContentDescription(description);
@@ -285,10 +420,48 @@
return mLogoView != null ? mLogoView.getContentDescription() : null;
}
+ private void ensureLogoView() {
+ if (mLogoView == null) {
+ mLogoView = new ImageView(getContext());
+ }
+ }
+
/**
- * Return the current title displayed in the toolbar.
+ * Check whether this Toolbar is currently hosting an expanded action view.
*
- * @return The current title
+ * <p>An action view may be expanded either directly from the
+ * {@link android.view.MenuItem MenuItem} it belongs to or by user action. If the Toolbar
+ * has an expanded action view it can be collapsed using the {@link #collapseActionView()}
+ * method.</p>
+ *
+ * @return true if the Toolbar has an expanded action view
+ */
+ public boolean hasExpandedActionView() {
+ return mExpandedMenuPresenter != null &&
+ mExpandedMenuPresenter.mCurrentExpandedItem != null;
+ }
+
+ /**
+ * Collapse a currently expanded action view. If this Toolbar does not have an
+ * expanded action view this method has no effect.
+ *
+ * <p>An action view may be expanded either directly from the
+ * {@link android.view.MenuItem MenuItem} it belongs to or by user action.</p>
+ *
+ * @see #hasExpandedActionView()
+ */
+ public void collapseActionView() {
+ final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
+ mExpandedMenuPresenter.mCurrentExpandedItem;
+ if (item != null) {
+ item.collapseActionView();
+ }
+ }
+
+ /**
+ * Returns the title of this toolbar.
+ *
+ * @return The current title.
*/
public CharSequence getTitle() {
return mTitleText;
@@ -319,6 +492,8 @@
if (mTitleTextView == null) {
final Context context = getContext();
mTitleTextView = new TextView(context);
+ mTitleTextView.setSingleLine();
+ mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
}
if (mTitleTextView.getParent() == null) {
@@ -365,6 +540,8 @@
if (mSubtitleTextView == null) {
final Context context = getContext();
mSubtitleTextView = new TextView(context);
+ mSubtitleTextView.setSingleLine();
+ mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance);
}
if (mSubtitleTextView.getParent() == null) {
@@ -395,6 +572,30 @@
}
/**
+ * Set a content description for the navigation button if one is present. The content
+ * description will be read via screen readers or other accessibility systems to explain
+ * the action of the navigation button.
+ *
+ * @param description Content description to set
+ */
+ public void setNavigationContentDescription(CharSequence description) {
+ ensureNavButtonView();
+ mNavButtonView.setContentDescription(description);
+ }
+
+ /**
+ * Set a content description for the navigation button if one is present. The content
+ * description will be read via screen readers or other accessibility systems to explain
+ * the action of the navigation button.
+ *
+ * @param resId Resource ID of a content description string to set
+ */
+ public void setNavigationContentDescription(int resId) {
+ ensureNavButtonView();
+ mNavButtonView.setContentDescription(getContext().getText(resId));
+ }
+
+ /**
* Set the icon to use for the toolbar's navigation button.
*
* <p>The navigation button appears at the start of the toolbar if present. Setting an icon
@@ -480,12 +681,19 @@
* @return The toolbar's Menu
*/
public Menu getMenu() {
+ ensureMenuView();
+ return mMenuView.getMenu();
+ }
+
+ private void ensureMenuView() {
if (mMenuView == null) {
mMenuView = new ActionMenuView(getContext());
mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ mMenuView.setLayoutParams(lp);
addSystemView(mMenuView);
}
- return mMenuView.getMenu();
}
private MenuInflater getMenuInflater() {
@@ -634,7 +842,27 @@
private void ensureNavButtonView() {
if (mNavButtonView == null) {
- mNavButtonView = new ImageButton(getContext(), null, R.attr.borderlessButtonStyle);
+ mNavButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ mNavButtonView.setLayoutParams(lp);
+ }
+ }
+
+ private void ensureCollapseButtonView() {
+ if (mCollapseButtonView == null) {
+ mCollapseButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
+ mCollapseButtonView.setImageDrawable(mCollapseIcon);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ lp.mViewType = LayoutParams.EXPANDED;
+ mCollapseButtonView.setLayoutParams(lp);
+ mCollapseButtonView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ collapseActionView();
+ }
+ });
}
}
@@ -657,6 +885,27 @@
super.onRestoreInstanceState(ss.getSuperState());
}
+ private void measureChildConstrained(View child, int parentWidthSpec, int widthUsed,
+ int parentHeightSpec, int heightUsed, int heightConstraint) {
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
+ mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ + widthUsed, lp.width);
+ int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
+ mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+ + heightUsed, lp.height);
+
+ final int childHeightMode = MeasureSpec.getMode(childHeightSpec);
+ if (childHeightMode != MeasureSpec.EXACTLY && heightConstraint >= 0) {
+ final int size = childHeightMode != MeasureSpec.UNSPECIFIED ?
+ Math.min(MeasureSpec.getSize(childHeightSpec), heightConstraint) :
+ heightConstraint;
+ childHeightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+ }
+ child.measure(childWidthSpec, childHeightSpec);
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
@@ -667,18 +916,30 @@
int navWidth = 0;
if (shouldLayout(mNavButtonView)) {
- measureChildWithMargins(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0);
+ measureChildConstrained(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0,
+ mMaxButtonHeight);
navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
height = Math.max(height, mNavButtonView.getMeasuredHeight() +
getVerticalMargins(mNavButtonView));
childState = combineMeasuredStates(childState, mNavButtonView.getMeasuredState());
}
+ if (shouldLayout(mCollapseButtonView)) {
+ measureChildConstrained(mCollapseButtonView, widthMeasureSpec, width,
+ heightMeasureSpec, 0, mMaxButtonHeight);
+ navWidth = mCollapseButtonView.getMeasuredWidth() +
+ getHorizontalMargins(mCollapseButtonView);
+ height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
+ getVerticalMargins(mCollapseButtonView));
+ childState = combineMeasuredStates(childState, mCollapseButtonView.getMeasuredState());
+ }
+
width += Math.max(getContentInsetStart(), navWidth);
int menuWidth = 0;
if (shouldLayout(mMenuView)) {
- measureChildWithMargins(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0);
+ measureChildConstrained(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0,
+ mMaxButtonHeight);
menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
height = Math.max(height, mMenuView.getMeasuredHeight() +
getVerticalMargins(mMenuView));
@@ -687,6 +948,16 @@
width += Math.max(getContentInsetEnd(), menuWidth);
+ if (shouldLayout(mExpandedActionView)) {
+ measureChildWithMargins(mExpandedActionView, widthMeasureSpec, width,
+ heightMeasureSpec, 0);
+ width += mExpandedActionView.getMeasuredWidth() +
+ getHorizontalMargins(mExpandedActionView);
+ height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
+ getVerticalMargins(mExpandedActionView));
+ childState = combineMeasuredStates(childState, mExpandedActionView.getMeasuredState());
+ }
+
if (shouldLayout(mLogoView)) {
measureChildWithMargins(mLogoView, widthMeasureSpec, width, heightMeasureSpec, 0);
width += mLogoView.getMeasuredWidth() + getHorizontalMargins(mLogoView);
@@ -723,7 +994,7 @@
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType == LayoutParams.SYSTEM || !shouldLayout(child)) {
+ if (lp.mViewType != LayoutParams.CUSTOM || !shouldLayout(child)) {
// We already got all system views above. Skip them and GONE views.
continue;
}
@@ -768,6 +1039,14 @@
}
}
+ if (shouldLayout(mCollapseButtonView)) {
+ if (isRtl) {
+ right = layoutChildRight(mCollapseButtonView, right);
+ } else {
+ left = layoutChildLeft(mCollapseButtonView, left);
+ }
+ }
+
if (shouldLayout(mMenuView)) {
if (isRtl) {
left = layoutChildLeft(mMenuView, left);
@@ -779,6 +1058,14 @@
left = Math.max(left, getContentInsetLeft());
right = Math.min(right, width - paddingRight - getContentInsetRight());
+ if (shouldLayout(mExpandedActionView)) {
+ if (isRtl) {
+ right = layoutChildRight(mExpandedActionView, right);
+ } else {
+ left = layoutChildLeft(mExpandedActionView, left);
+ }
+ }
+
if (shouldLayout(mLogoView)) {
if (isRtl) {
right = layoutChildRight(mLogoView, right);
@@ -801,40 +1088,42 @@
if (layoutTitle || layoutSubtitle) {
int titleTop;
+ final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView;
+ final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView;
+ final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams();
+ final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams();
+
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
case Gravity.TOP:
- titleTop = getPaddingTop();
+ titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop;
break;
default:
case Gravity.CENTER_VERTICAL:
- final View child = layoutTitle ? mTitleTextView : mSubtitleTextView;
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int space = height - paddingTop - paddingBottom;
int spaceAbove = (space - titleHeight) / 2;
- if (spaceAbove < lp.topMargin + mTitleMarginTop) {
- spaceAbove = lp.topMargin + mTitleMarginTop;
+ if (spaceAbove < toplp.topMargin + mTitleMarginTop) {
+ spaceAbove = toplp.topMargin + mTitleMarginTop;
} else {
final int spaceBelow = height - paddingBottom - titleHeight -
spaceAbove - paddingTop;
- if (spaceBelow < lp.bottomMargin + mTitleMarginBottom) {
+ if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) {
spaceAbove = Math.max(0, spaceAbove -
- (lp.bottomMargin + mTitleMarginBottom - spaceBelow));
+ (bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow));
}
}
titleTop = paddingTop + spaceAbove;
break;
case Gravity.BOTTOM:
- titleTop = height - paddingBottom - titleHeight;
+ titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom -
+ titleHeight;
break;
}
if (isRtl) {
int titleRight = right;
int subtitleRight = right;
- titleTop += mTitleMarginTop;
if (layoutTitle) {
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
titleRight -= lp.rightMargin + mTitleMarginStart;
- titleTop += lp.topMargin;
final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth();
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
@@ -855,11 +1144,9 @@
} else {
int titleLeft = left;
int subtitleLeft = left;
- titleTop += mTitleMarginTop;
if (layoutTitle) {
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
titleLeft += lp.leftMargin + mTitleMarginStart;
- titleTop += lp.topMargin;
final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth();
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
@@ -897,7 +1184,7 @@
// Centered views try to center with respect to the whole bar, but views pinned
// to the left or right can push the mass of centered views to one side or the other.
- addCustomViewsWithGravity(mTempViews, Gravity.CENTER);
+ addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL);
final int centerViewsWidth = getViewListMeasuredWidth(mTempViews);
final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2;
final int halfCenterViewsWidth = centerViewsWidth / 2;
@@ -1007,17 +1294,16 @@
for (int i = childCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.SYSTEM && shouldLayout(child) &&
+ if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
getChildHorizontalGravity(lp.gravity) == absGrav) {
views.add(child);
}
-
}
} else {
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.SYSTEM && shouldLayout(child) &&
+ if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
getChildHorizontalGravity(lp.gravity) == absGrav) {
views.add(child);
}
@@ -1054,14 +1340,16 @@
}
@Override
- public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
- return super.generateLayoutParams(attrs);
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
}
@Override
- protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
return new LayoutParams((LayoutParams) p);
+ } else if (p instanceof ActionBar.LayoutParams) {
+ return new LayoutParams((ActionBar.LayoutParams) p);
} else if (p instanceof MarginLayoutParams) {
return new LayoutParams((MarginLayoutParams) p);
} else {
@@ -1070,7 +1358,7 @@
}
@Override
- protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@@ -1083,6 +1371,25 @@
return ((LayoutParams) child.getLayoutParams()).mViewType == LayoutParams.CUSTOM;
}
+ /** @hide */
+ public DecorToolbar getWrapper() {
+ if (mWrapper == null) {
+ mWrapper = new ToolbarWidgetWrapper(this);
+ }
+ return mWrapper;
+ }
+
+ private void setChildVisibilityForExpandedActionView(boolean expand) {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
+ child.setVisibility(expand ? GONE : VISIBLE);
+ }
+ }
+ }
+
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
@@ -1103,44 +1410,15 @@
*
* @attr ref android.R.styleable#Toolbar_LayoutParams_layout_gravity
*/
- public static class LayoutParams extends MarginLayoutParams {
- /**
- * Gravity for the view associated with these LayoutParams.
- *
- * @see android.view.Gravity
- */
- @ViewDebug.ExportedProperty(category = "layout", mapping = {
- @ViewDebug.IntToString(from = -1, to = "NONE"),
- @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"),
- @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"),
- @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"),
- @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"),
- @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"),
- @ViewDebug.IntToString(from = Gravity.START, to = "START"),
- @ViewDebug.IntToString(from = Gravity.END, to = "END"),
- @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"),
- @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"),
- @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
- @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"),
- @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
- @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
- })
- public int gravity = Gravity.NO_GRAVITY;
-
+ public static class LayoutParams extends ActionBar.LayoutParams {
static final int CUSTOM = 0;
static final int SYSTEM = 1;
+ static final int EXPANDED = 2;
int mViewType = CUSTOM;
public LayoutParams(@NonNull Context c, AttributeSet attrs) {
super(c, attrs);
-
- TypedArray a = c.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.Toolbar_LayoutParams);
- gravity = a.getInt(
- com.android.internal.R.styleable.Toolbar_LayoutParams_layout_gravity,
- Gravity.NO_GRAVITY);
- a.recycle();
}
public LayoutParams(int width, int height) {
@@ -1160,7 +1438,11 @@
public LayoutParams(LayoutParams source) {
super(source);
- this.gravity = source.gravity;
+ mViewType = source.mViewType;
+ }
+
+ public LayoutParams(ActionBar.LayoutParams source) {
+ super(source);
}
public LayoutParams(MarginLayoutParams source) {
@@ -1199,4 +1481,126 @@
}
};
}
+
+ private class ExpandedActionViewMenuPresenter implements MenuPresenter {
+ MenuBuilder mMenu;
+ MenuItemImpl mCurrentExpandedItem;
+
+ @Override
+ public void initForMenu(Context context, MenuBuilder menu) {
+ // Clear the expanded action view when menus change.
+ if (mMenu != null && mCurrentExpandedItem != null) {
+ mMenu.collapseItemActionView(mCurrentExpandedItem);
+ }
+ mMenu = menu;
+ }
+
+ @Override
+ public MenuView getMenuView(ViewGroup root) {
+ return null;
+ }
+
+ @Override
+ public void updateMenuView(boolean cleared) {
+ // Make sure the expanded item we have is still there.
+ if (mCurrentExpandedItem != null) {
+ boolean found = false;
+
+ if (mMenu != null) {
+ final int count = mMenu.size();
+ for (int i = 0; i < count; i++) {
+ final MenuItem item = mMenu.getItem(i);
+ if (item == mCurrentExpandedItem) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ // The item we had expanded disappeared. Collapse.
+ collapseItemActionView(mMenu, mCurrentExpandedItem);
+ }
+ }
+ }
+
+ @Override
+ public void setCallback(Callback cb) {
+ }
+
+ @Override
+ public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
+ return false;
+ }
+
+ @Override
+ public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+ }
+
+ @Override
+ public boolean flagActionItems() {
+ return false;
+ }
+
+ @Override
+ public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
+ ensureCollapseButtonView();
+ if (mCollapseButtonView.getParent() != Toolbar.this) {
+ addView(mCollapseButtonView);
+ }
+ mExpandedActionView = item.getActionView();
+ mCurrentExpandedItem = item;
+ if (mExpandedActionView.getParent() != Toolbar.this) {
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ lp.mViewType = LayoutParams.EXPANDED;
+ mExpandedActionView.setLayoutParams(lp);
+ addView(mExpandedActionView);
+ }
+
+ setChildVisibilityForExpandedActionView(true);
+ requestLayout();
+ item.setActionViewExpanded(true);
+
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
+ // Do this before detaching the actionview from the hierarchy, in case
+ // it needs to dismiss the soft keyboard, etc.
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
+ }
+
+ removeView(mExpandedActionView);
+ removeView(mCollapseButtonView);
+ mExpandedActionView = null;
+
+ setChildVisibilityForExpandedActionView(false);
+ mCurrentExpandedItem = null;
+ requestLayout();
+ item.setActionViewExpanded(false);
+
+ return true;
+ }
+
+ @Override
+ public int getId() {
+ return 0;
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ return null;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 41f3337..7e11850 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1100,7 +1100,7 @@
public boolean evaluateSystemProperties(boolean update) {
boolean changed = false;
- String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.1",
+ String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2",
VMRuntime.getRuntime().vmLibrary());
if (!Objects.equals(runtime, mRuntime)) {
changed = true;
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a238ae3..5c7a4e6 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -18,7 +18,10 @@
import android.animation.ValueAnimator;
import android.content.res.TypedArray;
+import android.view.ViewGroup;
import android.view.ViewParent;
+import android.widget.AdapterView;
+import android.widget.Toolbar;
import com.android.internal.R;
import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.MenuBuilder;
@@ -28,6 +31,7 @@
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarOverlayLayout;
import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.DecorToolbar;
import com.android.internal.widget.ScrollingTabContainerView;
import android.animation.Animator;
@@ -55,6 +59,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.SpinnerAdapter;
+import com.android.internal.widget.ToolbarWidgetWrapper;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -77,7 +82,7 @@
private ActionBarOverlayLayout mOverlayLayout;
private ActionBarContainer mContainerView;
- private ActionBarView mActionView;
+ private DecorToolbar mDecorToolbar;
private ActionBarContextView mContextView;
private ActionBarContainer mSplitView;
private View mContentView;
@@ -187,7 +192,7 @@
if (mOverlayLayout != null) {
mOverlayLayout.setActionBarVisibilityCallback(this);
}
- mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
+ mDecorToolbar = getDecorToolbar(decor.findViewById(com.android.internal.R.id.action_bar));
mContextView = (ActionBarContextView) decor.findViewById(
com.android.internal.R.id.action_context_bar);
mContainerView = (ActionBarContainer) decor.findViewById(
@@ -195,18 +200,17 @@
mSplitView = (ActionBarContainer) decor.findViewById(
com.android.internal.R.id.split_action_bar);
- if (mActionView == null || mContextView == null || mContainerView == null) {
+ if (mDecorToolbar == null || mContextView == null || mContainerView == null) {
throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
"with a compatible window decor layout");
}
- mContext = mActionView.getContext();
- mActionView.setContextView(mContextView);
- mContextDisplayMode = mActionView.isSplitActionBar() ?
+ mContext = mDecorToolbar.getContext();
+ mContextDisplayMode = mDecorToolbar.isSplit() ?
CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
// This was initially read from the action bar style
- final int current = mActionView.getDisplayOptions();
+ final int current = mDecorToolbar.getDisplayOptions();
final boolean homeAsUp = (current & DISPLAY_HOME_AS_UP) != 0;
if (homeAsUp) {
mDisplayHomeAsUpSet = true;
@@ -225,6 +229,17 @@
a.recycle();
}
+ private DecorToolbar getDecorToolbar(View view) {
+ if (view instanceof DecorToolbar) {
+ return (DecorToolbar) view;
+ } else if (view instanceof Toolbar) {
+ return ((Toolbar) view).getWrapper();
+ } else {
+ throw new IllegalStateException("Can't make a decor toolbar out of " +
+ view.getClass().getSimpleName());
+ }
+ }
+
public void onConfigurationChanged(Configuration newConfig) {
setHasEmbeddedTabs(ActionBarPolicy.get(mContext).hasEmbeddedTabs());
}
@@ -233,11 +248,11 @@
mHasEmbeddedTabs = hasEmbeddedTabs;
// Switch tab layout configuration if needed
if (!mHasEmbeddedTabs) {
- mActionView.setEmbeddedTabView(null);
+ mDecorToolbar.setEmbeddedTabView(null);
mContainerView.setTabContainer(mTabScrollView);
} else {
mContainerView.setTabContainer(null);
- mActionView.setEmbeddedTabView(mTabScrollView);
+ mDecorToolbar.setEmbeddedTabView(mTabScrollView);
}
final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
if (mTabScrollView != null) {
@@ -250,7 +265,7 @@
mTabScrollView.setVisibility(View.GONE);
}
}
- mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode);
+ mDecorToolbar.setCollapsible(!mHasEmbeddedTabs && isInTabMode);
mOverlayLayout.setHasNonEmbeddedTabs(!mHasEmbeddedTabs && isInTabMode);
}
@@ -263,7 +278,7 @@
if (mHasEmbeddedTabs) {
tabScroller.setVisibility(View.VISIBLE);
- mActionView.setEmbeddedTabView(tabScroller);
+ mDecorToolbar.setEmbeddedTabView(tabScroller);
} else {
if (getNavigationMode() == NAVIGATION_MODE_TABS) {
tabScroller.setVisibility(View.VISIBLE);
@@ -326,7 +341,8 @@
@Override
public void setCustomView(int resId) {
- setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false));
+ setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId,
+ mDecorToolbar.getViewGroup(), false));
}
@Override
@@ -356,7 +372,7 @@
@Override
public void setHomeButtonEnabled(boolean enable) {
- mActionView.setHomeButtonEnabled(enable);
+ mDecorToolbar.setHomeButtonEnabled(enable);
}
@Override
@@ -370,12 +386,12 @@
}
public void setSelectedNavigationItem(int position) {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
selectTab(mTabs.get(position));
break;
case NAVIGATION_MODE_LIST:
- mActionView.setDropdownSelectedPosition(position);
+ mDecorToolbar.setDropdownSelectedPosition(position);
break;
default:
throw new IllegalStateException(
@@ -399,26 +415,26 @@
}
public void setTitle(CharSequence title) {
- mActionView.setTitle(title);
+ mDecorToolbar.setTitle(title);
}
public void setSubtitle(CharSequence subtitle) {
- mActionView.setSubtitle(subtitle);
+ mDecorToolbar.setSubtitle(subtitle);
}
public void setDisplayOptions(int options) {
if ((options & DISPLAY_HOME_AS_UP) != 0) {
mDisplayHomeAsUpSet = true;
}
- mActionView.setDisplayOptions(options);
+ mDecorToolbar.setDisplayOptions(options);
}
public void setDisplayOptions(int options, int mask) {
- final int current = mActionView.getDisplayOptions();
+ final int current = mDecorToolbar.getDisplayOptions();
if ((mask & DISPLAY_HOME_AS_UP) != 0) {
mDisplayHomeAsUpSet = true;
}
- mActionView.setDisplayOptions((options & mask) | (current & ~mask));
+ mDecorToolbar.setDisplayOptions((options & mask) | (current & ~mask));
}
public void setBackgroundDrawable(Drawable d) {
@@ -436,23 +452,23 @@
}
public View getCustomView() {
- return mActionView.getCustomNavigationView();
+ return mDecorToolbar.getCustomView();
}
public CharSequence getTitle() {
- return mActionView.getTitle();
+ return mDecorToolbar.getTitle();
}
public CharSequence getSubtitle() {
- return mActionView.getSubtitle();
+ return mDecorToolbar.getSubtitle();
}
public int getNavigationMode() {
- return mActionView.getNavigationMode();
+ return mDecorToolbar.getNavigationMode();
}
public int getDisplayOptions() {
- return mActionView.getDisplayOptions();
+ return mDecorToolbar.getDisplayOptions();
}
public ActionMode startActionMode(ActionMode.Callback callback) {
@@ -572,7 +588,7 @@
return;
}
- final FragmentTransaction trans = mActionView.isInEditMode() ? null :
+ final FragmentTransaction trans = ((View) mDecorToolbar).isInEditMode() ? null :
mActivity.getFragmentManager().beginTransaction().disallowAddToBackStack();
if (mSelectedTab == tab) {
@@ -828,13 +844,18 @@
hideForActionMode();
}
- mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
+ mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
- if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) {
+ if (mTabScrollView != null && !mDecorToolbar.hasEmbeddedTabs() &&
+ isCollapsed((View) mDecorToolbar)) {
mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
}
}
+ private boolean isCollapsed(View view) {
+ return view == null || view.getVisibility() == View.GONE || view.getMeasuredHeight() == 0;
+ }
+
public Context getThemedContext() {
if (mThemedContext == null) {
TypedValue outValue = new TypedValue();
@@ -854,27 +875,27 @@
@Override
public boolean isTitleTruncated() {
- return mActionView != null && mActionView.isTitleTruncated();
+ return mDecorToolbar != null && mDecorToolbar.isTitleTruncated();
}
@Override
public void setHomeAsUpIndicator(Drawable indicator) {
- mActionView.setHomeAsUpIndicator(indicator);
+ mDecorToolbar.setNavigationIcon(indicator);
}
@Override
public void setHomeAsUpIndicator(int resId) {
- mActionView.setHomeAsUpIndicator(resId);
+ mDecorToolbar.setNavigationIcon(resId);
}
@Override
public void setHomeActionContentDescription(CharSequence description) {
- mActionView.setHomeActionContentDescription(description);
+ mDecorToolbar.setNavigationContentDescription(description);
}
@Override
public void setHomeActionContentDescription(int resId) {
- mActionView.setHomeActionContentDescription(resId);
+ mDecorToolbar.setNavigationContentDescription(resId);
}
@Override
@@ -938,7 +959,8 @@
// Clear out the context mode views after the animation finishes
mContextView.closeMode();
- mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ ((View) mDecorToolbar).sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
mOverlayLayout.setHideOnContentScrollEnabled(mHideOnContentScroll);
mActionMode = null;
@@ -1178,28 +1200,27 @@
@Override
public void setCustomView(View view) {
- mActionView.setCustomNavigationView(view);
+ mDecorToolbar.setCustomView(view);
}
@Override
public void setCustomView(View view, LayoutParams layoutParams) {
view.setLayoutParams(layoutParams);
- mActionView.setCustomNavigationView(view);
+ mDecorToolbar.setCustomView(view);
}
@Override
public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
- mActionView.setDropdownAdapter(adapter);
- mActionView.setCallback(callback);
+ mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
}
@Override
public int getSelectedNavigationIndex() {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
case NAVIGATION_MODE_LIST:
- return mActionView.getDropdownSelectedPosition();
+ return mDecorToolbar.getDropdownSelectedPosition();
default:
return -1;
}
@@ -1207,12 +1228,11 @@
@Override
public int getNavigationItemCount() {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
return mTabs.size();
case NAVIGATION_MODE_LIST:
- SpinnerAdapter adapter = mActionView.getDropdownAdapter();
- return adapter != null ? adapter.getCount() : 0;
+ return mDecorToolbar.getDropdownItemCount();
default:
return 0;
}
@@ -1225,7 +1245,7 @@
@Override
public void setNavigationMode(int mode) {
- final int oldMode = mActionView.getNavigationMode();
+ final int oldMode = mDecorToolbar.getNavigationMode();
switch (oldMode) {
case NAVIGATION_MODE_TABS:
mSavedTabPosition = getSelectedNavigationIndex();
@@ -1238,7 +1258,7 @@
mOverlayLayout.requestFitSystemWindows();
}
}
- mActionView.setNavigationMode(mode);
+ mDecorToolbar.setNavigationMode(mode);
switch (mode) {
case NAVIGATION_MODE_TABS:
ensureTabsExist();
@@ -1249,7 +1269,7 @@
}
break;
}
- mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
+ mDecorToolbar.setCollapsible(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
mOverlayLayout.setHasNonEmbeddedTabs(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
}
@@ -1261,30 +1281,30 @@
@Override
public void setIcon(int resId) {
- mActionView.setIcon(resId);
+ mDecorToolbar.setIcon(resId);
}
@Override
public void setIcon(Drawable icon) {
- mActionView.setIcon(icon);
+ mDecorToolbar.setIcon(icon);
}
public boolean hasIcon() {
- return mActionView.hasIcon();
+ return mDecorToolbar.hasIcon();
}
@Override
public void setLogo(int resId) {
- mActionView.setLogo(resId);
+ mDecorToolbar.setLogo(resId);
}
@Override
public void setLogo(Drawable logo) {
- mActionView.setLogo(logo);
+ mDecorToolbar.setLogo(logo);
}
public boolean hasLogo() {
- return mActionView.hasLogo();
+ return mDecorToolbar.hasLogo();
}
public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
@@ -1292,4 +1312,24 @@
setDisplayHomeAsUpEnabled(enable);
}
}
+
+ static class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
+ private final OnNavigationListener mListener;
+
+ public NavItemSelectedListener(OnNavigationListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ if (mListener != null) {
+ mListener.onNavigationItemSelected(position, id);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Do nothing
+ }
+ }
}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index b78c70f..f22800c 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -56,4 +56,10 @@
oneway void dispatch(in MotionEvent event);
oneway void launchCamera();
oneway void onBootCompleted();
+
+ /**
+ * Notifies that the activity behind has now been drawn and it's safe to remove the wallpaper
+ * and keyguard flag.
+ */
+ oneway void startKeyguardExitAnimation(long fadeoutDuration);
}
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 183478f..9e7ff93 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -34,7 +34,7 @@
public abstract class AbsActionBarView extends ViewGroup {
protected ActionMenuView mMenuView;
protected ActionMenuPresenter mActionMenuPresenter;
- protected ActionBarContainer mSplitView;
+ protected ViewGroup mSplitView;
protected boolean mSplitActionBar;
protected boolean mSplitWhenNarrow;
protected int mContentHeight;
@@ -74,7 +74,7 @@
setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
a.recycle();
if (mSplitWhenNarrow) {
- setSplitActionBar(getContext().getResources().getBoolean(
+ setSplitToolbar(getContext().getResources().getBoolean(
com.android.internal.R.bool.split_action_bar_is_narrow));
}
if (mActionMenuPresenter != null) {
@@ -86,7 +86,7 @@
* Sets whether the bar should be split right now, no questions asked.
* @param split true if the bar should split
*/
- public void setSplitActionBar(boolean split) {
+ public void setSplitToolbar(boolean split) {
mSplitActionBar = split;
}
@@ -107,7 +107,7 @@
return mContentHeight;
}
- public void setSplitView(ActionBarContainer splitView) {
+ public void setSplitView(ViewGroup splitView) {
mSplitView = splitView;
}
@@ -214,6 +214,10 @@
return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
}
+ public boolean canShowOverflowMenu() {
+ return isOverflowReserved() && getVisibility() == VISIBLE;
+ }
+
public void dismissPopupMenus() {
if (mActionMenuPresenter != null) {
mActionMenuPresenter.dismissPopupMenus();
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index ed07514..790b611 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -36,7 +36,7 @@
public class ActionBarContainer extends FrameLayout {
private boolean mIsTransitioning;
private View mTabContainer;
- private ActionBarView mActionBarView;
+ private View mActionBarView;
private Drawable mBackground;
private Drawable mStackedBackground;
@@ -76,7 +76,7 @@
@Override
public void onFinishInflate() {
super.onFinishInflate();
- mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ mActionBarView = findViewById(com.android.internal.R.id.action_bar);
}
public void setPrimaryBackground(Drawable bg) {
@@ -251,6 +251,10 @@
return null;
}
+ private boolean isCollapsed(View view) {
+ return view == null || view.getVisibility() == GONE || view.getMeasuredHeight() == 0;
+ }
+
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mActionBarView == null &&
@@ -263,7 +267,7 @@
if (mActionBarView == null) return;
final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams();
- final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 :
+ final int actionBarViewHeight = isCollapsed(mActionBarView) ? 0 :
mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
@@ -298,9 +302,8 @@
}
} else {
if (mBackground != null) {
- final ActionBarView actionBarView = mActionBarView;
- mBackground.setBounds(actionBarView.getLeft(), actionBarView.getTop(),
- actionBarView.getRight(), actionBarView.getBottom());
+ mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
+ mActionBarView.getRight(), mActionBarView.getBottom());
needsInvalidate = true;
}
mIsStacked = hasTabs;
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index e10070f..6ff77a0 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -83,7 +83,7 @@
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.ActionMode, defStyleAttr, defStyleRes);
- setBackgroundDrawable(a.getDrawable(
+ setBackground(a.getDrawable(
com.android.internal.R.styleable.ActionMode_background));
mTitleStyleRes = a.getResourceId(
com.android.internal.R.styleable.ActionMode_titleTextStyle, 0);
@@ -109,7 +109,7 @@
}
@Override
- public void setSplitActionBar(boolean split) {
+ public void setSplitToolbar(boolean split) {
if (mSplitActionBar != split) {
if (mActionMenuPresenter != null) {
// Mode is already active; move everything over and adjust the menu itself.
@@ -137,7 +137,7 @@
mSplitView.addView(mMenuView, layoutParams);
}
}
- super.setSplitActionBar(split);
+ super.setSplitToolbar(split);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 7ab4bed..8a9cb22 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -39,6 +39,7 @@
import android.view.Window;
import android.view.WindowInsets;
import android.widget.OverScroller;
+import android.widget.Toolbar;
import com.android.internal.view.menu.MenuPresenter;
/**
@@ -59,7 +60,7 @@
private ActionBarContainer mActionBarTop;
// Some interior UI elements.
- private ActionBarView mActionBarView;
+ private DecorToolbar mDecorToolbar;
// Content overlay drawable - generally the action bar's shadow
private Drawable mWindowContentOverlay;
@@ -401,7 +402,7 @@
topInset = mActionBarTop.getMeasuredHeight();
}
- if (mActionBarView.isSplitActionBar()) {
+ if (mDecorToolbar.isSplit()) {
// If action bar is split, adjust bottom insets for it.
if (mActionBarBottom != null) {
if (stable) {
@@ -563,12 +564,23 @@
mContent = findViewById(com.android.internal.R.id.content);
mActionBarTop = (ActionBarContainer) findViewById(
com.android.internal.R.id.action_bar_container);
- mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ mDecorToolbar = getDecorToolbar(findViewById(com.android.internal.R.id.action_bar));
mActionBarBottom = (ActionBarContainer) findViewById(
com.android.internal.R.id.split_action_bar);
}
}
+ private DecorToolbar getDecorToolbar(View view) {
+ if (view instanceof DecorToolbar) {
+ return (DecorToolbar) view;
+ } else if (view instanceof Toolbar) {
+ return ((Toolbar) view).getWrapper();
+ } else {
+ throw new IllegalStateException("Can't make a decor toolbar out of " +
+ view.getClass().getSimpleName());
+ }
+ }
+
public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
if (hideOnContentScroll != mHideOnContentScroll) {
mHideOnContentScroll = hideOnContentScroll;
@@ -648,9 +660,9 @@
final int action = event.getAction();
// Collapse any expanded action views.
- if (mActionBarView != null && mActionBarView.hasExpandedActionView()) {
+ if (mDecorToolbar != null && mDecorToolbar.hasExpandedActionView()) {
if (action == KeyEvent.ACTION_UP) {
- mActionBarView.collapseActionView();
+ mDecorToolbar.collapseActionView();
}
return true;
}
@@ -662,19 +674,19 @@
@Override
public void setWindowCallback(Window.Callback cb) {
pullChildren();
- mActionBarView.setWindowCallback(cb);
+ mDecorToolbar.setWindowCallback(cb);
}
@Override
public void setWindowTitle(CharSequence title) {
pullChildren();
- mActionBarView.setWindowTitle(title);
+ mDecorToolbar.setWindowTitle(title);
}
@Override
public CharSequence getTitle() {
pullChildren();
- return mActionBarView.getTitle();
+ return mDecorToolbar.getTitle();
}
@Override
@@ -682,10 +694,10 @@
pullChildren();
switch (windowFeature) {
case Window.FEATURE_PROGRESS:
- mActionBarView.initProgress();
+ mDecorToolbar.initProgress();
break;
case Window.FEATURE_INDETERMINATE_PROGRESS:
- mActionBarView.initIndeterminateProgress();
+ mDecorToolbar.initIndeterminateProgress();
break;
case Window.FEATURE_ACTION_BAR_OVERLAY:
setOverlayMode(true);
@@ -704,15 +716,15 @@
}
if (splitActionBar) {
pullChildren();
- if (mActionBarBottom != null) {
- mActionBarView.setSplitView(mActionBarBottom);
- mActionBarView.setSplitActionBar(splitActionBar);
- mActionBarView.setSplitWhenNarrow(splitWhenNarrow);
+ if (mActionBarBottom != null && mDecorToolbar.canSplit()) {
+ mDecorToolbar.setSplitView(mActionBarBottom);
+ mDecorToolbar.setSplitToolbar(splitActionBar);
+ mDecorToolbar.setSplitWhenNarrow(splitWhenNarrow);
final ActionBarContextView cab = (ActionBarContextView) findViewById(
com.android.internal.R.id.action_context_bar);
cab.setSplitView(mActionBarBottom);
- cab.setSplitActionBar(splitActionBar);
+ cab.setSplitToolbar(splitActionBar);
cab.setSplitWhenNarrow(splitWhenNarrow);
} else if (splitActionBar) {
Log.e(TAG, "Requested split action bar with " +
@@ -724,91 +736,91 @@
@Override
public boolean hasIcon() {
pullChildren();
- return mActionBarView.hasIcon();
+ return mDecorToolbar.hasIcon();
}
@Override
public boolean hasLogo() {
pullChildren();
- return mActionBarView.hasLogo();
+ return mDecorToolbar.hasLogo();
}
@Override
public void setIcon(int resId) {
pullChildren();
- mActionBarView.setIcon(resId);
+ mDecorToolbar.setIcon(resId);
}
@Override
public void setIcon(Drawable d) {
pullChildren();
- mActionBarView.setIcon(d);
+ mDecorToolbar.setIcon(d);
}
@Override
public void setLogo(int resId) {
pullChildren();
- mActionBarView.setLogo(resId);
+ mDecorToolbar.setLogo(resId);
}
@Override
public boolean canShowOverflowMenu() {
pullChildren();
- return mActionBarView.isOverflowReserved() && mActionBarView.getVisibility() == VISIBLE;
+ return mDecorToolbar.canShowOverflowMenu();
}
@Override
public boolean isOverflowMenuShowing() {
pullChildren();
- return mActionBarView.isOverflowMenuShowing();
+ return mDecorToolbar.isOverflowMenuShowing();
}
@Override
public boolean isOverflowMenuShowPending() {
pullChildren();
- return mActionBarView.isOverflowMenuShowPending();
+ return mDecorToolbar.isOverflowMenuShowPending();
}
@Override
public boolean showOverflowMenu() {
pullChildren();
- return mActionBarView.showOverflowMenu();
+ return mDecorToolbar.showOverflowMenu();
}
@Override
public boolean hideOverflowMenu() {
pullChildren();
- return mActionBarView.hideOverflowMenu();
+ return mDecorToolbar.hideOverflowMenu();
}
@Override
public void setMenuPrepared() {
pullChildren();
- mActionBarView.setMenuPrepared();
+ mDecorToolbar.setMenuPrepared();
}
@Override
public void setMenu(Menu menu, MenuPresenter.Callback cb) {
pullChildren();
- mActionBarView.setMenu(menu, cb);
+ mDecorToolbar.setMenu(menu, cb);
}
@Override
public void saveToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
pullChildren();
- mActionBarView.saveHierarchyState(toolbarStates);
+ mDecorToolbar.saveHierarchyState(toolbarStates);
}
@Override
public void restoreToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
pullChildren();
- mActionBarView.restoreHierarchyState(toolbarStates);
+ mDecorToolbar.restoreHierarchyState(toolbarStates);
}
@Override
public void dismissPopups() {
pullChildren();
- mActionBarView.dismissPopupMenus();
+ mDecorToolbar.dismissPopupMenus();
}
public static class LayoutParams extends MarginLayoutParams {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 60631b9..af82778 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -18,7 +18,6 @@
import android.animation.LayoutTransition;
import android.app.ActionBar;
-import android.app.ActionBar.OnNavigationListener;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -63,7 +62,7 @@
/**
* @hide
*/
-public class ActionBarView extends AbsActionBarView {
+public class ActionBarView extends AbsActionBarView implements DecorToolbar {
private static final String TAG = "ActionBarView";
/**
@@ -117,8 +116,7 @@
private boolean mUserTitle;
private boolean mIncludeTabs;
- private boolean mIsCollapsable;
- private boolean mIsCollapsed;
+ private boolean mIsCollapsible;
private boolean mWasHomeEnabled; // Was it enabled before action view expansion?
private MenuBuilder mOptionsMenu;
@@ -129,7 +127,7 @@
private ActionMenuItem mLogoNavItem;
private SpinnerAdapter mSpinnerAdapter;
- private OnNavigationListener mCallback;
+ private AdapterView.OnItemSelectedListener mNavItemSelectedListener;
private Runnable mTabSelector;
@@ -138,18 +136,6 @@
Window.Callback mWindowCallback;
- private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
- new AdapterView.OnItemSelectedListener() {
- public void onItemSelected(AdapterView parent, View view, int position, long id) {
- if (mCallback != null) {
- mCallback.onNavigationItemSelected(position, id);
- }
- }
- public void onNothingSelected(AdapterView parent) {
- // Do nothing
- }
- };
-
private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
@Override
public void onClick(View v) {
@@ -178,8 +164,6 @@
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
com.android.internal.R.attr.actionBarStyle, 0);
- ApplicationInfo appInfo = context.getApplicationInfo();
- PackageManager pm = context.getPackageManager();
mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
ActionBar.NAVIGATION_MODE_STANDARD);
mTitle = a.getText(R.styleable.ActionBar_title);
@@ -260,7 +244,7 @@
}
if (mHomeDescriptionRes != 0) {
- setHomeActionContentDescription(mHomeDescriptionRes);
+ setNavigationContentDescription(mHomeDescriptionRes);
}
if (mTabScrollView != null && mIncludeTabs) {
@@ -313,7 +297,7 @@
}
@Override
- public void setSplitActionBar(boolean splitActionBar) {
+ public void setSplitToolbar(boolean splitActionBar) {
if (mSplitActionBar != splitActionBar) {
if (mMenuView != null) {
final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
@@ -349,18 +333,26 @@
mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
}
}
- super.setSplitActionBar(splitActionBar);
+ super.setSplitToolbar(splitActionBar);
}
}
- public boolean isSplitActionBar() {
+ public boolean isSplit() {
return mSplitActionBar;
}
+ public boolean canSplit() {
+ return true;
+ }
+
public boolean hasEmbeddedTabs() {
return mIncludeTabs;
}
+ public void setEmbeddedTabView(View view) {
+ setEmbeddedTabView((ScrollingTabContainerView) view);
+ }
+
public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
if (mTabScrollView != null) {
removeView(mTabScrollView);
@@ -376,10 +368,6 @@
}
}
- public void setCallback(OnNavigationListener callback) {
- mCallback = callback;
- }
-
public void setMenuPrepared() {
mMenuPrepared = true;
}
@@ -473,7 +461,7 @@
}
}
- public void setCustomNavigationView(View view) {
+ public void setCustomView(View view) {
final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
if (showCustom) {
ActionBarTransition.beginDelayedTransition(this);
@@ -765,15 +753,16 @@
}
}
- public void setDropdownAdapter(SpinnerAdapter adapter) {
+ public void setDropdownParams(SpinnerAdapter adapter, AdapterView.OnItemSelectedListener l) {
mSpinnerAdapter = adapter;
+ mNavItemSelectedListener = l;
if (mSpinner != null) {
mSpinner.setAdapter(adapter);
}
}
- public SpinnerAdapter getDropdownAdapter() {
- return mSpinnerAdapter;
+ public int getDropdownItemCount() {
+ return mSpinnerAdapter != null ? mSpinnerAdapter.getCount() : 0;
}
public void setDropdownSelectedPosition(int position) {
@@ -784,7 +773,7 @@
return mSpinner.getSelectedItemPosition();
}
- public View getCustomNavigationView() {
+ public View getCustomView() {
return mCustomNavView;
}
@@ -797,6 +786,11 @@
}
@Override
+ public ViewGroup getViewGroup() {
+ return this;
+ }
+
+ @Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
// Used by custom nav views if they don't supply layout params. Everything else
// added to an ActionBarView should have them already.
@@ -860,12 +854,8 @@
mContextView = view;
}
- public void setCollapsable(boolean collapsable) {
- mIsCollapsable = collapsable;
- }
-
- public boolean isCollapsed() {
- return mIsCollapsed;
+ public void setCollapsible(boolean collapsible) {
+ mIsCollapsible = collapsible;
}
/**
@@ -893,7 +883,7 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int childCount = getChildCount();
- if (mIsCollapsable) {
+ if (mIsCollapsible) {
int visibleChildren = 0;
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
@@ -915,11 +905,9 @@
if (visibleChildren == 0) {
// No size for an empty action bar when collapsable.
setMeasuredDimension(0, 0);
- mIsCollapsed = true;
return;
}
}
- mIsCollapsed = false;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
@@ -1323,20 +1311,20 @@
}
}
- public void setHomeAsUpIndicator(Drawable indicator) {
+ public void setNavigationIcon(Drawable indicator) {
mHomeLayout.setUpIndicator(indicator);
}
- public void setHomeAsUpIndicator(int resId) {
+ public void setNavigationIcon(int resId) {
mHomeLayout.setUpIndicator(resId);
}
- public void setHomeActionContentDescription(CharSequence description) {
+ public void setNavigationContentDescription(CharSequence description) {
mHomeDescription = description;
updateHomeAccessibility(mUpGoerFive.isEnabled());
}
- public void setHomeActionContentDescription(int resId) {
+ public void setNavigationContentDescription(int resId) {
mHomeDescriptionRes = resId;
mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
updateHomeAccessibility(mUpGoerFive.isEnabled());
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
new file mode 100644
index 0000000..ee6988e
--- /dev/null
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -0,0 +1,94 @@
+/*
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
+import android.util.SparseArray;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.SpinnerAdapter;
+import com.android.internal.view.menu.MenuPresenter;
+
+/**
+ * Common interface for a toolbar that sits as part of the window decor.
+ * Layouts that control window decor use this as a point of interaction with different
+ * bar implementations.
+ *
+ * @hide
+ */
+public interface DecorToolbar {
+ ViewGroup getViewGroup();
+ Context getContext();
+ boolean isSplit();
+ boolean hasExpandedActionView();
+ void collapseActionView();
+ void setWindowCallback(Window.Callback cb);
+ void setWindowTitle(CharSequence title);
+ CharSequence getTitle();
+ void setTitle(CharSequence title);
+ CharSequence getSubtitle();
+ void setSubtitle(CharSequence subtitle);
+ void initProgress();
+ void initIndeterminateProgress();
+ boolean canSplit();
+ void setSplitView(ViewGroup splitView);
+ void setSplitToolbar(boolean split);
+ void setSplitWhenNarrow(boolean splitWhenNarrow);
+ boolean hasIcon();
+ boolean hasLogo();
+ void setIcon(int resId);
+ void setIcon(Drawable d);
+ void setLogo(int resId);
+ void setLogo(Drawable d);
+ boolean canShowOverflowMenu();
+ boolean isOverflowMenuShowing();
+ boolean isOverflowMenuShowPending();
+ boolean showOverflowMenu();
+ boolean hideOverflowMenu();
+ void setMenuPrepared();
+ void setMenu(Menu menu, MenuPresenter.Callback cb);
+ void dismissPopupMenus();
+
+ int getDisplayOptions();
+ void setDisplayOptions(int opts);
+ void setEmbeddedTabView(View tabView);
+ boolean hasEmbeddedTabs();
+ boolean isTitleTruncated();
+ void setCollapsible(boolean collapsible);
+ void setHomeButtonEnabled(boolean enable);
+ int getNavigationMode();
+ void setNavigationMode(int mode);
+ void setDropdownParams(SpinnerAdapter adapter, AdapterView.OnItemSelectedListener listener);
+ void setDropdownSelectedPosition(int position);
+ int getDropdownSelectedPosition();
+ int getDropdownItemCount();
+ void setCustomView(View view);
+ View getCustomView();
+ void animateToVisibility(int visibility);
+ void setNavigationIcon(Drawable icon);
+ void setNavigationIcon(int resId);
+ void setNavigationContentDescription(CharSequence description);
+ void setNavigationContentDescription(int resId);
+ void saveHierarchyState(SparseArray<Parcelable> toolbarStates);
+ void restoreHierarchyState(SparseArray<Parcelable> toolbarStates);
+}
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
new file mode 100644
index 0000000..f90aaea
--- /dev/null
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -0,0 +1,526 @@
+/*
+ * 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.internal.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.ActionBar;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.ActionMenuPresenter;
+import android.widget.AdapterView;
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+import android.widget.Toolbar;
+import com.android.internal.R;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuPresenter;
+
+/**
+ * Internal class used to interact with the Toolbar widget without
+ * exposing interface methods to the public API.
+ *
+ * <p>ToolbarWidgetWrapper manages the differences between Toolbar and ActionBarView
+ * so that either variant acting as a
+ * {@link com.android.internal.app.WindowDecorActionBar WindowDecorActionBar} can behave
+ * in the same way.</p>
+ *
+ * @hide
+ */
+public class ToolbarWidgetWrapper implements DecorToolbar {
+ private static final String TAG = "ToolbarWidgetWrapper";
+
+ private static final int AFFECTS_LOGO_MASK =
+ ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO;
+
+ private Toolbar mToolbar;
+
+ private int mDisplayOpts;
+ private View mTabView;
+ private Spinner mSpinner;
+ private View mCustomView;
+
+ private Drawable mIcon;
+ private Drawable mLogo;
+ private Drawable mNavIcon;
+
+ private boolean mTitleSet;
+ private CharSequence mTitle;
+ private CharSequence mSubtitle;
+
+ private Window.Callback mWindowCallback;
+ private boolean mMenuPrepared;
+ private ActionMenuPresenter mActionMenuPresenter;
+
+ public ToolbarWidgetWrapper(Toolbar toolbar) {
+ mToolbar = toolbar;
+
+ final TypedArray a = toolbar.getContext().obtainStyledAttributes(null,
+ R.styleable.ActionBar, R.attr.actionBarStyle, 0);
+
+ final CharSequence title = a.getText(R.styleable.ActionBar_title);
+ if (title != null) {
+ setTitle(title);
+ }
+
+ final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle);
+ if (subtitle != null) {
+ setSubtitle(subtitle);
+ }
+
+ final Drawable logo = a.getDrawable(R.styleable.ActionBar_logo);
+ if (logo != null) {
+ setLogo(logo);
+ }
+
+ final Drawable icon = a.getDrawable(R.styleable.ActionBar_icon);
+ if (icon != null) {
+ setIcon(icon);
+ }
+
+ final Drawable navIcon = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator);
+ if (navIcon != null) {
+ setNavigationIcon(navIcon);
+ }
+
+ setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, 0));
+
+ final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
+ if (customNavId != 0) {
+ setCustomView(LayoutInflater.from(mToolbar.getContext()).inflate(customNavId,
+ mToolbar, false));
+ setDisplayOptions(mDisplayOpts | ActionBar.DISPLAY_SHOW_CUSTOM);
+ }
+
+ final int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
+ if (height > 0) {
+ final ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();
+ lp.height = height;
+ mToolbar.setLayoutParams(lp);
+ }
+
+ final int contentInsetStart = a.getDimensionPixelOffset(
+ R.styleable.ActionBar_contentInsetStart, 0);
+ final int contentInsetEnd = a.getDimensionPixelOffset(
+ R.styleable.ActionBar_contentInsetEnd, 0);
+ if (contentInsetStart > 0 || contentInsetEnd > 0) {
+ mToolbar.setContentInsetsRelative(contentInsetStart, contentInsetEnd);
+ }
+
+ a.recycle();
+
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
+ 0, android.R.id.home, 0, 0, mTitle);
+ @Override
+ public void onClick(View v) {
+ if (mWindowCallback != null && mMenuPrepared) {
+ mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mNavItem);
+ }
+ }
+ });
+ }
+
+ @Override
+ public ViewGroup getViewGroup() {
+ return mToolbar;
+ }
+
+ @Override
+ public Context getContext() {
+ return mToolbar.getContext();
+ }
+
+ @Override
+ public boolean isSplit() {
+ return false;
+ }
+
+ @Override
+ public boolean hasExpandedActionView() {
+ return mToolbar.hasExpandedActionView();
+ }
+
+ @Override
+ public void collapseActionView() {
+ mToolbar.collapseActionView();
+ }
+
+ @Override
+ public void setWindowCallback(Window.Callback cb) {
+ mWindowCallback = cb;
+ }
+
+ @Override
+ public void setWindowTitle(CharSequence title) {
+ // "Real" title always trumps window title.
+ if (!mTitleSet) {
+ setTitleInt(title);
+ }
+ }
+
+ @Override
+ public CharSequence getTitle() {
+ return mToolbar.getTitle();
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {
+ mTitleSet = true;
+ setTitleInt(title);
+ }
+
+ private void setTitleInt(CharSequence title) {
+ mTitle = title;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setTitle(title);
+ }
+ }
+
+ @Override
+ public CharSequence getSubtitle() {
+ return mToolbar.getSubtitle();
+ }
+
+ @Override
+ public void setSubtitle(CharSequence subtitle) {
+ mSubtitle = subtitle;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setSubtitle(subtitle);
+ }
+ }
+
+ @Override
+ public void initProgress() {
+ Log.i(TAG, "Progress display unsupported");
+ }
+
+ @Override
+ public void initIndeterminateProgress() {
+ Log.i(TAG, "Progress display unsupported");
+ }
+
+ @Override
+ public boolean canSplit() {
+ return false;
+ }
+
+ @Override
+ public void setSplitView(ViewGroup splitView) {
+ }
+
+ @Override
+ public void setSplitToolbar(boolean split) {
+ if (split) {
+ throw new UnsupportedOperationException("Cannot split an android.widget.Toolbar");
+ }
+ }
+
+ @Override
+ public void setSplitWhenNarrow(boolean splitWhenNarrow) {
+ // Ignore.
+ }
+
+ @Override
+ public boolean hasIcon() {
+ return mIcon != null;
+ }
+
+ @Override
+ public boolean hasLogo() {
+ return mLogo != null;
+ }
+
+ @Override
+ public void setIcon(int resId) {
+ setIcon(resId != 0 ? getContext().getDrawable(resId) : null);
+ }
+
+ @Override
+ public void setIcon(Drawable d) {
+ mIcon = d;
+ updateToolbarLogo();
+ }
+
+ @Override
+ public void setLogo(int resId) {
+ setLogo(resId != 0 ? getContext().getDrawable(resId) : null);
+ }
+
+ @Override
+ public void setLogo(Drawable d) {
+ mLogo = d;
+ updateToolbarLogo();
+ }
+
+ private void updateToolbarLogo() {
+ Drawable logo = null;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_HOME) != 0) {
+ if ((mDisplayOpts & ActionBar.DISPLAY_USE_LOGO) != 0) {
+ logo = mLogo != null ? mLogo : mIcon;
+ } else {
+ logo = mIcon;
+ }
+ }
+ mToolbar.setLogo(logo);
+ }
+
+ @Override
+ public boolean canShowOverflowMenu() {
+ return mToolbar.canShowOverflowMenu();
+ }
+
+ @Override
+ public boolean isOverflowMenuShowing() {
+ return mToolbar.isOverflowMenuShowing();
+ }
+
+ @Override
+ public boolean isOverflowMenuShowPending() {
+ return mToolbar.isOverflowMenuShowPending();
+ }
+
+ @Override
+ public boolean showOverflowMenu() {
+ return mToolbar.showOverflowMenu();
+ }
+
+ @Override
+ public boolean hideOverflowMenu() {
+ return mToolbar.hideOverflowMenu();
+ }
+
+ @Override
+ public void setMenuPrepared() {
+ mMenuPrepared = true;
+ }
+
+ @Override
+ public void setMenu(Menu menu, MenuPresenter.Callback cb) {
+ if (mActionMenuPresenter == null) {
+ mActionMenuPresenter = new ActionMenuPresenter(mToolbar.getContext());
+ mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
+ }
+ mActionMenuPresenter.setCallback(cb);
+ mToolbar.setMenu((MenuBuilder) menu, mActionMenuPresenter);
+ }
+
+ @Override
+ public void dismissPopupMenus() {
+ mToolbar.dismissPopupMenus();
+ }
+
+ @Override
+ public int getDisplayOptions() {
+ return mDisplayOpts;
+ }
+
+ @Override
+ public void setDisplayOptions(int newOpts) {
+ final int oldOpts = mDisplayOpts;
+ final int changed = oldOpts ^ newOpts;
+ mDisplayOpts = newOpts;
+ if (changed != 0) {
+ if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ mToolbar.setNavigationIcon(mNavIcon);
+ } else {
+ mToolbar.setNavigationIcon(null);
+ }
+ }
+
+ if ((changed & AFFECTS_LOGO_MASK) != 0) {
+ updateToolbarLogo();
+ }
+
+ if ((changed & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ if ((newOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setTitle(mTitle);
+ mToolbar.setSubtitle(mSubtitle);
+ } else {
+ mToolbar.setTitle(null);
+ mToolbar.setSubtitle(null);
+ }
+ }
+
+ if ((changed & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomView != null) {
+ if ((newOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.addView(mCustomView);
+ } else {
+ mToolbar.removeView(mCustomView);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setEmbeddedTabView(View tabView) {
+ mTabView = tabView;
+ }
+
+ @Override
+ public boolean hasEmbeddedTabs() {
+ return mTabView != null;
+ }
+
+ @Override
+ public boolean isTitleTruncated() {
+ return mToolbar.isTitleTruncated();
+ }
+
+ @Override
+ public void setCollapsible(boolean collapsible) {
+ // Ignore
+ }
+
+ @Override
+ public void setHomeButtonEnabled(boolean enable) {
+ // Ignore
+ }
+
+ @Override
+ public int getNavigationMode() {
+ return 0;
+ }
+
+ @Override
+ public void setNavigationMode(int mode) {
+ if (mode != ActionBar.NAVIGATION_MODE_STANDARD) {
+ throw new IllegalArgumentException(
+ "Navigation modes not supported in this configuration");
+ }
+ }
+
+ @Override
+ public void setDropdownParams(SpinnerAdapter adapter,
+ AdapterView.OnItemSelectedListener listener) {
+ if (mSpinner == null) {
+ mSpinner = new Spinner(getContext());
+ }
+ mSpinner.setAdapter(adapter);
+ mSpinner.setOnItemSelectedListener(listener);
+ }
+
+ @Override
+ public void setDropdownSelectedPosition(int position) {
+ if (mSpinner == null) {
+ throw new IllegalStateException(
+ "Can't set dropdown selected position without an adapter");
+ }
+ mSpinner.setSelection(position);
+ }
+
+ @Override
+ public int getDropdownSelectedPosition() {
+ return mSpinner != null ? mSpinner.getSelectedItemPosition() : 0;
+ }
+
+ @Override
+ public int getDropdownItemCount() {
+ return mSpinner != null ? mSpinner.getCount() : 0;
+ }
+
+ @Override
+ public void setCustomView(View view) {
+ if (mCustomView != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.removeView(mCustomView);
+ }
+ mCustomView = view;
+ if (view != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.addView(mCustomView);
+ }
+ }
+
+ @Override
+ public View getCustomView() {
+ return mCustomView;
+ }
+
+ @Override
+ public void animateToVisibility(int visibility) {
+ if (visibility == View.GONE) {
+ mToolbar.animate().translationY(mToolbar.getHeight()).alpha(0)
+ .setListener(new AnimatorListenerAdapter() {
+ private boolean mCanceled = false;
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCanceled) {
+ mToolbar.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCanceled = true;
+ }
+ });
+ } else if (visibility == View.VISIBLE) {
+ mToolbar.animate().translationY(0).alpha(1)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mToolbar.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void setNavigationIcon(Drawable icon) {
+ mNavIcon = icon;
+ if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ mToolbar.setNavigationIcon(icon);
+ }
+ }
+
+ @Override
+ public void setNavigationIcon(int resId) {
+ setNavigationIcon(mToolbar.getContext().getDrawable(resId));
+ }
+
+ @Override
+ public void setNavigationContentDescription(CharSequence description) {
+ mToolbar.setNavigationContentDescription(description);
+ }
+
+ @Override
+ public void setNavigationContentDescription(int resId) {
+ mToolbar.setNavigationContentDescription(resId);
+ }
+
+ @Override
+ public void saveHierarchyState(SparseArray<Parcelable> toolbarStates) {
+ mToolbar.saveHierarchyState(toolbarStates);
+ }
+
+ @Override
+ public void restoreHierarchyState(SparseArray<Parcelable> toolbarStates) {
+ mToolbar.restoreHierarchyState(toolbarStates);
+ }
+
+}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 0c7eefa..e069876 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -789,7 +789,7 @@
}
// libart tolerates libdvm flags, but not vice versa, so only pass some options if libart.
- property_get("persist.sys.dalvik.vm.lib.1", dalvikVmLibBuf, "libdvm.so");
+ property_get("persist.sys.dalvik.vm.lib.2", dalvikVmLibBuf, "libart.so");
bool libart = (strncmp(dalvikVmLibBuf, "libart", 6) == 0);
if (libart) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5a935a9..4594cc3 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -61,6 +61,13 @@
jfieldID secure;
} gPhysicalDisplayInfoClassInfo;
+static struct {
+ jfieldID bottom;
+ jfieldID left;
+ jfieldID right;
+ jfieldID top;
+} gRectClassInfo;
+
// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
void DeleteScreenshot(void* addr, void* context) {
SkASSERT(addr == ((ScreenshotClient*) context)->getPixels());
@@ -104,25 +111,32 @@
ctrl->decStrong((void *)nativeCreate);
}
-static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
- bool useIdentityTransform) {
+static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
+ jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
+ jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken == NULL) {
return NULL;
}
+ int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);
+ int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);
+ int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);
+ int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);
+ Rect sourceCrop(left, top, right, bottom);
+
ScreenshotClient* screenshot = new ScreenshotClient();
status_t res;
if (width > 0 && height > 0) {
if (allLayers) {
- res = screenshot->update(displayToken, width, height, useIdentityTransform);
- } else {
- res = screenshot->update(displayToken, width, height, minLayer, maxLayer,
+ res = screenshot->update(displayToken, sourceCrop, width, height,
useIdentityTransform);
+ } else {
+ res = screenshot->update(displayToken, sourceCrop, width, height,
+ minLayer, maxLayer, useIdentityTransform);
}
} else {
- res = screenshot->update(displayToken, useIdentityTransform);
+ res = screenshot->update(displayToken, sourceCrop, useIdentityTransform);
}
if (res != NO_ERROR) {
delete screenshot;
@@ -174,20 +188,25 @@
GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
}
-static void nativeScreenshot(JNIEnv* env, jclass clazz,
- jobject displayTokenObj, jobject surfaceObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
- bool useIdentityTransform) {
+static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
+ jobject surfaceObj, jobject sourceCropObj, jint width, jint height,
+ jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken != NULL) {
sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
if (consumer != NULL) {
+ int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);
+ int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);
+ int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);
+ int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);
+ Rect sourceCrop(left, top, right, bottom);
+
if (allLayers) {
minLayer = 0;
maxLayer = -1;
}
- ScreenshotClient::capture(
- displayToken, consumer->getIGraphicBufferProducer(),
+ ScreenshotClient::capture(displayToken,
+ consumer->getIGraphicBufferProducer(), sourceCrop,
width, height, uint32_t(minLayer), uint32_t(maxLayer),
useIdentityTransform);
}
@@ -563,9 +582,9 @@
(void*)nativeRelease },
{"nativeDestroy", "(J)V",
(void*)nativeDestroy },
- {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;",
(void*)nativeScreenshotBitmap },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
(void*)nativeScreenshot },
{"nativeOpenTransaction", "()V",
(void*)nativeOpenTransaction },
@@ -640,6 +659,12 @@
gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F");
gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z");
+ jclass rectClazz = env->FindClass("android/graphics/Rect");
+ gRectClassInfo.bottom = env->GetFieldID(rectClazz, "bottom", "I");
+ gRectClassInfo.left = env->GetFieldID(rectClazz, "left", "I");
+ gRectClassInfo.right = env->GetFieldID(rectClazz, "right", "I");
+ gRectClassInfo.top = env->GetFieldID(rectClazz, "top", "I");
+
jclass frameStatsClazz = env->FindClass("android/view/FrameStats");
jfieldID undefined_time_nano_field = env->GetStaticFieldID(frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 5bc0f62..6f256f0 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -293,6 +293,12 @@
proxy->destroyLayer(layer);
}
+static void android_view_ThreadedRenderer_flushCaches(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jint flushMode) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->flushCaches(static_cast<Caches::FlushMode>(flushMode));
+}
+
static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -334,6 +340,7 @@
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
{ "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
{ "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer },
+ { "nFlushCaches", "(JI)V", (void*) android_view_ThreadedRenderer_flushCaches },
{ "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
{ "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
#endif
diff --git a/core/res/res/anim/input_method_exit.xml b/core/res/res/anim/input_method_exit.xml
index e87352f2a..4c4f6a4 100644
--- a/core/res/res/anim/input_method_exit.xml
+++ b/core/res/res/anim/input_method_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/fade_out.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, 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.
@@ -19,7 +17,7 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <translate android:fromYDelta="0" android:toYDelta="10%"
+ <translate android:fromYDelta="0" android:toYDelta="-20%"
android:interpolator="@interpolator/accelerate_quint"
android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index cb47b3c..4a956d7 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -20,9 +20,8 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false">
<alpha
- android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:fromAlpha="1.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="@android:integer/config_shortAnimTime"
- android:duration="@android:integer/config_shortAnimTime"/>
+ android:duration="0"/>
</set>
\ No newline at end of file
diff --git a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
index c29fd1a..f7a6a65 100644
--- a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
@@ -23,6 +23,6 @@
android:fromAlpha="0.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="@android:integer/config_shortAnimTime"
+ android:startOffset="@android:integer/config_mediumAnimTime"
android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/voice_activity_close_enter.xml b/core/res/res/anim/voice_activity_close_enter.xml
new file mode 100644
index 0000000..4f3d3d5
--- /dev/null
+++ b/core/res/res/anim/voice_activity_close_enter.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+ android:interpolator="@interpolator/accelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/anim/voice_activity_close_exit.xml b/core/res/res/anim/voice_activity_close_exit.xml
new file mode 100644
index 0000000..023b012
--- /dev/null
+++ b/core/res/res/anim/voice_activity_close_exit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="0" android:toYDelta="-20%"
+ android:interpolator="@interpolator/accelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:interpolator="@interpolator/accelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/anim/voice_activity_open_enter.xml b/core/res/res/anim/voice_activity_open_enter.xml
new file mode 100644
index 0000000..57fba2a
--- /dev/null
+++ b/core/res/res/anim/voice_activity_open_enter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_in.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="-20%" android:toYDelta="0"
+ android:interpolator="@interpolator/decelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/core/res/res/anim/voice_activity_open_exit.xml b/core/res/res/anim/voice_activity_open_exit.xml
new file mode 100644
index 0000000..4f3d3d5
--- /dev/null
+++ b/core/res/res/anim/voice_activity_open_exit.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+ android:interpolator="@interpolator/accelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/anim/voice_layer_enter.xml b/core/res/res/anim/voice_layer_enter.xml
new file mode 100644
index 0000000..57fba2a
--- /dev/null
+++ b/core/res/res/anim/voice_layer_enter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_in.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="-20%" android:toYDelta="0"
+ android:interpolator="@interpolator/decelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/core/res/res/anim/voice_layer_exit.xml b/core/res/res/anim/voice_layer_exit.xml
new file mode 100644
index 0000000..023b012
--- /dev/null
+++ b/core/res/res/anim/voice_layer_exit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="0" android:toYDelta="-20%"
+ android:interpolator="@interpolator/accelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:interpolator="@interpolator/accelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
new file mode 100644
index 0000000..290c7da
--- /dev/null
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+
+<!--
+This is an optimized layout for a screen with a toolbar enabled.
+-->
+
+<com.android.internal.widget.ActionBarOverlayLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/decor_content_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:splitMotionEvents="false"
+ android:theme="?attr/actionBarTheme">
+ <FrameLayout android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <com.android.internal.widget.ActionBarContainer
+ android:id="@+id/action_bar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ style="?attr/actionBarStyle"
+ android:viewName="android:action_bar"
+ android:gravity="top">
+ <Toolbar
+ android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?attr/toolbarStyle" />
+ <com.android.internal.widget.ActionBarContextView
+ android:id="@+id/action_context_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?attr/actionModeStyle" />
+ </com.android.internal.widget.ActionBarContainer>
+</com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a7cd9a7..3d043c4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -294,7 +294,7 @@
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"recevoir des messages texte (WAP)"</string>
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"récupérer les applications en cours d\'exécution"</string>
- <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet à l\'application de récupérer des informations sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible de d\'obtenir des informations sur les applications utilisées sur l\'appareil."</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet à l\'application de récupérer des informations sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des informations sur les applications utilisées sur l\'appareil."</string>
<string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interagir entre les utilisateurs"</string>
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet à l\'application d\'effectuer des actions entre les différents utilisateurs de l\'appareil. Les applications malveillantes peuvent utiliser cette autorisation pour passer outre la protection entre les utilisateurs."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"autorisation totale d\'interagir entre les utilisateurs"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index dbe2d7f..f3b8495 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -68,7 +68,7 @@
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
<string name="ClirMmi" msgid="7784673673446833091">"លេខសម្គាល់អ្នកហៅចេញ"</string>
<string name="CfMmi" msgid="5123218989141573515">"បញ្ជូនការហៅបន្ត"</string>
<string name="CwMmi" msgid="9129678056795016867">"រង់ចាំការហៅ"</string>
@@ -125,7 +125,7 @@
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិនបានបញ្ជូនបន្ត"</string>
<string name="fcComplete" msgid="3118848230966886575">"កូដលក្ខណៈពេញលេញ។"</string>
<string name="fcError" msgid="3327560126588500777">"បញ្ហាការតភ្ជាប់ ឬកូដលក្ខណៈមិនត្រឹមត្រូវ។"</string>
- <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
+ <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
<string name="httpError" msgid="7956392511146698522">"មានកំហុសបណ្ដាញ។"</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"រកមិនឃើញ URL ។"</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"គ្រោងការណ៍ផ្ទៀងផ្ទាត់តំបន់បណ្ដាញមិនត្រូវបានគាំទ្រ។"</string>
@@ -183,7 +183,7 @@
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើកសំឡេង"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"ពេលជិះយន្តហោះ"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"បានបើករបៀបពេលជិះយន្តហោះ"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"ការកំណត់"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string>
@@ -195,7 +195,7 @@
<string name="permgrouplab_messages" msgid="7521249148445456662">"សាររបស់អ្នក"</string>
<string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និងសរសេរសារ SMS, អ៊ីមែល និងសារផ្សេងៗទៀតរបស់អ្នក។"</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នក"</string>
- <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
+ <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មានសង្គមរបស់អ្នក"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីទំនាក់ទំនង និងការភ្ជាប់សង្គមរបស់អ្នក។"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំងរបស់អ្នក"</string>
@@ -384,7 +384,7 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យកម្មវិធីមើលគ្រាប់ចុចដែលអ្នកចុចពេលមានអន្តរកម្មជាមួយកម្មវិធីផ្សេង (ដូចជា បញ្ចូលពាក្យសម្ងាត់)។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចងទៅវិធីសាស្ត្របញ្ចូល"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃវិធីសាស្ត្របញ្ចូល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មភាពងាយស្រួល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ចងសេវាកម្មបោះពុម្ព"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -402,7 +402,7 @@
<string name="permdesc_bindVoiceInteraction" msgid="2345721766501778101">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលរបស់សេវាកម្មអន្តរកម្មសំឡេង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់ទៅការបង្ហាញពីចម្ងាយ"</string>
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃការបង្ហាញពីចម្ងាយ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ភ្ជាប់ទៅសេវាកម្មក្រុមហ៊ុនផ្ដល់ច្រក"</string>
<string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅក្រុមហ៊ុនផ្ដល់ច្រកដែលបានចុះឈ្មោះ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -410,7 +410,7 @@
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យម្ចាស់ផ្ញើគោលបំណងទៅអ្នកគ្រប់គ្រងឧបករណ៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ភ្ជាប់ទៅការបញ្ចូលទូរទស្សន៍"</string>
<string name="permdesc_bindTvInput" msgid="2371008331852001924">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតខ្ពស់នៃការបញ្ចូលទូរទស្សន៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
+ <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
<string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាតឲ្យម្ចាស់បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍សកម្មចេញ។ មិនគួរប្រើសម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរទិសអេក្រង់"</string>
<string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យកម្មវិធីប្ដូរការបង្វិលអេក្រង់នៅពេលណាមួយ។ មិនចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -422,9 +422,9 @@
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ឲ្យកម្មវិធីស្នើសញ្ញាដែលបានផ្ដល់ត្រូវផ្ញើទៅដំណើរការស្ថិតស្ថេរទាំងអស់។"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើឲ្យកម្មវិធីដំណើរការជានិច្ច"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យកម្មវិធីធ្វើជាផ្នែកស្ថិតស្ថេរដោយខ្លួនឯងក្នុងអង្គចងចាំ។ វាអាចកំណត់អង្គចងចាំដែលអាចប្រើបានចំពោះកម្មវិធីផ្សេងៗ ដោយធ្វើឲ្យកុំព្យូទ័របន្ទះយឺត។"</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"លុបកម្មវិធី"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។ "</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។"</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"លុបទិន្នន័យរបស់កម្មវិធីផ្សេង"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យកម្មវិធីសម្អាតទិន្នន័យអ្នកប្រើ។"</string>
<string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុបឃ្លាំងសម្ងាត់កម្មវិធីផ្សេងៗ"</string>
@@ -475,7 +475,7 @@
<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងកុំព្យូទ័របន្ទះ រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនងជាក់លាក់។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬបានទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនាក់ជាក់លាក់។ សិទ្ធិនេះឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"អានកំណត់ហេតុហៅ"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យកម្មវិធីអានបញ្ជីហៅទូរស័ព្ទរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរបញ្ជីហៅ"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យកម្មវិធីកែបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នករួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីហៅរបស់អ្នក។"</string>
@@ -609,7 +609,7 @@
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ឲ្យកម្មវិធីកំណត់ជំនួយទំហំផ្ទាំងរូបភាពប្រព័ន្ធ។"</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"កំណត់ប្រព័ន្ធទៅលំនាំដើមរោងចក្រឡើងវិញ"</string>
<string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យកម្មវិធីកំណត់ប្រព័ន្ធដូចការកំណត់ចេញពីរោងចក្រឡើងវិញពេញលេញ ដោយលុបទិន្នន័យ ការកំណត់រចនាសម្ព័ន្ធ និងកម្មវិធីបានដំឡើង។"</string>
- <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
+ <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យកម្មវិធីប្ដូរម៉ោងកុំព្យូទ័របន្ទះ។"</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យកម្មវិធីប្ដូរម៉ោងទូរស័ព្ទ។"</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"កំណត់តំបន់ពេលវេលា"</string>
@@ -775,7 +775,7 @@
<string-array name="organizationTypes">
<item msgid="7546335612189115615">"កន្លែងធ្វើការ"</item>
<item msgid="4378074129049520373">"ផ្សេងៗ"</item>
- <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
+ <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="8595261363518459565">"AIM"</item>
@@ -791,7 +791,7 @@
<string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"ចល័ត"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែងធ្វើការ"</string>
- <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
<string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារផ្ទះ"</string>
<string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
@@ -916,7 +916,7 @@
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ដើម្បីដោះសោ ចូលគណនី Google របស់អ្នក។"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ឈ្មោះអ្នកប្រើ (អ៊ីមែល)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ចូល"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -961,7 +961,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"បានបរាជ័យក្នុងការសាកល្បងរោងចក្រ"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវបានគាំទ្រសម្រាប់តែកញ្ចប់បានដំឡើងក្នុង /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"រកមិនឃើញកញ្ចប់ដែលផ្ដល់សកម្មភាព FACTORY_TEST ។"</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"ទំព័រមានចំណងជើង \"<xliff:g id="TITLE">%s</xliff:g>\" សរសេរ៖"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"បញ្ជាក់ការរុករក"</string>
@@ -1019,7 +1019,7 @@
<string name="prepend_shortcut_label" msgid="2572214461676015642">"ម៉ឺនុយ +"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"ដកឃ្លា"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
- <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
<string name="search_go" msgid="8298016669822141719">"ស្វែងរក"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"ស្វែងរក"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"ស្វែងរកសំណួរ"</string>
@@ -1103,18 +1103,18 @@
<string name="preposition_for_date" msgid="9093949757757445117">"នៅ <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"នៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"ក្នុងឆ្នាំ <xliff:g id="YEAR">%s</xliff:g>"</string>
- <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
+ <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
<string name="days" msgid="4774547661021344602">"ថ្ងៃ"</string>
<string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
<string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
- <string name="minute" msgid="9148878657703769868">"នាទី"</string>
+ <string name="minute" msgid="9148878657703769868">"នាទី"</string>
<string name="minutes" msgid="5646001005827034509">"នាទី"</string>
- <string name="second" msgid="3184235808021478">"វិនាទី"</string>
+ <string name="second" msgid="3184235808021478">"វិនាទី"</string>
<string name="seconds" msgid="3161515347216589235">"វិនាទី"</string>
- <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
- <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
- <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
- <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
+ <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+ <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+ <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+ <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
<plurals name="duration_seconds">
<item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
<item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
@@ -1130,12 +1130,12 @@
<string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហាវីដេអូ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូនេះមិនត្រឹមត្រូវសម្រាប់ចរន្តចូលឧបករណ៍នេះ។"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិនអាចចាក់វីដេអូនេះ។"</string>
- <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
+ <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"រសៀល"</string>
<string name="Noon" msgid="3342127745230013127">"រសៀល"</string>
<string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
- <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
+ <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="6876518925844129331">"ជ្រើសទាំងអស់"</string>
@@ -1152,13 +1152,13 @@
<string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្របញ្ចូល"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាពអត្ថបទ"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់ទំហំផ្ទុក"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការ"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"ប៉ះ ដើម្បីមើលព័ត៌មានបន្ថែម ឬបញ្ឈប់កម្មវិធី។"</string>
- <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
- <string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
- <string name="yes" msgid="5362982303337969312">"យល់ព្រម"</string>
- <string name="no" msgid="5141531044935541497">"បោះបង់"</string>
+ <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
+ <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="loading" msgid="7933681260296021180">"កំពុងផ្ទុក..."</string>
<string name="capital_on" msgid="1544682755514494298">"បើក"</string>
@@ -1167,7 +1167,7 @@
<string name="whichHomeApplication" msgid="4616420172727326782">"ជ្រើសកម្មវិធីដើម"</string>
<string name="alwaysUse" msgid="4583018368000610438">"ប្រើតាមលំនាំដើមសម្រាប់សកម្មភាពនេះ។"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាតលំនាំដើមក្នុងការកំណត់ប្រព័ន្ធ > កម្មវិធី > ទាញយក។"</string>
- <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើសកម្មវិធីសម្រាប់ឧបករណ៍យូអេសប៊ី"</string>
<string name="noApplications" msgid="2991814273936504689">"គ្មានកម្មវិធីអាចអនុវត្តសកម្មភាពនេះ។"</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
@@ -1178,7 +1178,7 @@
<string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
<string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិនឆ្លើយតប។ តើអ្នកចង់បិទវា?"</string>
<string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិនឆ្លើយតប។ \n\nតើអ្នកចង់បិទវាឬ?"</string>
- <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
+ <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
<string name="report" msgid="4060218260984795706">"រាយការណ៍"</string>
<string name="wait" msgid="7147118217226317732">"រង់ចាំ"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"ទំព័រក្លាយជាមិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
@@ -1260,19 +1260,19 @@
<string name="sms_short_code_details" msgid="3492025719868078457"><font fgcolor="#ffffb060">"នេះអាចកាត់លុយ"</font>" លើគណនីចល័តរបស់អ្នក។"</string>
<string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"វានឹងគិតថ្លៃសេវាកម្មលើគណនីចល័តរបស់អ្នក។"</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ផ្ញើ"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ចងចាំជម្រើសរបស់ខ្ញុំ"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"អ្នកអាចប្ដូរវាពេលក្រោយក្នុងការកំណត់ > កម្មវិធី"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាតជានិច្ច"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"កុំអនុញ្ញាត"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"បានដកស៊ីមកាតចេញ"</string>
- <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញចល័តនឹងប្រើលែងបានរហូតដល់អ្នកចាប់ផ្ដើមជាមួយស៊ីមកាតដែលបាបញ្ចូលត្រឹមត្រូវ។"</string>
+ <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញចល័តនឹងប្រើលែងបានរហូតដល់អ្នកចាប់ផ្ដើមជាមួយស៊ីមកាតដែលបាបញ្ចូលត្រឹមត្រូវ។"</string>
<string name="sim_done_button" msgid="827949989369963775">"រួចរាល់"</string>
<string name="sim_added_title" msgid="3719670512889674693">"បានបន្ថែមស៊ីមកាត"</string>
<string name="sim_added_message" msgid="6599945301141050216">"ចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ ដើម្បីចូលដំណើរការបណ្ដាញចល័ត។"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើមឡើងវិញ"</string>
- <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
- <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
+ <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
+ <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
<string name="date_time_set" msgid="5777075614321087758">"កំណត់"</string>
<string name="date_time_done" msgid="2507683751759308828">"រួចរាល់"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"ថ្មី៖ "</font></string>
@@ -1350,7 +1350,7 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យកម្មវិធីដកសេវាកម្មនៃកម្មវិធីផ្ទុកលំនាំដើម ដើម្បីចម្លងមាតិកា។ មិនសម្រាប់ប្រើដោយកម្មវិធីលំនាំដើម។"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"នាំផ្លូវលទ្ធផលមេឌៀ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យកម្មវិធីនាំផ្លូវលទ្ធផលមេឌៀទៅឧបករណ៍ខាងក្រៅផ្សេង។"</string>
- <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យកម្មវិធីចូលការផ្ទុកមានសុវត្ថិភាព keguard ។"</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យការបង្ហាញ និងលាក់ការការពារ"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យកម្មវិធីគ្រប់គ្រង keguard ។"</string>
@@ -1365,7 +1365,7 @@
<string name="ime_action_go" msgid="8320845651737369027">"ទៅ"</string>
<string name="ime_action_search" msgid="658110271822807811">"ស្វែងរក"</string>
<string name="ime_action_send" msgid="2316166556349314424">"ផ្ញើ"</string>
- <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
<string name="ime_action_done" msgid="8971516117910934605">"រួចរាល់"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"មុន"</string>
<string name="ime_action_default" msgid="2840921885558045721">"អនុវត្ត"</string>
@@ -1374,7 +1374,7 @@
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធីមួយ ឬច្រើនដូចខាងក្រោមស្នើសិទ្ធិ ដើម្បីចូលគណនីរបស់អ្នកឥឡូវ និងពេលអនាគត។"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"តើអ្នកចង់អនុញ្ញាតសំណើនេះ?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"ស្នើចូល"</string>
- <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
+ <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
<string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"បានស្នើសិទ្ធិ"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"បានស្នើសិទ្ធិ\nសម្រាប់គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</string>
@@ -1397,12 +1397,12 @@
<string name="no_file_chosen" msgid="6363648562170759465">"គ្មានឯកសារបានជ្រើស"</string>
<string name="reset" msgid="2448168080964209908">"កំណត់ឡើងវិញ"</string>
<string name="submit" msgid="1602335572089911941">"ដាក់ស្នើ"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ប៉ះ ដើម្បីចេញពីរបៀបរថយន្ត។"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ ដើម្បីរៀបចំ។"</string>
<string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
- <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
<string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"ការប្រើទិន្នន័យចល័តខ្ពស់"</string>
<string name="throttle_warning_notification_message" msgid="3340822228599337743">"ប៉ះ ដើម្បីស្វែងយល់បន្ថែមអំពីការប្រើទិន្នន័យចល័ត។"</string>
@@ -1428,7 +1428,7 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍ផ្ទុកយូអេសប៊ីបច្ចុប្បន្នកំពុងប្រើដោយកុំព្យូទ័រ។"</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្នកាតអេសឌីកំពុងប្រើដោយកុំព្យូទ័រ"</string>
<string name="media_unknown_state" msgid="729192782197290385">"មិនស្គាល់ស្ថានភាពមេឌៀខាងក្រៅ។"</string>
- <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
+ <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
<string name="find" msgid="4808270900322985960">"រក"</string>
<string name="websearch" msgid="4337157977400211589">"ស្វែងរកតាមបណ្ដាញ"</string>
<string name="find_next" msgid="5742124618942193978">"រកបន្ទាប់"</string>
@@ -1444,7 +1444,7 @@
<string name="sync_undo_deletes" msgid="2941317360600338602">"មិនធ្វើការលុបវិញ"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"មិនធ្វើអ្វីទេឥឡូវ"</string>
<string name="choose_account_label" msgid="5655203089746423927">"ជ្រើសគណនី"</string>
- <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែមគណនី"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
<string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
@@ -1463,15 +1463,15 @@
<string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើនឆ្នាំ"</string>
<string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយឆ្នាំ"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"មិនអាចចាប់ផ្ដើម <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែករំលែកជាមួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រងការរុញ។ ប៉ះ & សង្កត់។"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស ដើម្បីដោះសោ។"</string>
@@ -1485,7 +1485,7 @@
<string name="storage_internal" msgid="4891916833657929263">"ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"កាតអេសឌី"</string>
<string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍ផ្ទុកយូអេសប៊ី"</string>
- <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមានប្រើទិន្នន័យ"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បីមើលការប្រើ និងការកំណត់។"</string>
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"បានបិទទិន្នន័យ 2G-3G"</string>
@@ -1542,7 +1542,7 @@
<string name="media_route_status_available" msgid="6983258067194649391">"ទំនេរ"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"មិនទំនេរ"</string>
<string name="media_route_status_in_use" msgid="4533786031090198063">"កំពុងប្រើ"</string>
- <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
+ <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"អេក្រង់ HDMI"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួតគ្នា"</string>
<string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
@@ -1574,7 +1574,7 @@
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -1683,7 +1683,7 @@
<string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
<string name="mediasize_unknown_portrait" msgid="3088043641616409762">"មិនស្គាល់បញ្ឈរ"</string>
<string name="mediasize_unknown_landscape" msgid="4876995327029361552">"មិនស្គាល់ទេសភាព"</string>
- <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
+ <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុសក្នុងការសរសេរមាតិកា"</string>
<string name="reason_unknown" msgid="6048913880184628119">"មិនស្គាល់"</string>
<string name="reason_service_unavailable" msgid="7824008732243903268">"មិនបានបើកសេវាកម្មបោះពុម្ព"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 3b275a5d..71f55fb 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1695,7 +1695,7 @@
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະຈຸບັນ"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</string>
- <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ບໍ່ກົງກັນ. ລອງໃໝ່ອີກຄັ້ງ."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ສັ້ນເກີນໄປ. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ."</string>
<plurals name="restr_pin_countdown">
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 4640f2a..d235eaa 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -187,7 +187,7 @@
<string name="global_action_settings" msgid="1756531602592545966">"การตั้งค่า"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
- <string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"ระบบแอนดรอยด์"</string>
<string name="user_owner_label" msgid="2804351898001038951">"ส่วนตัว"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ที่ทำงาน"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"บริการที่ต้องเสียค่าใช้จ่าย"</string>
@@ -424,7 +424,7 @@
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"อนุญาตให้แอปพลิเคชันทำให้ส่วนหนึ่งของตัวเองคงอยู่ถาวรในหน่วยความจำ ซึ่งจะจำกัดพื้นที่หน่วยความจำที่ใช้งานได้ของแอปพลิเคชันอื่นๆ และทำให้แท็บเล็ตทำงานช้าลง"</string>
<string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"อนุญาตให้แอปพลิเคชันทำให้ส่วนหนึ่งของตัวเองคงอยู่ถาวรในหน่วยความจำ ซึ่งจะจำกัดพื้นที่หน่วยความจำที่ใช้งานได้ของแอปพลิเคชันอื่นๆ และทำให้โทรศัพท์ทำงานช้าลง"</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"ลบแอปพลิเคชัน"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"อนุญาตให้แอปพลิเคชันลบแพ็กเกจ Android แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ลบแอปพลิเคชันที่สำคัญ"</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"อนุญาตให้แอปพลิเคชันลบแพ็กเกจแอนดรอยด์แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ลบแอปพลิเคชันที่สำคัญ"</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"ลบข้อมูลของแอปพลิเคชันอื่น"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"อนุญาตให้แอปพลิเคชันล้างข้อมูลผู้ใช้"</string>
<string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"ลบแคชของแอปพลิเคชันอื่น"</string>
@@ -432,7 +432,7 @@
<string name="permlab_getPackageSize" msgid="7472921768357981986">"วัดพื้นที่เก็บข้อมูลของแอปพลิเคชัน"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"อนุญาตให้แอปพลิเคชันเรียกดูรหัส ข้อมูล และขนาดแคชของตน"</string>
<string name="permlab_installPackages" msgid="2199128482820306924">"ติดตั้งแอปพลิเคชันโดยตรง"</string>
- <string name="permdesc_installPackages" msgid="5628530972548071284">"อนุญาตให้แอปพลิเคชันติดตั้งแพ็กเกจ Android ใหม่หรือที่อัปเดต แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ในการเพิ่มแอปพลิเคชันใหม่ๆ ด้วยสิทธิ์ที่สูงนี้ได้ตามต้องการ"</string>
+ <string name="permdesc_installPackages" msgid="5628530972548071284">"อนุญาตให้แอปพลิเคชันติดตั้งแพ็กเกจแอนดรอยด์ใหม่หรือที่อัปเดต แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ในการเพิ่มแอปพลิเคชันใหม่ๆ ด้วยสิทธิ์ที่สูงนี้ได้ตามต้องการ"</string>
<string name="permlab_clearAppCache" msgid="7487279391723526815">"ลบข้อมูลแคชของแอปพลิเคชันทั้งหมด"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"อนุญาตให้แอปพลิเคชันสร้างพื้นที่ว่างในที่จัดเก็บข้อมูลของแท็บเล็ต โดยลบไฟล์ในไดเรกทอรีแคชของแอปพลิเคชันอื่นๆ ซึ่งอาจทำให้แอปพลิเคชันอื่นเริ่มทำงานช้ากว่าเดิมเนื่องจากต้องดึงข้อมูลของตนซ้ำ"</string>
<string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"อนุญาตให้แอปพลิเคชันสร้างพื้นที่ว่างในที่จัดเก็บข้อมูลของโทรศัพท์ โดยลบไฟล์ในไดเรกทอรีแคชของแอปพลิเคชันอื่นๆ ซึ่งอาจทำให้แอปพลิเคชันอื่นเริ่มทำงานช้ากว่าเดิมเนื่องจากต้องดึงข้อมูลของตนซ้ำ"</string>
@@ -1190,7 +1190,7 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"เปิดใช้งานอีกครั้งในการตั้งค่าระบบ > แอปพลิเคชัน > ดาวน์โหลด"</string>
<string name="smv_application" msgid="3307209192155442829">"แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> (กระบวนการ <xliff:g id="PROCESS">%2$s</xliff:g>) ละเมิดนโยบาย StrictMode ที่บังคับใช้ด้วยตัวเอง"</string>
<string name="smv_process" msgid="5120397012047462446">"กระบวนการ <xliff:g id="PROCESS">%1$s</xliff:g> ละเมิดนโยบาย StrictMode ที่บังคับใช้ด้วยตัวเอง"</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"กำลังอัปเกรด Android..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"กำลังอัปเกรดแอนดรอยด์..."</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>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"เสร็จสิ้นการบูต"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9eb6f74..0ef23e3 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -493,6 +493,9 @@
{@link android.view.Window#setAllowExitTransitionOverlap(boolean)}. -->
<attr name="windowAllowExitTransitionOverlap" format="boolean"/>
+ <!-- Internal layout used internally for window decor -->
+ <attr name="windowActionBarFullscreenDecorLayout" format="reference" />
+
<!-- ============ -->
<!-- Alert Dialog styles -->
<!-- ============ -->
@@ -685,6 +688,7 @@
<!-- Default ActivityChooserView style. -->
<attr name="activityChooserViewStyle" format="reference" />
+ <!-- Default Toolbar style. -->
<attr name="toolbarStyle" format="reference" />
<!-- Fast scroller styles -->
@@ -1713,6 +1717,7 @@
<attr name="windowSwipeToDismiss" />
<attr name="windowContentTransitions" />
<attr name="windowContentTransitionManager" />
+ <attr name="windowActionBarFullscreenDecorLayout" />
<!-- The minimum width the window is allowed to be, along the major
axis of the screen. That is, when in landscape. Can be either
@@ -4780,6 +4785,26 @@
<attr name="height" />
</declare-styleable>
+ <!-- Defines the group used in Vector Drawables. -->
+ <declare-styleable name="VectorDrawableGroup">
+ <!-- The Name of this group -->
+ <attr name="name" />
+ <!-- The amount to rotate the group -->
+ <attr name="rotation" />
+ <!-- The X coordinate of the center of rotation of a group -->
+ <attr name="pivotX" />
+ <!-- The Y coordinate of the center of rotation of a group -->
+ <attr name="pivotY" />
+ <!-- The amount to translate the group on X coordinate -->
+ <attr name="translateX" format="float"/>
+ <!-- The amount to translate the group on Y coordinate -->
+ <attr name="translateY" format="float"/>
+ <!-- The amount to scale the group on X coordinate -->
+ <attr name="scaleX" />
+ <!-- The amount to scale the group on X coordinate -->
+ <attr name="scaleY" />
+ </declare-styleable>
+
<!-- Defines the path used in Vector Drawables. -->
<declare-styleable name="VectorDrawablePath">
<!-- The Name of this path -->
@@ -4788,12 +4813,6 @@
<attr name="strokeWidth" format="float" />
<!-- The opacity of a path stroke -->
<attr name="strokeOpacity" format="float" />
- <!-- The amount to rotate the path stroke -->
- <attr name="rotation" />
- <!-- The X coordinate of the center of rotation of a path -->
- <attr name="pivotX" />
- <!-- The Y coordinate of the center of rotation of a path -->
- <attr name="pivotY" />
<!-- The color to stroke the path if not defined implies no stroke-->
<attr name="stroke" format="color" />
<!-- The color to fill the path if not defined implies no fill-->
@@ -6404,11 +6423,17 @@
<attr name="indeterminateProgressStyle" format="reference" />
<!-- Specifies the horizontal padding on either end for an embedded progress bar. -->
<attr name="progressBarPadding" format="dimension" />
+ <!-- Up navigation glyph -->
+ <attr name="homeAsUpIndicator" />
<!-- Specifies padding that should be applied to the left and right sides of
system-provided items in the bar. -->
<attr name="itemPadding" format="dimension" />
<!-- Set true to hide the action bar on a vertical nested scroll of content. -->
<attr name="hideOnContentScroll" format="boolean" />
+ <attr name="contentInsetStart" format="dimension" />
+ <attr name="contentInsetEnd" format="dimension" />
+ <attr name="contentInsetLeft" format="dimension" />
+ <attr name="contentInsetRight" format="dimension" />
</declare-styleable>
<declare-styleable name="ActionMode">
@@ -6659,10 +6684,19 @@
<attr name="titleMarginEnd" format="dimension" />
<attr name="titleMarginTop" format="dimension" />
<attr name="titleMarginBottom" format="dimension" />
- <attr name="contentInsetStart" format="dimension" />
- <attr name="contentInsetEnd" format="dimension" />
- <attr name="contentInsetLeft" format="dimension" />
- <attr name="contentInsetRight" format="dimension" />
+ <attr name="contentInsetStart" />
+ <attr name="contentInsetEnd" />
+ <attr name="contentInsetLeft" />
+ <attr name="contentInsetRight" />
+ <attr name="maxButtonHeight" format="dimension" />
+ <attr name="navigationButtonStyle" format="reference" />
+ <attr name="buttonGravity">
+ <!-- Push object to the top of its container, not changing its size. -->
+ <flag name="top" value="0x30" />
+ <!-- Push object to the bottom of its container, not changing its size. -->
+ <flag name="bottom" value="0x50" />
+ </attr>
+ <attr name="collapseIcon" format="reference" />
</declare-styleable>
<declare-styleable name="Toolbar_LayoutParams">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 42ed318..9c33d80 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2180,6 +2180,8 @@
<public type="attr" name="paddingMode" />
<public type="attr" name="layout_rowWeight" />
<public type="attr" name="layout_columnWeight" />
+ <public type="attr" name="translateX" />
+ <public type="attr" name="translateY" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 1f4c88d..63f2674 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -171,8 +171,8 @@
<!-- Window animations that are applied to voice interaction overlay windows. -->
<style name="Animation.VoiceInteractionSession">
- <item name="windowEnterAnimation">@anim/input_method_enter</item>
- <item name="windowExitAnimation">@anim/input_method_exit</item>
+ <item name="windowEnterAnimation">@anim/voice_layer_enter</item>
+ <item name="windowExitAnimation">@anim/voice_layer_exit</item>
</style>
<!-- Special optional fancy IM animations. @hide -->
@@ -1189,6 +1189,16 @@
<item name="android:subtitleTextAppearance">@android:style/TextAppearance.Widget.Toolbar.Subtitle</item>
<item name="android:minHeight">?android:attr/actionBarSize</item>
<item name="android:titleMargins">4dp</item>
+ <item name="android:maxButtonHeight">56dp</item>
+ <item name="android:buttonGravity">top</item>
+ <item name="android:navigationButtonStyle">@android:style/Widget.Toolbar.Button.Navigation</item>
+ <item name="android:collapseIcon">?android:attr/homeAsUpIndicator</item>
+ </style>
+
+ <style name="Widget.Toolbar.Button.Navigation" parent="@android:style/Widget">
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:minWidth">56dp</item>
+ <item name="android:scaleType">center</item>
</style>
<style name="TextAppearance.Widget.ActionBar.Title"
@@ -2386,7 +2396,6 @@
<item name="android:background">@android:drawable/ab_transparent_light_holo</item>
<item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_light_holo</item>
<item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_light_holo</item>
- <item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item>
<item name="android:progressBarStyle">@android:style/Widget.Holo.Light.ProgressBar.Horizontal</item>
<item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.Light.ProgressBar</item>
</style>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index 2e7a5b1..ea32681 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -773,7 +773,7 @@
<item name="background">@null</item>
<item name="backgroundStacked">@null</item>
<item name="backgroundSplit">@null</item>
- <item name="displayOptions">useLogo|showHome|showTitle</item>
+ <item name="displayOptions">showTitle</item>
<item name="divider">?attr/dividerVertical</item>
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
@@ -783,6 +783,7 @@
<item name="itemPadding">8dip</item>
<item name="homeLayout">@layout/action_bar_home_quantum</item>
<item name="gravity">center_vertical</item>
+ <item name="contentInsetStart">56dp</item>
</style>
<style name="Widget.Quantum.ActionBar.Solid">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 69f73e5..6e1629b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1286,6 +1286,10 @@
<java-symbol type="anim" name="dock_left_exit" />
<java-symbol type="anim" name="dock_right_enter" />
<java-symbol type="anim" name="dock_right_exit" />
+ <java-symbol type="anim" name="voice_activity_close_exit" />
+ <java-symbol type="anim" name="voice_activity_close_enter" />
+ <java-symbol type="anim" name="voice_activity_open_exit" />
+ <java-symbol type="anim" name="voice_activity_open_enter" />
<java-symbol type="array" name="config_hdmiCecLogicalDeviceType" />
<java-symbol type="array" name="config_keyboardTapVibePattern" />
@@ -1862,6 +1866,7 @@
<java-symbol type="attr" name="toolbarStyle" />
<java-symbol type="attr" name="titleTextAppearance" />
<java-symbol type="attr" name="subtitleTextAppearance" />
+ <java-symbol type="attr" name="windowActionBarFullscreenDecorLayout" />
<java-symbol type="drawable" name="ic_lock_bugreport" />
<java-symbol type="id" name="icon_frame" />
<java-symbol type="style" name="Animation.VolumePanel" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index aaab949..41f4ff8 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -192,6 +192,7 @@
<item name="windowDrawsSystemBarBackgrounds">false</item>
<item name="statusBarColor">@android:color/black</item>
<item name="navigationBarColor">@android:color/black</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item>
<!-- Define these here; ContextThemeWrappers around themes that define them should
always clear these values. -->
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index bb787bb..484c694 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -162,6 +162,7 @@
<item name="windowActionBar">true</item>
<item name="windowActionModeOverlay">false</item>
<item name="windowDrawsSystemBarBackgrounds">true</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
<item name="statusBarColor">?attr/colorPrimaryDark</item>
<item name="navigationBarColor">?attr/colorPrimaryDark</item>
@@ -505,6 +506,7 @@
<item name="windowActionBar">true</item>
<item name="windowActionModeOverlay">false</item>
<item name="windowDrawsSystemBarBackgrounds">true</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
<item name="statusBarColor">?attr/colorPrimaryDark</item>
<item name="navigationBarColor">?attr/colorPrimaryDark</item>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d4ea7a9..5e4e42b 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -713,6 +713,9 @@
* @param region The region to operate on the current clip, based on op
* @param op How the clip is modified
* @return true if the resulting is non-empty
+ *
+ * @deprecated Unlike all other clip calls this API does not respect the
+ * current matrix. Use {@link #clipRect(Rect)} as an alternative.
*/
public boolean clipRegion(Region region, Region.Op op) {
return native_clipRegion(mNativeCanvas, region.ni(), op.nativeInt);
@@ -727,6 +730,9 @@
*
* @param region The region to operate on the current clip, based on op
* @return true if the resulting is non-empty
+ *
+ * @deprecated Unlike all other clip calls this API does not respect the
+ * current matrix. Use {@link #clipRect(Rect)} as an alternative.
*/
public boolean clipRegion(Region region) {
return clipRegion(region, Region.Op.INTERSECT);
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 492376f..afd529c 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -39,7 +39,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
/**
@@ -59,7 +58,23 @@
* The size is defined using the attributes <code>android:viewportHeight</code>
* <code>android:viewportWidth</code></dd>
* <dt><code><group></code></dt>
- * <dd>Defines a group of paths or subgroups, plus transformation information.</dd>
+ * <dd>Defines a group of paths or subgroups, plus transformation information.
+ * The transformations are defined in the same coordinates as the viewport.
+ * And the transformations are applied in the order of scale, rotate then translate. </dd>
+ * <dt><code>android:rotation</code>
+ * <dd>The degrees of rotation of the group.</dd></dt>
+ * <dt><code>android:pivotX</code>
+ * <dd>The X coordinate of the pivot for the scale and rotation of the group</dd></dt>
+ * <dt><code>android:pivotY</code>
+ * <dd>The Y coordinate of the pivot for the scale and rotation of the group</dd></dt>
+ * <dt><code>android:scaleX</code>
+ * <dd>The amount of scale on the X Coordinate</dd></dt>
+ * <dt><code>android:scaleY</code>
+ * <dd>The amount of scale on the Y coordinate</dd></dt>
+ * <dt><code>android:translateX</code>
+ * <dd>The amount of translation on the X coordinate</dd></dt>
+ * <dt><code>android:translateY</code>
+ * <dd>The amount of translation on the Y coordinate</dd></dt>
* <dt><code><path></code></dt>
* <dd>Defines paths to be drawn.
* <dl>
@@ -77,12 +92,6 @@
* <dd>The width a path stroke</dd></dt>
* <dt><code>android:strokeOpacity</code>
* <dd>The opacity of a path stroke</dd></dt>
- * <dt><code>android:rotation</code>
- * <dd>The amount to rotation the path stroke.</dd></dt>
- * <dt><code>android:pivotX</code>
- * <dd>The X coordinate of the center of rotation of a path</dd></dt>
- * <dt><code>android:pivotY</code>
- * <dd>The Y coordinate of the center of rotation of a path</dd></dt>
* <dt><code>android:fillOpacity</code>
* <dd>The opacity to fill the path with</dd></dt>
* <dt><code>android:trimPathStart</code>
@@ -289,6 +298,7 @@
noViewportTag = false;
} else if (SHAPE_GROUP.equals(tagName)) {
currentGroup = new VGroup();
+ currentGroup.inflate(res, attrs, theme);
pathRenderer.mGroupList.add(currentGroup);
noGroupTag = false;
}
@@ -325,8 +335,6 @@
throw new XmlPullParserException("no " + tag + " defined");
}
- // post parse cleanup
- pathRenderer.parseFinish();
return pathRenderer;
}
@@ -373,7 +381,6 @@
private final Path mRenderPath = new Path();
private final Matrix mMatrix = new Matrix();
- private VPath[] mCurrentPaths;
private Paint mStrokePaint;
private Paint mFillPaint;
private ColorFilter mColorFilter;
@@ -391,12 +398,6 @@
public VPathRenderer(VPathRenderer copy) {
mGroupList.addAll(copy.mGroupList);
- if (copy.mCurrentPaths != null) {
- mCurrentPaths = new VPath[copy.mCurrentPaths.length];
- for (int i = 0; i < mCurrentPaths.length; i++) {
- mCurrentPaths[i] = new VPath(copy.mCurrentPaths[i]);
- }
- }
mBaseWidth = copy.mBaseWidth;
mBaseHeight = copy.mBaseHeight;
@@ -422,7 +423,9 @@
public void applyTheme(Theme t) {
final ArrayList<VGroup> groups = mGroupList;
for (int i = groups.size() - 1; i >= 0; i--) {
- final ArrayList<VPath> paths = groups.get(i).mVGList;
+ VGroup currentGroup = groups.get(i);
+ currentGroup.applyTheme(t);
+ final ArrayList<VPath> paths = currentGroup.mVGList;
for (int j = paths.size() - 1; j >= 0; j--) {
final VPath path = paths.get(j);
if (path.canApplyTheme()) {
@@ -446,104 +449,104 @@
}
public void draw(Canvas canvas, int w, int h) {
- if (mCurrentPaths == null) {
- Log.e(LOGTAG,"mCurrentPaths == null");
+ if (mGroupList == null || mGroupList.size() == 0) {
+ Log.e(LOGTAG,"There is no group to draw");
return;
}
- for (int i = 0; i < mCurrentPaths.length; i++) {
- if (mCurrentPaths[i] != null) {
- drawPath(mCurrentPaths[i], canvas, w, h);
+ for (int i = 0; i < mGroupList.size(); i++) {
+ VGroup currentGroup = mGroupList.get(i);
+ if (currentGroup != null) {
+ drawPath(currentGroup, canvas, w, h);
}
}
}
- private void drawPath(VPath vPath, Canvas canvas, int w, int h) {
+ private void drawPath(VGroup vGroup, Canvas canvas, int w, int h) {
final float scale = Math.min(h / mViewportHeight, w / mViewportWidth);
- vPath.toPath(mPath);
- final Path path = mPath;
-
- if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) {
- float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f;
- float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f;
-
- if (mPathMeasure == null) {
- mPathMeasure = new PathMeasure();
- }
- mPathMeasure.setPath(mPath, false);
-
- float len = mPathMeasure.getLength();
- start = start * len;
- end = end * len;
- path.reset();
- if (start > end) {
- mPathMeasure.getSegment(start, len, path, true);
- mPathMeasure.getSegment(0f, end, path, true);
- } else {
- mPathMeasure.getSegment(start, end, path, true);
- }
- path.rLineTo(0, 0); // fix bug in measure
- }
-
- mRenderPath.reset();
mMatrix.reset();
- mMatrix.postRotate(vPath.mRotate, vPath.mPivotX, vPath.mPivotY);
+ // The order we apply is the same as the
+ // RenderNode.cpp::applyViewPropertyTransforms().
+ mMatrix.postTranslate(-vGroup.mPivotX, -vGroup.mPivotY);
+ mMatrix.postScale(vGroup.mScaleX, vGroup.mScaleY);
+ mMatrix.postRotate(vGroup.mRotate, 0, 0);
+ mMatrix.postTranslate(vGroup.mTranslateX + vGroup.mPivotX, vGroup.mTranslateY + vGroup.mPivotY);
+
mMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f);
mMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
- mRenderPath.addPath(path, mMatrix);
+ ArrayList<VPath> paths = vGroup.getPaths();
+ for (int i = 0; i < paths.size(); i++) {
+ VPath vPath = paths.get(i);
+ vPath.toPath(mPath);
+ final Path path = mPath;
- if (vPath.mClip) {
- canvas.clipPath(mRenderPath, Region.Op.REPLACE);
- }
+ if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) {
+ float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f;
+ float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f;
- if (vPath.mFillColor != 0) {
- if (mFillPaint == null) {
- mFillPaint = new Paint();
- mFillPaint.setColorFilter(mColorFilter);
- mFillPaint.setStyle(Paint.Style.FILL);
- mFillPaint.setAntiAlias(true);
+ if (mPathMeasure == null) {
+ mPathMeasure = new PathMeasure();
+ }
+ mPathMeasure.setPath(mPath, false);
+
+ float len = mPathMeasure.getLength();
+ start = start * len;
+ end = end * len;
+ path.reset();
+ if (start > end) {
+ mPathMeasure.getSegment(start, len, path, true);
+ mPathMeasure.getSegment(0f, end, path, true);
+ } else {
+ mPathMeasure.getSegment(start, end, path, true);
+ }
+ path.rLineTo(0, 0); // fix bug in measure
}
- mFillPaint.setColor(vPath.mFillColor);
- canvas.drawPath(mRenderPath, mFillPaint);
- }
+ mRenderPath.reset();
- if (vPath.mStrokeColor != 0) {
- if (mStrokePaint == null) {
- mStrokePaint = new Paint();
- mStrokePaint.setColorFilter(mColorFilter);
- mStrokePaint.setStyle(Paint.Style.STROKE);
- mStrokePaint.setAntiAlias(true);
+ mRenderPath.addPath(path, mMatrix);
+
+ if (vPath.mClip) {
+ canvas.clipPath(mRenderPath, Region.Op.REPLACE);
}
- final Paint strokePaint = mStrokePaint;
- if (vPath.mStrokeLineJoin != null) {
- strokePaint.setStrokeJoin(vPath.mStrokeLineJoin);
+ if (vPath.mFillColor != 0) {
+ if (mFillPaint == null) {
+ mFillPaint = new Paint();
+ mFillPaint.setColorFilter(mColorFilter);
+ mFillPaint.setStyle(Paint.Style.FILL);
+ mFillPaint.setAntiAlias(true);
+ }
+
+ mFillPaint.setColor(vPath.mFillColor);
+ canvas.drawPath(mRenderPath, mFillPaint);
}
- if (vPath.mStrokeLineCap != null) {
- strokePaint.setStrokeCap(vPath.mStrokeLineCap);
+ if (vPath.mStrokeColor != 0) {
+ if (mStrokePaint == null) {
+ mStrokePaint = new Paint();
+ mStrokePaint.setColorFilter(mColorFilter);
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+ mStrokePaint.setAntiAlias(true);
+ }
+
+ final Paint strokePaint = mStrokePaint;
+ if (vPath.mStrokeLineJoin != null) {
+ strokePaint.setStrokeJoin(vPath.mStrokeLineJoin);
+ }
+
+ if (vPath.mStrokeLineCap != null) {
+ strokePaint.setStrokeCap(vPath.mStrokeLineCap);
+ }
+
+ strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale);
+ strokePaint.setColor(vPath.mStrokeColor);
+ strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale);
+ canvas.drawPath(mRenderPath, strokePaint);
}
-
- strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale);
- strokePaint.setColor(vPath.mStrokeColor);
- strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale);
- canvas.drawPath(mRenderPath, strokePaint);
- }
- }
-
- /**
- * Build the "current" path based on the current group
- * TODO: improve memory use & performance or move to C++
- */
- public void parseFinish() {
- final Collection<VPath> paths = mGroupList.get(0).getPaths();
- mCurrentPaths = paths.toArray(new VPath[paths.size()]);
- for (int i = 0; i < mCurrentPaths.length; i++) {
- mCurrentPaths[i] = new VPath(mCurrentPaths[i]);
}
}
@@ -587,17 +590,84 @@
private final HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
private final ArrayList<VPath> mVGList = new ArrayList<VPath>();
+ private float mRotate = 0;
+ private float mPivotX = 0;
+ private float mPivotY = 0;
+ private float mScaleX = 1;
+ private float mScaleY = 1;
+ private float mTranslateX = 0;
+ private float mTranslateY = 0;
+
+ private int[] mThemeAttrs;
+
public void add(VPath path) {
String id = path.getID();
mVGPathMap.put(id, path);
mVGList.add(path);
}
+ public void applyTheme(Theme t) {
+ if (mThemeAttrs == null) {
+ return;
+ }
+
+ final TypedArray a = t.resolveAttributes(
+ mThemeAttrs, R.styleable.VectorDrawablePath);
+
+ mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
+ mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
+ mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
+ mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
+ mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
+ mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
+ mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
+ a.recycle();
+ }
+
+ public void inflate(Resources res, AttributeSet attrs, Theme theme) {
+ final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawableGroup);
+ final int[] themeAttrs = a.extractThemeAttrs();
+
+ mThemeAttrs = themeAttrs;
+ // NOTE: The set of attributes loaded here MUST match the
+ // set of attributes loaded in applyTheme.
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_rotation] == 0) {
+ mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotX] == 0) {
+ mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotY] == 0) {
+ mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleX] == 0) {
+ mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleY] == 0) {
+ mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateX] == 0) {
+ mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
+ }
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateY] == 0) {
+ mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
+ }
+
+ a.recycle();
+ }
+
/**
* Must return in order of adding
* @return ordered list of paths
*/
- public Collection<VPath> getPaths() {
+ public ArrayList<VPath> getPaths() {
return mVGList;
}
@@ -616,10 +686,6 @@
int mFillRule;
float mFillOpacity = Float.NaN;
- float mRotate = 0;
- float mPivotX = 0;
- float mPivotY = 0;
-
float mTrimPathStart = 0;
float mTrimPathEnd = 1;
float mTrimPathOffset = 0;
@@ -631,18 +697,11 @@
private VNode[] mNode = null;
private String mId;
- private int[] mCheckState = new int[MAX_STATES];
- private boolean[] mCheckValue = new boolean[MAX_STATES];
- private int mNumberOfStates = 0;
public VPath() {
// Empty constructor.
}
- public VPath(VPath p) {
- copyFrom(p);
- }
-
public void toPath(Path path) {
path.reset();
if (mNode != null) {
@@ -707,18 +766,6 @@
mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity);
}
- if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_rotation] == 0) {
- mRotate = a.getFloat(R.styleable.VectorDrawablePath_rotation, mRotate);
- }
-
- if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_pivotX] == 0) {
- mPivotX = a.getFloat(R.styleable.VectorDrawablePath_pivotX, mPivotX);
- }
-
- if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_pivotY] == 0) {
- mPivotY = a.getFloat(R.styleable.VectorDrawablePath_pivotY, mPivotY);
- }
-
if (themeAttrs == null
|| themeAttrs[R.styleable.VectorDrawablePath_strokeLineCap] == 0) {
mStrokeLineCap = getStrokeLineCap(
@@ -797,10 +844,6 @@
mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor);
mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity);
- mRotate = a.getFloat(R.styleable.VectorDrawablePath_rotation, mRotate);
- mPivotX = a.getFloat(R.styleable.VectorDrawablePath_pivotX, mPivotX);
- mPivotY = a.getFloat(R.styleable.VectorDrawablePath_pivotY, mPivotY);
-
mStrokeLineCap = getStrokeLineCap(a.getInt(
R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
mStrokeLineJoin = getStrokeLineJoin(a.getInt(
@@ -819,6 +862,7 @@
R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
updateColorAlphas();
+ a.recycle();
}
private void updateColorAlphas() {
@@ -921,33 +965,6 @@
}
return list.toArray(new VectorDrawable.VNode[list.size()]);
}
-
- public void copyFrom(VPath p1) {
- mNode = new VNode[p1.mNode.length];
- for (int i = 0; i < mNode.length; i++) {
- mNode[i] = new VNode(p1.mNode[i]);
- }
- mId = p1.mId;
- mStrokeColor = p1.mStrokeColor;
- mFillColor = p1.mFillColor;
- mStrokeWidth = p1.mStrokeWidth;
- mRotate = p1.mRotate;
- mPivotX = p1.mPivotX;
- mPivotY = p1.mPivotY;
- mTrimPathStart = p1.mTrimPathStart;
- mTrimPathEnd = p1.mTrimPathEnd;
- mTrimPathOffset = p1.mTrimPathOffset;
- mStrokeLineCap = p1.mStrokeLineCap;
- mStrokeLineJoin = p1.mStrokeLineJoin;
- mStrokeMiterlimit = p1.mStrokeMiterlimit;
- mNumberOfStates = p1.mNumberOfStates;
- for (int i = 0; i < mNumberOfStates; i++) {
- mCheckState[i] = p1.mCheckState[i];
- mCheckValue[i] = p1.mCheckValue[i];
- }
-
- mFillRule = p1.mFillRule;
- }
}
private static class VNode {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b6b3428..160fbea 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -556,6 +556,13 @@
return LayerRenderer::copyLayer(layer->backingLayer(), bitmap);
}
+void CanvasContext::flushCaches(Caches::FlushMode flushMode) {
+ if (mGlobalContext->hasContext()) {
+ requireGlContext();
+ Caches::getInstance().flush(flushMode);
+ }
+}
+
void CanvasContext::runWithGlContext(RenderTask* task) {
requireGlContext();
task->run();
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index a54b33e..da85d448 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -63,6 +63,8 @@
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
+ void flushCaches(Caches::FlushMode flushMode);
+
void invokeFunctor(Functor* functor);
void runWithGlContext(RenderTask* task);
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 2e103d8..8e772f2 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -282,6 +282,18 @@
post(task);
}
+CREATE_BRIDGE2(flushCaches, CanvasContext* context, Caches::FlushMode flushMode) {
+ args->context->flushCaches(args->flushMode);
+ return NULL;
+}
+
+void RenderProxy::flushCaches(Caches::FlushMode flushMode) {
+ SETUP_TASK(flushCaches);
+ args->context = mContext;
+ args->flushMode = flushMode;
+ post(task);
+}
+
CREATE_BRIDGE0(fence) {
// Intentionally empty
return NULL;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8aeb264..22d4e22 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -29,6 +29,7 @@
#include <utils/StrongPointer.h>
#include <utils/Vector.h>
+#include "../Caches.h"
#include "DrawFrameTask.h"
namespace android {
@@ -81,6 +82,8 @@
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
ANDROID_API void destroyLayer(DeferredLayerUpdater* layer);
+ ANDROID_API void flushCaches(Caches::FlushMode flushMode);
+
ANDROID_API void fence();
ANDROID_API void notifyFramePending();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index f4affa0..47a8ce5 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2818,18 +2818,22 @@
}
/**
- * Indicate A2DP sink connection state change.
+ * Indicate A2DP source or sink connection state change.
* @param device Bluetooth device connected/disconnected
* @param state new connection state (BluetoothProfile.STATE_xxx)
+ * @param profile profile for the A2DP device
+ * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
+ * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
* @return a delay in ms that the caller should wait before broadcasting
* BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
* {@hide}
*/
- public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state,
+ int profile) {
IAudioService service = getService();
int delay = 0;
try {
- delay = service.setBluetoothA2dpDeviceConnectionState(device, state);
+ delay = service.setBluetoothA2dpDeviceConnectionState(device, state, profile);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
} finally {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index cf18902..98a7c65 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -169,7 +169,8 @@
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100;
- private static final int MSG_SET_A2DP_CONNECTION_STATE = 101;
+ private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
+ private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
// end of messages handled under wakelock
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -2371,10 +2372,10 @@
synchronized (mConnectedDevices) {
int state = mA2dp.getConnectionState(btDevice);
int delay = checkSendBecomingNoisyIntent(
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
queueMsgUnderWakeLock(mAudioHandler,
- MSG_SET_A2DP_CONNECTION_STATE,
+ MSG_SET_A2DP_SINK_CONNECTION_STATE,
state,
0,
btDevice,
@@ -2384,6 +2385,22 @@
}
break;
+ case BluetoothProfile.A2DP_SINK:
+ deviceList = proxy.getConnectedDevices();
+ if (deviceList.size() > 0) {
+ btDevice = deviceList.get(0);
+ synchronized (mConnectedDevices) {
+ int state = proxy.getConnectionState(btDevice);
+ queueMsgUnderWakeLock(mAudioHandler,
+ MSG_SET_A2DP_SRC_CONNECTION_STATE,
+ state,
+ 0,
+ btDevice,
+ 0 /* delay */);
+ }
+ }
+ break;
+
case BluetoothProfile.HEADSET:
synchronized (mScoClients) {
// Discard timeout message
@@ -2452,6 +2469,15 @@
}
break;
+ case BluetoothProfile.A2DP_SINK:
+ synchronized (mConnectedDevices) {
+ if (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) {
+ makeA2dpSrcUnavailable(
+ mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP));
+ }
+ }
+ break;
+
case BluetoothProfile.HEADSET:
synchronized (mScoClients) {
mBluetoothHeadset = null;
@@ -2863,14 +2889,22 @@
}
}
- public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
{
int delay;
+ if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
+ throw new IllegalArgumentException("invalid profile " + profile);
+ }
synchronized (mConnectedDevices) {
- delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ if (profile == BluetoothProfile.A2DP) {
+ delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ } else {
+ delay = 0;
+ }
queueMsgUnderWakeLock(mAudioHandler,
- MSG_SET_A2DP_CONNECTION_STATE,
+ (profile == BluetoothProfile.A2DP ?
+ MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
state,
0,
device,
@@ -3726,8 +3760,13 @@
mAudioEventWakeLock.release();
break;
- case MSG_SET_A2DP_CONNECTION_STATE:
- onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ case MSG_SET_A2DP_SRC_CONNECTION_STATE:
+ onSetA2dpSourceConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ mAudioEventWakeLock.release();
+ break;
+
+ case MSG_SET_A2DP_SINK_CONNECTION_STATE:
+ onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1);
mAudioEventWakeLock.release();
break;
@@ -3854,6 +3893,23 @@
}
// must be called synchronized on mConnectedDevices
+ private void makeA2dpSrcAvailable(String address) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ address);
+ mConnectedDevices.put( new Integer(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP),
+ address);
+ }
+
+ // must be called synchronized on mConnectedDevices
+ private void makeA2dpSrcUnavailable(String address) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ address);
+ mConnectedDevices.remove(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP);
+ }
+
+ // must be called synchronized on mConnectedDevices
private void cancelA2dpDeviceTimeout() {
mAudioHandler.removeMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
@@ -3863,9 +3919,11 @@
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
+ private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)
{
- if (DEBUG_VOL) Log.d(TAG, "onSetA2dpConnectionState btDevice="+btDevice+" state="+state);
+ if (DEBUG_VOL) {
+ Log.d(TAG, "onSetA2dpSinkConnectionState btDevice="+btDevice+"state="+state);
+ }
if (btDevice == null) {
return;
}
@@ -3924,6 +3982,32 @@
}
}
+ private void onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state)
+ {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "onSetA2dpSourceConnectionState btDevice="+btDevice+" state="+state);
+ }
+ if (btDevice == null) {
+ return;
+ }
+ String address = btDevice.getAddress();
+ if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+ address = "";
+ }
+
+ synchronized (mConnectedDevices) {
+ boolean isConnected =
+ (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) &&
+ mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP).equals(address));
+
+ if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
+ makeA2dpSrcUnavailable(address);
+ } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
+ makeA2dpSrcAvailable(address);
+ }
+ }
+ }
+
public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
// address is not used for now, but may be used when multiple a2dp devices are supported
synchronized (mA2dpAvrcpLock) {
@@ -3989,7 +4073,8 @@
}
}
- if (mAudioHandler.hasMessages(MSG_SET_A2DP_CONNECTION_STATE) ||
+ if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
+ mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
delay = 1000;
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 0c45443..5abf4b6 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -299,7 +299,7 @@
public static final int DEVICE_IN_TV_TUNER = DEVICE_BIT_IN | 0x4000;
public static final int DEVICE_IN_LINE = DEVICE_BIT_IN | 0x8000;
public static final int DEVICE_IN_SPDIF = DEVICE_BIT_IN | 0x10000;
-
+ public static final int DEVICE_IN_BLUETOOTH_A2DP = DEVICE_BIT_IN | 0x20000;
public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT;
public static final int DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION |
@@ -319,6 +319,7 @@
DEVICE_IN_TV_TUNER |
DEVICE_IN_LINE |
DEVICE_IN_SPDIF |
+ DEVICE_IN_BLUETOOTH_A2DP |
DEVICE_IN_DEFAULT);
public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 30de4f9..e59623b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -232,7 +232,7 @@
int getMasterStreamType();
void setWiredDeviceConnectionState(int device, int state, String name);
- int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
+ int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index a3caba2..fe51215 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -41,6 +41,7 @@
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.params.TonemapCurve;
import android.hardware.camera2.utils.TypeReference;
import static android.hardware.camera2.impl.CameraMetadataNative.*;
@@ -49,6 +50,7 @@
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.util.Arrays;
import java.util.List;
/**
@@ -1015,6 +1017,26 @@
assertNull(resultSimpleFaces[i].getMouthPosition());
}
+ /**
+ * Read/Write TonemapCurve
+ */
+ float[] red = new float[] {0.0f, 0.0f, 1.0f, 1.0f};
+ float[] green = new float[] {0.0f, 1.0f, 1.0f, 0.0f};
+ float[] blue = new float[] {
+ 0.0000f, 0.0000f, 0.0667f, 0.2920f, 0.1333f, 0.4002f, 0.2000f, 0.4812f,
+ 0.2667f, 0.5484f, 0.3333f, 0.6069f, 0.4000f, 0.6594f, 0.4667f, 0.7072f,
+ 0.5333f, 0.7515f, 0.6000f, 0.7928f, 0.6667f, 0.8317f, 0.7333f, 0.8685f,
+ 0.8000f, 0.9035f, 0.8667f, 0.9370f, 0.9333f, 0.9691f, 1.0000f, 1.0000f};
+ TonemapCurve tcIn = new TonemapCurve(red, green, blue);
+ mMetadata.set(CaptureResult.TONEMAP_CURVE, tcIn);
+ float[] redOut = mMetadata.get(CaptureResult.TONEMAP_CURVE_RED);
+ float[] greenOut = mMetadata.get(CaptureResult.TONEMAP_CURVE_GREEN);
+ float[] blueOut = mMetadata.get(CaptureResult.TONEMAP_CURVE_BLUE);
+ assertTrue("Input and output tonemap curve should match", Arrays.equals(red, redOut));
+ assertTrue("Input and output tonemap curve should match", Arrays.equals(green, greenOut));
+ assertTrue("Input and output tonemap curve should match", Arrays.equals(blue, blueOut));
+ TonemapCurve tcOut = mMetadata.get(CaptureResult.TONEMAP_CURVE);
+ assertTrue("Input and output tonemap curve should match", tcIn.equals(tcOut));
}
/**
@@ -1166,6 +1188,48 @@
}
}
+ private <T> void assertKeyValueEquals(T expected, CameraCharacteristics.Key<T> key) {
+ assertKeyValueEquals(expected, key.getNativeKey());
+ }
+
+ private <T> void assertKeyValueEquals(T expected, Key<T> key) {
+ T actual = mMetadata.get(key);
+
+ assertEquals("Expected value for key " + key + " to match", expected, actual);
+ }
+
+ @SmallTest
+ public void testOverrideMaxRegions() {
+ // All keys are null before doing any writes.
+ assertKeyValueEquals(null, CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
+ assertKeyValueEquals(null, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
+ assertKeyValueEquals(null, CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
+
+ mMetadata.set(CameraCharacteristics.CONTROL_MAX_REGIONS,
+ new int[] { /*AE*/1, /*AWB*/2, /*AF*/3 });
+
+ // All keys are the expected value after doing a write
+ assertKeyValueEquals(1, CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
+ assertKeyValueEquals(2, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
+ assertKeyValueEquals(3, CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
+ }
+
+ @SmallTest
+ public void testOverrideMaxNumOutputStreams() {
+ // All keys are null before doing any writes.
+ assertKeyValueEquals(null, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW);
+ assertKeyValueEquals(null, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC);
+ assertKeyValueEquals(null, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING);
+
+ mMetadata.set(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS,
+ new int[] { /*AE*/1, /*AWB*/2, /*AF*/3 });
+
+ // All keys are the expected value after doing a write
+ assertKeyValueEquals(1, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW);
+ assertKeyValueEquals(2, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC);
+ assertKeyValueEquals(3, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING);
+ }
+
@SmallTest
public void testCaptureResult() {
mMetadata.set(CaptureRequest.CONTROL_AE_MODE,
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 8c9030d..e8944ec 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -20,14 +20,14 @@
<string name="title_open" msgid="4353228937663917801">"បើកពី"</string>
<string name="title_save" msgid="2433679664882857999">"រក្សាទុកទៅ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"បង្កើតថត"</string>
- <string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាពក្រឡា"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាពក្រឡា"</string>
<string name="menu_list" msgid="7279285939892417279">"ទិដ្ឋភាពបញ្ជី"</string>
<string name="menu_sort" msgid="7677740407158414452">"តម្រៀបតាម"</string>
<string name="menu_search" msgid="3816712084502856974">"ស្វែងរក"</string>
<string name="menu_settings" msgid="6008033148948428823">"ការកំណត់"</string>
<string name="menu_open" msgid="432922957274920903">"បើក"</string>
<string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
- <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
+ <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
<string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
<string name="menu_select" msgid="8711270657353563424">"ជ្រើស \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
<string name="mode_selected_count" msgid="459111894725594625">"បានជ្រើស <xliff:g id="COUNT">%1$d</xliff:g>"</string>
@@ -48,7 +48,7 @@
<string name="pref_advanced_devices" msgid="903257239609301276">"បង្ហាញឧបករណ៍កម្រិតខ្ពស់"</string>
<string name="pref_file_size" msgid="2826879315743961459">"បង្ហាញទំហំឯកសារ"</string>
<string name="pref_device_size" msgid="3542106883278997222">"បង្ហាញទំហំឧបករណ៍"</string>
- <string name="empty" msgid="7858882803708117596">"គ្មានធាតុ"</string>
+ <string name="empty" msgid="7858882803708117596">"គ្មានធាតុ"</string>
<string name="toast_no_application" msgid="1339885974067891667">"មិនអាចបើកឯកសារ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"មិនអាចលុបឯកសារមួយចំនួន"</string>
<string name="share_via" msgid="8966594246261344259">"ចែករំលែកតាម"</string>
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
index a804c8c..a8e330b 100644
--- a/packages/Keyguard/res/layout/keyguard_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -41,28 +41,16 @@
android:layout_weight="1"
android:layoutDirection="ltr"
>
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/row0"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:orientation="horizontal"
android:layout_weight="1"
>
- <TextView android:id="@+id/pinEntry"
- android:editable="true"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
- android:singleLine="true"
- android:cursorVisible="false"
- android:background="@null"
- android:textAppearance="@style/TextAppearance.NumPadKey"
- android:imeOptions="flagForceAscii|actionDone"
- />
- <ImageButton android:id="@+id/delete_button"
+ <ImageButton android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_alignParentEnd="true"
android:gravity="center_vertical"
android:src="@drawable/ic_input_delete"
android:clickable="true"
@@ -73,13 +61,30 @@
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/keyboardview_keycode_delete"
/>
- </LinearLayout>
- <View
- android:layout_width="wrap_content"
- android:layout_height="1dp"
- android:background="#55FFFFFF"
- />
+ <TextView android:id="@+id/pinEntry"
+ android:editable="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_toStartOf="@+id/delete_button"
+ android:layout_alignParentStart="true"
+ android:gravity="center"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:cursorVisible="false"
+ android:background="@null"
+ android:textAppearance="@style/TextAppearance.NumPadKey"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_alignParentBottom="true"
+ android:background="#55FFFFFF"
+ />
+ </RelativeLayout>
<LinearLayout
+ android:id="@+id/row1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
@@ -114,6 +119,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
@@ -148,6 +154,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
@@ -182,6 +189,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index 18b59f1..a2e54a7 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -83,7 +83,7 @@
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
@@ -120,7 +120,7 @@
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index 3830df7..01d9ab3 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -161,4 +161,6 @@
<dimen name="widget_big_font_size">68dp</dimen>
<dimen name="big_font_size">120dp</dimen>
+ <!-- The y translation to apply at the start in appear animations. -->
+ <dimen name="appear_y_translation_start">24dp</dimen>
</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
new file mode 100644
index 0000000..ea896d5
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
@@ -0,0 +1,99 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+/**
+ * A class to make nice appear transitions for views in a tabular layout.
+ */
+public class AppearAnimationUtils {
+
+ public static final long APPEAR_DURATION = 220;
+
+ private final Interpolator mLinearOutSlowIn;
+ private final float mStartTranslation;
+
+ public AppearAnimationUtils(Context ctx) {
+ mLinearOutSlowIn = AnimationUtils.loadInterpolator(
+ ctx, android.R.interpolator.linear_out_slow_in);
+ mStartTranslation =
+ ctx.getResources().getDimensionPixelOffset(R.dimen.appear_y_translation_start);
+ }
+
+ public void startAppearAnimation(View[][] views, final Runnable finishListener) {
+ long maxDelay = 0;
+ ViewPropertyAnimator maxDelayAnimator = null;
+ for (int row = 0; row < views.length; row++) {
+ View[] columns = views[row];
+ for (int col = 0; col < columns.length; col++) {
+ long delay = calculateDelay(row, col);
+ ViewPropertyAnimator animator = startAppearAnimation(columns[col], delay);
+ if (animator != null && delay > maxDelay) {
+ maxDelay = delay;
+ maxDelayAnimator = animator;
+ }
+ }
+ }
+ if (maxDelayAnimator != null) {
+ maxDelayAnimator.setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishListener.run();
+ }
+ });
+ } else {
+ finishListener.run();
+ }
+ }
+
+ private ViewPropertyAnimator startAppearAnimation(View view, long delay) {
+ if (view == null) return null;
+ view.setAlpha(0f);
+ view.setTranslationY(mStartTranslation);
+ view.animate()
+ .alpha(1f)
+ .translationY(0)
+ .setInterpolator(mLinearOutSlowIn)
+ .setDuration(APPEAR_DURATION)
+ .setStartDelay(delay)
+ .setListener(null);
+ if (view.hasOverlappingRendering()) {
+ view.animate().withLayer();
+ }
+ return view.animate();
+ }
+
+ private long calculateDelay(int row, int col) {
+ return (long) (row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20);
+ }
+
+ public TimeInterpolator getInterpolator() {
+ return mLinearOutSlowIn;
+ }
+
+ public float getStartTranslation() {
+ return mStartTranslation;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index 4dfda91..1f3c176 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -22,6 +22,7 @@
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TextView.OnEditorActionListener;
/**
@@ -30,12 +31,21 @@
public class KeyguardPINView extends KeyguardAbsKeyInputView
implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+ private final AppearAnimationUtils mAppearAnimationUtils;
+ private ViewGroup mKeyguardBouncerFrame;
+ private ViewGroup mRow0;
+ private ViewGroup mRow1;
+ private ViewGroup mRow2;
+ private ViewGroup mRow3;
+ private View mDivider;
+
public KeyguardPINView(Context context) {
this(context, null);
}
public KeyguardPINView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mAppearAnimationUtils = new AppearAnimationUtils(context);
}
protected void resetState() {
@@ -56,6 +66,12 @@
protected void onFinishInflate() {
super.onFinishInflate();
+ mKeyguardBouncerFrame = (ViewGroup) findViewById(R.id.keyguard_bouncer_frame);
+ mRow0 = (ViewGroup) findViewById(R.id.row0);
+ mRow1 = (ViewGroup) findViewById(R.id.row1);
+ mRow2 = (ViewGroup) findViewById(R.id.row2);
+ mRow3 = (ViewGroup) findViewById(R.id.row3);
+ mDivider = findViewById(R.id.divider);
final View ok = findViewById(R.id.key_enter);
if (ok != null) {
ok.setOnClickListener(new View.OnClickListener() {
@@ -117,8 +133,45 @@
@Override
public void startAppearAnimation() {
- // TODO: Fancy animation.
- setAlpha(0);
- animate().alpha(1).withLayer().setDuration(200);
+ enableClipping(false);
+ setTranslationY(mAppearAnimationUtils.getStartTranslation());
+ animate()
+ .setDuration(500)
+ .setInterpolator(mAppearAnimationUtils.getInterpolator())
+ .translationY(0);
+ mAppearAnimationUtils.startAppearAnimation(new View[][] {
+ new View[] {
+ mRow0, null, null
+ },
+ new View[] {
+ findViewById(R.id.key1), findViewById(R.id.key2), findViewById(R.id.key3)
+ },
+ new View[] {
+ findViewById(R.id.key4), findViewById(R.id.key5), findViewById(R.id.key6)
+ },
+ new View[] {
+ findViewById(R.id.key7), findViewById(R.id.key8), findViewById(R.id.key9)
+ },
+ new View[] {
+ null, findViewById(R.id.key0), findViewById(R.id.key_enter)
+ },
+ new View[] {
+ null, mEcaView, null
+ }},
+ new Runnable() {
+ @Override
+ public void run() {
+ enableClipping(true);
+ }
+ });
+ }
+
+ private void enableClipping(boolean enable) {
+ mKeyguardBouncerFrame.setClipToPadding(enable);
+ mKeyguardBouncerFrame.setClipChildren(enable);
+ mRow1.setClipToPadding(enable);
+ mRow2.setClipToPadding(enable);
+ mRow3.setClipToPadding(enable);
+ setClipChildren(enable);
}
}
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index ba3c042..c89f9bf 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -60,7 +60,7 @@
</plurals>
<string name="cancel" msgid="4373674107267141885">"បោះបង់"</string>
<string name="restart" msgid="2472034227037808749">"ចាប់ផ្ដើមឡើងវិញ"</string>
- <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មានការភ្ជាប់ទៅម៉ាស៊ីនបោះពុម្ព"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មានការភ្ជាប់ទៅម៉ាស៊ីនបោះពុម្ព"</string>
<string name="reason_unknown" msgid="5507940196503246139">"មិនស្គាល់"</string>
<string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិនអាចប្រើបាន"</string>
<string name="print_error_default_message" msgid="8568506918983980567">"មិនអាចបង្កើតការងារបោះពុម្ព"</string>
diff --git a/packages/SettingsProvider/res/values-fr/defaults.xml b/packages/SettingsProvider/res/values-fr/defaults.xml
new file mode 100644
index 0000000..295b4f5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-fr/defaults.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rCN/defaults.xml b/packages/SettingsProvider/res/values-zh-rCN/defaults.xml
new file mode 100644
index 0000000..295b4f5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-zh-rCN/defaults.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+</resources>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 936f73b..9bf42b2 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
>
- <com.android.systemui.statusbar.phone.SwipeAffordanceView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/camera_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -30,10 +30,9 @@
android:tint="#ffffffff"
android:src="@drawable/ic_camera_alt_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_camera_button"
- systemui:swipeDirection="start"/>
+ android:contentDescription="@string/accessibility_camera_button" />
- <com.android.systemui.statusbar.phone.SwipeAffordanceView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/phone_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -41,8 +40,7 @@
android:tint="#ffffffff"
android:src="@drawable/ic_phone_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_phone_button"
- systemui:swipeDirection="end"/>
+ android:contentDescription="@string/accessibility_phone_button" />
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text"
@@ -54,15 +52,13 @@
android:textColor="#ffffff"
android:textAppearance="?android:attr/textAppearanceSmall"/>
- <ImageView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/lock_icon"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:scaleType="center"
- android:alpha="0.7"
- android:layerType="hardware"
- android:tint="#ffffffff"/>
+ android:tint="#ffffffff" />
</com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml
index bc7288d..046862f 100644
--- a/packages/SystemUI/res/layout/volume_panel.xml
+++ b/packages/SystemUI/res/layout/volume_panel.xml
@@ -24,6 +24,7 @@
android:id="@+id/slider_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:minHeight="64dip"
android:layout_toLeftOf="@+id/expand_button_divider" />
<ImageView
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index ae04bf5..0936cc2 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -21,7 +21,9 @@
android:layout_height="wrap_content"
android:background="@color/system_primary_color"
android:orientation="vertical"
- android:padding="@dimen/qs_panel_padding" >
+ android:paddingTop="@dimen/qs_panel_padding"
+ android:paddingLeft="@dimen/qs_panel_padding"
+ android:paddingRight="@dimen/qs_panel_padding" >
<TextView
android:id="@android:id/title"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e43464c..c45254e 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Ligging <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Wekker gestel vir <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Maak paneel toe"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Meer tyd"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Minder tyd"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data gedeaktiveer"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data gedeaktiveer"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobieldata gedeaktiveer"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellings"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"USB-verbinding"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Warmkol"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Kennisgewings"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ONLANGS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Programinligting"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tik weer om oop te maak"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Sleep op om te ontsluit"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Totdat jy dit afskakel"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Een minuut lank"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d minute lank"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Een uur lank"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d uur lank"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index ce3d14b..5c4d98b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ብሉቱዝ <xliff:g id="STATE">%s</xliff:g>።"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"አካባቢ <xliff:g id="STATE">%s</xliff:g>።"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ማንቂያ ለ<xliff:g id="TIME">%s</xliff:g> ተዋቅሯል።"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G ውሂብ ቦዝኗል"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G ውሂብ ቦዝኗል"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"የተንቀሳቃሽ ውሂብ ቦዝኗል"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"ተጨማሪ ቅንብሮች"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"በማገናኘት ላይ"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"መገናኛ ነጥብ"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"የቅርብ ጊዜዎች"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"የመተግበሪያ መረጃ"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"ለመክፈት ዳግም መታ ያድርጉ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ለማስከፈት ወደ ላይ ያንሸራትቱ"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c9ddc23..d7c5651 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"البلوتوث <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"حالة الموقع: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"تم ضبط المنبه على <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"إغلاق اللوحة"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"وقت أكثر"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"وقت أقل"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"تم تعطيل بيانات شبكات الجيل الثاني والجيل الثالث"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"تم تعطيل بيانات الجوال"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"المزيد من الإعدادات"</string>
<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="recents_empty_message" msgid="2269156590813544104">"الأخيرة"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"معلومات التطبيق"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"انقر مرة أخرى للفتح"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"مرر سريعًا لأعلى لإلغاء القفل"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"لحين تعطيل هذا الإعداد"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"لمدة دقيقة واحدة"</item>
+ <item quantity="other" msgid="6924190729213550991">"لمدة %d من الدقائق"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"لمدة ساعة واحدة"</item>
+ <item quantity="other" msgid="5408537517529822157">"لمدة %d من الساعات"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d396b8c..2405804 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Местоположението е <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Будилникът е навит за <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Затваряне на панела"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Повече време"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"По-малко време"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G данните са деактивирани"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G данните са деактивирани"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобилните данни са деактивирани"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Още настройки"</string>
<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="recents_empty_message" msgid="2269156590813544104">"СКОРОШНИ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Информация за приложението"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Докоснете отново, за да отворите"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Прекарайте пръст нагоре, за да отключите"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Докато не изключите това"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"За една минута"</item>
+ <item quantity="other" msgid="6924190729213550991">"За %d минути"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"За един час"</item>
+ <item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 51790b5..982e0c6 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Ubicació: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarma establerta a les <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Tanca el tauler."</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Més temps"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Menys temps"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dades 2G-3G desactivades"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dades 4G desactivades"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dades mòbils desactivades"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Més opcions"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Ancoratge a xarxa"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificacions"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informació de l\'aplicació"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Torna a tocar per obrir-la."</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Fes lliscar el dit cap amunt per desbloquejar el teclat."</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Fins que no ho desactivis"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Durant un minut"</item>
+ <item quantity="other" msgid="6924190729213550991">"Durant %d minuts"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Durant una hora"</item>
+ <item quantity="other" msgid="5408537517529822157">"Durant %d hores"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 91b8f6e..570e1bb 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Poloha: <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Budík je nastaven na <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zavřít panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Delší doba"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Kratší doba"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datové přenosy 2G a 3G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datové přenosy 4G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilní data jsou zakázána"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Další nastavení"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Sdílení datového připojení"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Oznámení"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"POSLEDNÍ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informace o aplikaci"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Oznámení otevřete opětovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zařízení odemknete přejetím prstem nahoru"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Dokud tuto funkci nevypnete"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Na jednu minutu"</item>
+ <item quantity="other" msgid="6924190729213550991">"Na %d min"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Na jednu hodinu"</item>
+ <item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1d1ca0a2..127192a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Placering <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmen er indstillet til <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Luk panelet"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Mere tid"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mindre tid"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktiveret"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktiveret"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktiveret"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Flere indstillinger"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Netdeling"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Underretninger"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"SENESTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Oplysninger om applikationen"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende underretninger nedenfor"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tryk igen for at åbne"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Stryg for at låse op"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Indtil du slår denne indstilling fra"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"I ét minut"</item>
+ <item quantity="other" msgid="6924190729213550991">"I %d minutter"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"I én time"</item>
+ <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index a79193d..c9c7b8e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Standort <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Wecker gestellt für <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Fenster schließen"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Mehr Zeit"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Weniger Zeit"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilfunk Daten deaktiviert"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Weitere Einstellungen"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Benachrichtigungen"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"Letzte"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zum Entsperren nach oben wischen"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Bis zur Deaktivierung"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Für eine Minute"</item>
+ <item quantity="other" msgid="6924190729213550991">"Für %d Minuten"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Für eine Stunde"</item>
+ <item quantity="other" msgid="5408537517529822157">"Für %d Stunden"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 32b7090..1d90dae 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Τοποθεσία <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Το ξυπνητήρι έχει οριστεί στις <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Κλείσιμο παραθύρου"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Περισσότερος χρόνος"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Λιγότερος χρόνος"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Τα δεδομένα 2G-3G απενεργοποιήθηκαν"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Τα δεδομένα 4G απενεργοποιήθηκαν"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Τα δεδομένα κινητής τηλεφωνίας απενεργοποιήθηκαν"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Περισσότερες ρυθμίσεις"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Πρόσδεση"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Σημείο πρόσβασης Wi-Fi"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ειδοποιήσεις"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ΠΡΟΣΦΑΤΑ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Πληροφορίες εφαρμογής"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Πατήστε ξανά για να ανοίξετε"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Σύρετε για να ξεκλειδώσετε"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Μέχρι να το απενεργοποιήσετε"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Για ένα λεπτό"</item>
+ <item quantity="other" msgid="6924190729213550991">"Για %d λεπτά"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Για μία ώρα"</item>
+ <item quantity="other" msgid="5408537517529822157">"Για %d ώρες"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index d26cfae..a9c6678 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Location <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Close panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"More time"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Less time"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data disabled"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data disabled"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile data disabled"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"For one minute"</item>
+ <item quantity="other" msgid="6924190729213550991">"For %d minutes"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"For one hour"</item>
+ <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index d26cfae..a9c6678 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Location <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Close panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"More time"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Less time"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data disabled"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data disabled"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile data disabled"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"For one minute"</item>
+ <item quantity="other" msgid="6924190729213550991">"For %d minutes"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"For one hour"</item>
+ <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c93fbf6..6ca4ebc 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Ubicación <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarma: <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Cerrar panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Más tiempo"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Menos tiempo"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos de 2G-3G inhabilitados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos de 4G inhabilitados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Se inhabilitaron los datos móviles"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Más configuraciones"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Anclaje a red"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Presionar de nuevo para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslizar el dedo hacia arriba para desbloquear"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Hasta que lo desactives"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Durante un minuto"</item>
+ <item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Durante una hora"</item>
+ <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3bded8b..d0e9c0a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Ubicación <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"La alarma sonará a la(s) <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Cerrar panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Más tiempo"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Menos tiempo"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos 2G-3G inhabilitados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos 4G inhabilitados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datos móviles inhabilitados"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Más opciones"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Anclaje a red"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Toca de nuevo para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Desliza el dedo hacia arriba para desbloquear"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Hasta apagar el dispositivo"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Durante un minuto"</item>
+ <item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Durante una hora"</item>
+ <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 1979c55..c692b28 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Asukoht: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Määratud äratus: <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Sule paneel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Rohkem aega"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Vähem aega"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G andmeside keelatud"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G andmeside keelatud"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilne andmeside keelatud"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Rohkem seadeid"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jagamine"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Leviala"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Märguanded"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"HILJUTISED"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduste teave"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
@@ -224,4 +228,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Avamiseks puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Lukustuse tühistamiseks pühkige üles"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Kuni lülitate selle välja"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Üheks minutiks"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d minutiks"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Üheks tunniks"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d tunniks"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 399740a..ee2c48d 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"بلوتوث <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"مکان <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"هشدار برای <xliff:g id="TIME">%s</xliff:g> تنظیم شد."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"بستن پانل"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"زمان بیشتر"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"زمان کمتر"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"داده 2G-3G غیرفعال شد"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"داده 4G غیر فعال شد"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"دادههای تلفن همراه غیرفعال است"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"تنظیمات بیشتر"</string>
<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="recents_empty_message" msgid="2269156590813544104">"موارد اخیر"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"اطلاعات برنامه"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"برای باز کردن دوباره ضربه بزنید"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"برای باز کردن قفل سریع به بالا بکشید"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"تا وقتی آن را خاموش کنید"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"برای یک دقیقه"</item>
+ <item quantity="other" msgid="6924190729213550991">"برای %d دقیقه"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"برای یک ساعت"</item>
+ <item quantity="other" msgid="5408537517529822157">"برای %d ساعت"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index be7eb9b..44d35b3 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Sijainti <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Hälytys asetettu, aika: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Sulje paneeli"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Lisää aikaa"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Vähennä aikaa"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilitiedonsiirto pois käytöstä"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Lisäasetukset"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jaettu yhteys"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ilmoitukset"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"VIIMEISIMMÄT"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Sovellustiedot"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Avaa napauttamalla uudelleen"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Avaa lukitus pyyhkäisemällä ylös"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Kunnes poistat tämän käytöstä"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Minuutiksi"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d minuutiksi"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Tunniksi"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d tunniksi"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 390ec81..d9790f6 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth : <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Localisation <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Données 2G-3G désactivées"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Données 4G désactivées"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Données mobiles désactivées"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès sans fil"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Détails de l\'application"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Touchez à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Glissez vers le haut pour déverrouiller"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a0c5cfe..d95fe06 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth : <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Localisation <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Données 2G-3G désactivées"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Données 4G désactivées"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Données mobiles désactivées"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informations sur l\'application"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Appuyer à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Faire glisser pour déverrouiller"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 6850b3d..60d7de1 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"स्थान <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> के लिए अलार्म सेट किया गया."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"फलक बंद करें"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"अधिक समय"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"कम समय"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G डेटा अक्षम"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G डेटा अक्षम"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"मोबाइल डेटा अक्षम"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"और सेटिंग"</string>
<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="recents_empty_message" msgid="2269156590813544104">"हाल ही का"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"एप्लिकेशन जानकारी"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"खोलने के लिए पुन: टैप करें"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करने के लिए ऊपर स्वाइप करें"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"जब तक आप इसे बंद नहीं कर देते"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"एक मिनट के लिए"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d मिनट के लिए"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"एक घंटे के लिए"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d घंटे के लिए"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b00c382..09dde42 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth – <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokacija <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Vrijeme alarma: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zatvori ploču"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Više vremena"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Manje vremena"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Onemogućeni su 2G-3G podaci"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Onemogućeni su 4G podaci"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Onemogućeni su mobilni podaci"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Više postavki"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Žarišna točka"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavijesti"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNO"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite opet za otvaranje"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Prijeđite prstom prema gore za otključavanje"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Dok ne isključite"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Jednu minutu"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d min"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Jedan sat"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d h"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b75c7f3..dc85416 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Helyadatok: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Ébresztés időpontja: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Panel bezárása"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Több idő"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Kevesebb idő"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil adatforgalom letiltva"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"További beállítások"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Megosztás"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Értesítések"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"LEGUTÓBBIAK"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Az alkalmazás adatai"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Koppintson rá ismét a megnyitáshoz"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Húzza felfelé az ujját a feloldáshoz"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Amíg ki nem kapcsolja ezt"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Egy percen át"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d percen át"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Egy órán át"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d órán át"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 904b998..b11a004 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth-ը <xliff:g id="STATE">%s</xliff:g> է:"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Տեղադրությունը՝ <xliff:g id="STATE">%s</xliff:g>:"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Զարթուցիչը դրված է <xliff:g id="TIME">%s</xliff:g>-ին:"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G տվյալները անջատված են"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G տվյալները անջատված են"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Շարժական տվյալները անջատված են"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Հավելյալ կարգավորումներ"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Միացում"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Թեժ կետ"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"ՎԵՐՋԻՆՆԵՐԸ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Հավելվածի մասին"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Կրկին հպեք՝ բացելու համար"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Սահեցրեք վերև` ապակողպելու համար"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 98373c9..f62209f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokasi <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm disetel ke <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Tutup panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Lebih lama"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Lebih cepat"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dinonaktifkan"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dinonaktifkan"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data seluler dinonaktifkan"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Setelan lainnya"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Menambatkan"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pemberitahuan"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"TERBARU"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Info Aplikasi"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang darurat di bawah"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Gesek ke atas untuk membuka kunci"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Hingga Anda menonaktifkan ini"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Selama satu menit"</item>
+ <item quantity="other" msgid="6924190729213550991">"Selama %d menit"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Selama satu jam"</item>
+ <item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 412d001..6cf13be 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Posizione: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Allarme impostato per: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Chiudi riquadro"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Più tempo"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Meno tempo"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dati 2G-3G disattivati"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dati 4G disattivati"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dati mobili disattivati"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Altre impostazioni"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifiche"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"MESSAGGI RECENTI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informazioni sull\'applicazione"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tocca ancora per aprire"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Scorri verso l\'alto per sbloccare"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Fino alla disattivazione"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Per un minuto"</item>
+ <item quantity="other" msgid="6924190729213550991">"Per %d minuti"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Per un\'ora"</item>
+ <item quantity="other" msgid="5408537517529822157">"Per %d ore"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 33a6701..4f07006 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"המיקום <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ההתראה נקבעה ל-<xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"סגור חלונית"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"יותר זמן"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"פחות זמן"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"נתוני 2G-3G מושבתים"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"נתוני 4G מושבתים"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"נתונים לנייד מושבתים"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"הגדרות נוספות"</string>
<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="recents_empty_message" msgid="2269156590813544104">"אחרונים"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"מידע על האפליקציה"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"הודעות בדחיפות נמוכה יותר בהמשך"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"הקש שוב כדי לפתוח"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"החלק מעלה כדי לבטל את הנעילה"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"עד שתכבה"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"למשך דקה אחת"</item>
+ <item quantity="other" msgid="6924190729213550991">"למשך %d דקות"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"למשך שעה אחת"</item>
+ <item quantity="other" msgid="5408537517529822157">"למשך %d שעות"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 3ed729b..84bbf8b 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"現在地: <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"アラームは<xliff:g id="TIME">%s</xliff:g>に設定されています。"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G~3Gデータが無効になりました"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4Gデータが無効になりました"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"モバイルデータが無効になりました"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"詳細設定"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"テザリング"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"アクセスポイント"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"アプリ情報"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"開くにはもう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ロック解除するには上にスワイプしてください"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 409b9ba..c31ea24 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"მდებარეობა <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"მაღვიძარა დაყენებულია: <xliff:g id="TIME">%s</xliff:g>"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G ინტერნეტი გაითიშა."</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G მონაცემები გათიშულია"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"მობილური ინტერნეტი გაითიშა."</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"დამატებითი პარამეტრები"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"მოდემის რეჟიმი"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"წვდომის წერტილი"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"ბოლო დროის"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"აპლიკაციის შესახებ"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"შეეხეთ ისევ გასახსნელად"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"გაასრიალეთ ზევით განსაბლოკად"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index f3b4e9e..a9cf7d6 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -64,7 +64,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"កំពុងរក្សាទុករូបថតអេក្រង់…"</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"កំពុងរក្សាទុករូបថតអេក្រង់..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"រូបថតអេក្រង់កំពុងត្រូវបានរក្សាទុក។"</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"ប៉ះ ដើម្បីមើលរូបថតអេក្រង់របស់អ្នក។"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"មិនអាចចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_failed_text" msgid="8134011269572415402">"មិនអាចរក្សាទុករូបថតអេក្រង់។ ឧបករណ៍ផ្ទុកអាចកំពុងប្រើ។"</string>
@@ -140,7 +140,7 @@
<string name="accessibility_remove_notification" msgid="3603099514902182350">"សម្អាតការជូនដំណឹង។"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"បានបើក GPS ។"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ទទួល GPS ។"</string>
- <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"កម្មវិធីរោទ៍ញ័រ។"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"កម្មវិធីរោទ៍ស្ងាត់។"</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string>
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ប៊្លូធូស <xliff:g id="STATE">%s</xliff:g> ។"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"ទីតាំង <xliff:g id="STATE">%s</xliff:g> ។"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"កំណត់សំឡេងរោទ៍សម្រាប់ <xliff:g id="TIME">%s</xliff:g> ។"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"បិទបន្ទះ"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"ពេលច្រើនជាង"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"ពេលតិចជាង"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"បានបិទទិន្នន័យ 2G-3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"បានបិទទិន្នន័យ 4G"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"បានបិទទិន្នន័យចល័ត"</string>
@@ -187,7 +190,7 @@
<string name="quick_settings_rotation_locked_portrait_label" msgid="1553131290066230775">"ចាក់សោបញ្ឈរ"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ចាក់សោផ្ដេក"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"វិធីសាស្ត្របញ្ចូល"</string>
- <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
+ <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"ទីតាំងបានបិទ"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"ឧបករណ៍មេឌៀ"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
@@ -207,10 +210,11 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"ការកំណត់ច្រើនទៀត"</string>
<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="recents_empty_message" msgid="2269156590813544104">"ថ្មីៗ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ព័ត៌មានកម្មវិធី"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
- <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
+ <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
<string name="description_direction_up" msgid="7169032478259485180">"រុញឡើងលើដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
<string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"ប៉ះម្ដងទៀត ដើម្បីបើក"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"អូសឡើងលើ ដើម្បីដោះសោ"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"រហូតដល់ពេលអ្នកបិទវា"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"សម្រាប់មួយនាទី"</item>
+ <item quantity="other" msgid="6924190729213550991">"សម្រាប់ %d នាទី"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"សម្រាប់មួយម៉ោង"</item>
+ <item quantity="other" msgid="5408537517529822157">"សម្រាប់ %d ម៉ោង"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 2b39e14..bb2e5c1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"블루투스 <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"위치 <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"알람이 <xliff:g id="TIME">%s</xliff:g>(으)로 설정되었습니다."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"패널 닫기"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"시간 늘리기"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"시간 줄이기"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G 데이터 사용중지됨"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 데이터 사용중지됨"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"모바일 데이터 사용중지됨"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"설정 더보기"</string>
<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="recents_empty_message" msgid="2269156590813544104">"최근"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"애플리케이션 정보"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"다시 탭하여 열기"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"위로 스와이프하여 잠금 해제"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"이 기능을 사용 중지할 때까지"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"1분 동안"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d분 동안"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"1시간 동안"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d시간 동안"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 5d2ccbc..7220777 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"ສະຖານທີ່ <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ຕັ້ງໂມງປຸກ <xliff:g id="TIME">%s</xliff:g> ແລ້ວ."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"ປິດແຖບ"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"ເພີ່ມເວລາ"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"ຫຼຸດເວລາ"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"ອິນເຕີເນັດ 2G, 3G ຖືກປິດແລ້ວ"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ການນຳໃຊ້ຂໍ້ມູນ 4G ຖືກປິດແລ້ວ"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ອິນເຕີເນັດໃນມືຖືຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"ການຕັ້ງຄ່າເພີ່ມເຕີມ"</string>
<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="recents_empty_message" msgid="2269156590813544104">"ບໍ່ດົນມານີ້"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ຂໍ້ມູນແອັບພລິເຄຊັນ"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"ແຕະອີກຄັ້ງເພື່ອເປີດ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ເລື່ອນຂຶ້ນເພື່ອປົດລັອກ"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າທ່ານຈະປິດ"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"ສຳລັບນຶ່ງນາທີ"</item>
+ <item quantity="other" msgid="6924190729213550991">"ສຳລັບ %d ນາທີ"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"ສຳລັບນຶ່ງຊົ່ວໂມງ"</item>
+ <item quantity="other" msgid="5408537517529822157">"ສຳລັບ %d ຊົ່ວໂມງ"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index cede14c..d0ebd54 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"„Bluetooth“ <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Vietovė – <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Signalas nustatytas <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Uždaryti skydelį"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Daugiau laiko"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mažiau laiko"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G duomenys neleidžiami"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G duomenys neleidžiami"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilieji duomenys neleidžiami"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Daugiau nustatymų"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Susiejimas"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Viešosios interneto prieigos taškas"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pranešimai"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"PASTARIEJI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Programos informacija"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Palieskite dar kartą, kad atidarytumėte"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Perbraukite aukštyn, kad atrakintumėte"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Kol išjungsite"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"1 min."</item>
+ <item quantity="other" msgid="6924190729213550991">"%d min."</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"1 val."</item>
+ <item quantity="other" msgid="5408537517529822157">"%d val."</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 280ce40..23ce4a9 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth statuss: <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Atrašanās vieta: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Signāls ir iestatīts uz: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Aizvērt paneli"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Ilgāk"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mazāks laiks"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G dati atspējoti"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G dati atspējoti"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilie dati atspējoti"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Vairāk iestatījumu"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Piesaiste"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tīklājs"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Paziņojumi"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"JAUNĀKIE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informācija par lietojumprogrammu"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Pieskarieties vēlreiz, lai atvērtu"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Velciet uz augšu, lai atbloķētu"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Līdz brīdim, kad izslēgsiet"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Vienu minūti"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d min"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Vienu stundu"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d h"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 773a6fb..c00b7ed 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Блютүүт <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Байршил <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Сэрүүлгийг <xliff:g id="TIME">%s</xliff:g>-д тохируулсан."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G дата идэвхгүй болов"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G дата идэвхгүй байна"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобайл дата идэвхгүй болов"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Өөр тохиргоо"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Модем болгох"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Сүлжээний цэг"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"СҮҮЛИЙН"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Аппликешны мэдээлэл"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Нээхийн тулд дахин товшино уу"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Түгжээг тайлах бол шудрана уу"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 82216de1..263fc46 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokasi <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Penggera ditetapkan pada <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dilumpuhkan"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dilumpuhkan"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data mudah alih dilumpuhkan"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Lagi tetapan"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Penambatan"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tempat liputan"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"TERBAHARU"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Maklumat Aplikasi"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Ketik lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Leret ke atas untuk membuka kunci"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7ffd381..75706a2 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth – <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Posisjon <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmen ble stilt for <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Lukk panelet"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Mer tid"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mindre tid"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktivert"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktivert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktivert"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Flere innstillinger"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tilknytning"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Wi-Fi-sone"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Varsler"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NYLIGE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformasjon"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Trykk på nytt for å åpne"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Sveip oppover for å låse opp"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Inntil du slår av funksjonen"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"I ett minutt"</item>
+ <item quantity="other" msgid="6924190729213550991">"I %d minutter"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"I én time"</item>
+ <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index e79adf9..c4bef68 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Locatie <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm is ingesteld op <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Deelvenster sluiten"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Meer tijd"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Minder tijd"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-gegevens uitgeschakeld"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-gegevens uitgeschakeld"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiele gegevens uitgeschakeld"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellingen"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-informatie"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tik nogmaals om te openen"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Veeg omhoog om te ontgrendelen"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Totdat u dit uitschakelt"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Eén minuut"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d minuten"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Eén uur"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d uur"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index aec7e87..825dfec 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokalizacja <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zamknij panel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Więcej czasu"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mniej czasu"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Transmisja danych została wyłączona"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Więcej ustawień"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Powiązanie"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Punkt dostępu"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Powiadomienia"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"OSTATNIE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacje o aplikacji"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Kliknij ponownie, by otworzyć"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Przesuń w górę, by odblokować"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Dopóki nie wyłączysz"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Przez minutę"</item>
+ <item quantity="other" msgid="6924190729213550991">"Przez %d min"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Przez godzinę"</item>
+ <item quantity="other" msgid="5408537517529822157">"Przez %d godz."</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 93c7f60..f9ac828 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Localização <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Fechar painel"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Mais tempo"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Menos tempo"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Os dados 2G-3G estão desativados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Os dados 4G estão desativados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Os dados móveis estão desativados"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Mais definições"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Associação"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificações"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações da aplicação"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslizar rapidamente com o dedo para cima para desbloquear"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Até que o utilizador desative"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Durante um minuto"</item>
+ <item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Durante uma hora"</item>
+ <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b0e58e4..1c13e62 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Localização <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dados 2G e 3G desativados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dados 4G desativados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dados móveis desativados"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do aplicativo"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslize para cima para desbloquear"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index b9d121a..00bf8c0 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -282,6 +282,12 @@
<skip />
<!-- no translation found for accessibility_quick_settings_alarm (3959908972897295660) -->
<skip />
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
<!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
@@ -384,6 +390,8 @@
<skip />
<!-- no translation found for quick_settings_hotspot_label (6046917934974004879) -->
<skip />
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<!-- no translation found for recents_empty_message (2269156590813544104) -->
<skip />
<!-- no translation found for recents_app_info_button_label (2890317189376000030) -->
@@ -411,4 +419,10 @@
<skip />
<!-- no translation found for keyguard_unlock (8043466894212841998) -->
<skip />
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index c48733f..7ffa77c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Locație: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmă setată pentru <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datele 2G-3G au fost dezactivate"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datele 4G au fost dezactivate"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datele mobile au fost dezactivate"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Mai multe setări"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informații despre aplicație"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Atingeți din nou pentru a deschide"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Glisați în sus pentru a debloca"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index c726014..d726428 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Доступ к геоданным <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Будильник установлен на <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Закрыть панель."</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Увеличить продолжительность."</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Уменьшить продолжительность."</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Передача данных по каналам 2G и 3G отключена"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Передача данных по каналу 4G отключена"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Моб. Интернет отключен"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Дополнительные настройки"</string>
<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="recents_empty_message" msgid="2269156590813544104">"НЕДАВНИЕ СООБЩЕНИЯ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Сведения о приложении"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные оповещения"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Нажмите ещё раз, чтобы открыть"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Для разблокировки проведите пальцем по экрану"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Пока я не отключу"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"1 мин."</item>
+ <item quantity="other" msgid="6924190729213550991">"%d мин."</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"1 ч."</item>
+ <item quantity="other" msgid="5408537517529822157">"%d ч."</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 45bb2ad..8debc9a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Poloha: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Budík nastavený na <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dátové prenosy 2G a 3G sú zakázané"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dátové prenosy 4G sú zakázané"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilné dátové prenosy sú zakázané"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Ďalšie nastavenia"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Zdieľanie dátového pripojenia"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"NEDÁVNE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informácie o aplikácii"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Upozornenie otvoríte opätovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zariadenie odomknete prejdením prstom nahor"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 99470d6..6171c16 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokacija: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm je nastavljen na <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zapri podokno"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Daljši čas"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Krajši čas"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Podatki 2G-3G so onemogočeni"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Podatki 4G so onemogočeni"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilni podatki so onemogočeni"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Več nastavitev"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internet prek mobilne naprave"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Dostopna točka"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obvestila"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Podatki o aplikaciji"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Znova se dotaknite, da odprete"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Povlecite, da odklenete"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Dokler tega ne izklopite"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Za eno minuto"</item>
+ <item quantity="other" msgid="6924190729213550991">"Za %d min"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Za eno uro"</item>
+ <item quantity="other" msgid="5408537517529822157">"Za %d h"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1e40ed6..14782e6 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Локација је <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Аларм је подешен за <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Затворите таблу"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Више времена"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Мање времена"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G подаци су онемогућени"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G подаци су онемогућени"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Подаци мобилне мреже су онемогућени"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Још подешавања"</string>
<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="recents_empty_message" msgid="2269156590813544104">"НАЈНОВИЈЕ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Информације о апликацији"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Додирните поново да бисте отворили"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Превуците нагоре да бисте откључали"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Док не искључите"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Један минут"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d мин"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Један сат"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d с"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e4d7471..a7fb15d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Plats <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmet ringer <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Stäng panelen"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Längre tid"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Kortare tid"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data via 2G-3G har inaktiverats"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data via 4G har inaktiverats"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata har inaktiverats"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Fler inställningar"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internetdelning"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Trådlös surfzon"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Aviseringar"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NYA"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformation"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tryck igen för att öppna"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Dra uppåt om du vill låsa upp"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Tills du inaktiverar detta"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"I en minut"</item>
+ <item quantity="other" msgid="6924190729213550991">"I %d minuter"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"I en timme"</item>
+ <item quantity="other" msgid="5408537517529822157">"I %d timmar"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3525b5e..b8d8c58c 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -154,6 +154,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Mahali <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Kengele imewekwa <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data ya 2G-3G imelemazwa"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data ya 4G imelemazwa"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data ya kifaa cha mkononi imelemazwa"</string>
@@ -205,6 +211,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Mipangilio zaidi"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Kusambaza mtandao"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Mtandao-hewa"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"YA HIVI KARIBUNI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Maelezo ya Programu"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
@@ -224,4 +232,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Gonga tena ili ufungue"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Telezesha kidole ili ufungue"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 3217daa..dc75e78 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"บลูทูธ <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"สถานที่ <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ตั้งเวลาปลุกไว้ที่ <xliff:g id="TIME">%s</xliff:g>"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"ปิดใช้งานข้อมูล 2G-3G แล้ว"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ปิดใช้งานข้อมูล 4G แล้ว"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ปิดใช้งานข้อมูลมือถือแล้ว"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"การตั้งค่าเพิ่มเติม"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"การปล่อยสัญญาณ"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ฮอตสปอต"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"ล่าสุด"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ข้อมูลแอปพลิเคชัน"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"แตะอีกครั้งเพื่อเปิด"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"กวาดขึ้นเพื่อปลดล็อก"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 2f8ae2f..0713ddd 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"<xliff:g id="STATE">%s</xliff:g> ng Bluetooth."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokasyon <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set para sa <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Di pinapagana ang 2G-3G na data"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Hindi pinapagana ang 4G na data"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Hindi pinapagana ang data ng mobile"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Marami pang setting"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Nagte-tether"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"MGA KAMAKAILAN"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Impormasyon ng Application"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"I-tap ulit upang buksan"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Mag-swipe pataas upang i-unlock"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 506d27e..c0ba250 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -156,6 +156,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Konum: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm saati: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G verileri devre dışı bırakıldı"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G verileri devre dışı"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil veriler devre dışı"</string>
@@ -207,6 +213,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Diğer ayarlar"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"SON İLETİLER"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Uygulama Bilgileri"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
@@ -226,4 +234,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Açmak için tekrar hafifçe vurun"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Kilidi açmak için hızlıca yukarı kaydırın"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5b3c5b2..e149d7b 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Місцезнаходження <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Сигнал установлено на <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Закрити панель"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Більше часу"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Менше часу"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Дані 2G–3G вимкнено"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Дані 4G вимкнено"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобільне передавання даних вимкнено"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Більше налаштувань"</string>
<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="recents_empty_message" msgid="2269156590813544104">"ОСТАННІ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Інформація про додаток"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Торкніться знову, щоб відкрити"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Проведіть пальцем угору, щоб розблокувати"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Доки ви не вимкнете"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Протягом хвилини"</item>
+ <item quantity="other" msgid="6924190729213550991">"Протягом %d хв"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Протягом години"</item>
+ <item quantity="other" msgid="5408537517529822157">"Протягом %d год"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c6fddfe..f99c341 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Vị trí <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Báo thức được đặt cho <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Đóng bảng điều khiển"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Nhiều thời gian hơn"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Ít thời gian hơn"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Đã tắt dữ liệu 2G-3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Đã tắt dữ liệu 4G"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dữ liệu di động bị vô hiệu hóa"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Cài đặt khác"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Đang dùng làm điểm truy cập Internet"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Điểm phát sóng"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Thông báo"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"GẦN ĐÂY"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Thông tin ứng dụng"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Nhấn lại để mở"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Vuốt lên để mở khóa"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Cho đến khi bạn tắt tính năng này"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Trong một phút"</item>
+ <item quantity="other" msgid="6924190729213550991">"Trong %d phút"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Trong một giờ"</item>
+ <item quantity="other" msgid="5408537517529822157">"Trong %d giờ"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index d8e1c35..6940b2c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -158,6 +158,12 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"蓝牙:<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"位置信息服务<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"闹钟已设置为:<xliff:g id="TIME">%s</xliff:g>。"</string>
+ <!-- no translation found for accessibility_quick_settings_close (2571790856136835943) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_more_time (5778794273488176726) -->
+ <skip />
+ <!-- no translation found for accessibility_quick_settings_less_time (101026945195230084) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"移动数据网络已停用"</string>
@@ -209,6 +215,8 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"更多设置"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"网络共享"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"热点"</string>
+ <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
+ <skip />
<string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"应用信息"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
@@ -228,4 +236,10 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"再次点按即可打开"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上滑动即可解锁"</string>
+ <!-- no translation found for zen_mode_forever (7420011936770086993) -->
+ <skip />
+ <!-- no translation found for zen_mode_duration_minutes:one (9040808414992812341) -->
+ <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
+ <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
+ <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index ce9e260..04c00f5 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"藍牙:<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"定位服務<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"關閉面板"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"更多時間"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"更少時間"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"已停用 2G-3G 數據"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"已停用 4G 數據"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"已停用流動數據"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
<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="recents_empty_message" msgid="2269156590813544104">"近期"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資料"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上快速滑動即可解鎖"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"手動關閉這項設定前一律啟用"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"1 分鐘"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d 分鐘"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"1 小時"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index cafb688..4ffb01b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -158,6 +158,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"藍牙:<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"定位服務<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"關閉面板"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"更多時間"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"更少時間"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"已停用 2G-3G 數據"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"已停用 4G 數據"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"已停用行動數據"</string>
@@ -209,6 +212,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
<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="recents_empty_message" msgid="2269156590813544104">"近期"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資訊"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
@@ -228,4 +232,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上滑動即可解鎖"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"手動關閉這項設定前一律啟用"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"1 分鐘"</item>
+ <item quantity="other" msgid="6924190729213550991">"%d 分鐘"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"1 小時"</item>
+ <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 4865f7b..4c44972 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -156,6 +156,9 @@
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"I-Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Indawo i-<xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Vala iphaneli"</string>
+ <string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Isikhathi esiningi"</string>
+ <string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Isikhathi esingaphansi"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"idatha ye-2G-3G ivimbelwe"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Idatha ye-4G ivimbelwe"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Idatha yefoni ivimbelwe"</string>
@@ -207,6 +210,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Izilungiselelo eziningi"</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Ukusebenzisa njengemodemu"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"I-Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Izaziso"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"OKWAKAMUVA"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Ulwazi lohlelo lokusebenza"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
@@ -226,4 +230,13 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Thepha futhi ukuze uvule"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Swayiphela phezulu ukuze uvule"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"Uze uvale lokhu"</string>
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one" msgid="9040808414992812341">"Iminithi elilodwa"</item>
+ <item quantity="other" msgid="6924190729213550991">"Amaminithi angu-%d"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one" msgid="3480040795582254384">"Ihora elilodwa"</item>
+ <item quantity="other" msgid="5408537517529822157">"Amahora angu-%d"</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 3549689..c453618 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -43,12 +43,6 @@
<declare-styleable name="BatteryMeterView">
<attr name="frameColor" format="color" />
</declare-styleable>
- <declare-styleable name="SwipeAffordanceView">
- <attr name="swipeDirection" format="enum">
- <enum name="start" value="0" />
- <enum name="end" value="1" />
- </attr>
- </declare-styleable>
<declare-styleable name="Clock">
<attr name="amPmStyle" format="enum">
<enum name="normal" value="0" />
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6e35230..610b376 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -294,6 +294,9 @@
<dimen name="keyguard_clock_notifications_margin_min">22dp</dimen>
<dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
+ <!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
+ <dimen name="keyguard_min_swipe_amount">75dp</dimen>
+
<!-- Volume panel dialog y offset -->
<dimen name="volume_panel_top">16dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 41c0e78..4c7f3df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -202,6 +202,12 @@
checkPermission();
mKeyguardViewMediator.onBootCompleted();
}
+
+ @Override
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ checkPermission();
+ mKeyguardViewMediator.startKeyguardExitAnimation(fadeoutDuration);
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b2872fa..7110d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -46,7 +46,8 @@
import android.util.Log;
import android.util.Slog;
import android.view.ViewGroup;
-import android.view.WindowManager;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -137,6 +138,7 @@
private static final int SET_OCCLUDED = 12;
private static final int KEYGUARD_TIMEOUT = 13;
private static final int DISMISS = 17;
+ private static final int START_KEYGUARD_EXIT_ANIM = 18;
/**
* The default amount of time we stay awake (used for all key input)
@@ -180,6 +182,9 @@
/** High level access to the power manager for WakeLocks */
private PowerManager mPM;
+ /** High level access to the window manager for dismissing keyguard animation */
+ private IWindowManager mWM;
+
/** UserManager for querying number of users */
private UserManager mUserManager;
@@ -440,6 +445,7 @@
private void setup() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWM = WindowManagerGlobal.getWindowManagerService();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
@@ -1076,6 +1082,9 @@
case DISMISS:
handleDismiss();
break;
+ case START_KEYGUARD_EXIT_ANIM:
+ handleStartKeyguardExitAnimation((Long) msg.obj);
+ break;
}
}
};
@@ -1207,6 +1216,19 @@
private void handleHide() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleHide");
+ try {
+
+ // Don't actually hide the Keyguard at the moment, wait for window manager until
+ // it tells us it's safe to do so with startKeyguardExitAnimation.
+ mWM.keyguardGoingAway();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while calling WindowManager", e);
+ }
+ }
+ }
+
+ private void handleStartKeyguardExitAnimation(long fadeoutDuration) {
+ synchronized (KeyguardViewMediator.this) {
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
@@ -1324,6 +1346,11 @@
return mStatusBarKeyguardViewManager;
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, fadeoutDuration);
+ mHandler.sendMessage(msg);
+ }
+
public ViewMediatorCallback getViewMediatorCallback() {
return mViewMediatorCallback;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bdac7a0..626fc0d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -191,15 +191,23 @@
final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
record.tileView.measure(exactly(cw), exactly(ch));
}
- final int actualHeight = rows == 0 ? 0 : getRowTop(rows);
- mDetail.measure(exactly(width), exactly(actualHeight));
- setMeasuredDimension(width, actualHeight);
+ int h = rows == 0 ? 0 : getRowTop(rows);
+ mDetail.measure(exactly(width), unspecified());
+ if (mDetail.getVisibility() == VISIBLE && mDetail.getChildCount() > 0) {
+ final int dmh = mDetail.getMeasuredHeight();
+ if (dmh > 0) h = dmh;
+ }
+ setMeasuredDimension(width, h);
}
private static int exactly(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
+ private static int unspecified() {
+ return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int w = getWidth();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
index 130f9ce..20bbf8b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
@@ -85,7 +85,7 @@
// noop
}
});
- vp.postVolumeChanged(AudioManager.STREAM_NOTIFICATION, AudioManager.FLAG_SHOW_UI);
+ vp.postVolumeChanged(AudioManager.STREAM_RING, AudioManager.FLAG_SHOW_UI);
return v;
}
@@ -108,11 +108,7 @@
@Override
protected void handleClick() {
- if (mState.zen) {
- mZenController.setZen(false);
- } else {
- showDetail(true);
- }
+ showDetail(true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java
new file mode 100644
index 0000000..06dc4e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java
@@ -0,0 +1,48 @@
+/*
+ * 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.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * An ImageView which does not have overlapping renderings commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class AlphaImageView extends ImageView {
+ public AlphaImageView(Context context) {
+ super(context);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index cda84cf..21b41c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -48,6 +48,7 @@
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -77,11 +78,12 @@
import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView;
import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Locale;
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
@@ -91,7 +93,7 @@
public static final String TAG = "StatusBar";
public static final boolean DEBUG = false;
public static final boolean MULTIUSER_DEBUG = false;
- private static final boolean USE_NOTIFICATION_LISTENER = false;
+ private static final boolean USE_NOTIFICATION_LISTENER = true;
protected static final int MSG_SHOW_RECENT_APPS = 1019;
protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -195,7 +197,7 @@
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
if (provisioned != mDeviceProvisioned) {
mDeviceProvisioned = provisioned;
- updateNotificationIcons();
+ updateNotifications();
}
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
@@ -213,7 +215,7 @@
// so we just dump our cache ...
mUsersAllowingPrivateNotifications.clear();
// ... and refresh all the notifications
- updateNotificationIcons();
+ updateNotifications();
}
};
@@ -284,11 +286,12 @@
public void onListenerConnected() {
if (DEBUG) Log.d(TAG, "onListenerConnected");
final StatusBarNotification[] notifications = getActiveNotifications();
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
- addNotificationInternal(sbn);
+ addNotificationInternal(sbn, currentRanking);
}
}
});
@@ -297,13 +300,14 @@
@Override
public void onNotificationPosted(final StatusBarNotification sbn) {
if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
if (mNotificationData.findByKey(sbn.getKey()) != null) {
- updateNotificationInternal(sbn);
+ updateNotificationInternal(sbn, currentRanking);
} else {
- addNotificationInternal(sbn);
+ addNotificationInternal(sbn, currentRanking);
}
}
});
@@ -312,10 +316,24 @@
@Override
public void onNotificationRemoved(final StatusBarNotification sbn) {
if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
- removeNotificationInternal(sbn.getKey());
+ removeNotificationInternal(sbn.getKey(), currentRanking);
+ }
+ });
+ }
+
+ @Override
+ public void onNotificationRankingUpdate() {
+ if (DEBUG) Log.d(TAG, "onRankingUpdate");
+ final Ranking currentRanking = getCurrentRanking();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mNotificationData.updateRanking(currentRanking);
+ updateNotifications();
}
});
}
@@ -1120,19 +1138,13 @@
}
}
- protected StatusBarNotification removeNotificationViews(String key) {
- NotificationData.Entry entry = mNotificationData.remove(key);
+ protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) {
+ NotificationData.Entry entry = mNotificationData.remove(key, ranking);
if (entry == null) {
Log.w(TAG, "removeNotification for unknown key: " + key);
return null;
}
- // Remove the expanded view.
- ViewGroup rowParent = (ViewGroup)entry.row.getParent();
- if (rowParent != null) rowParent.removeView(entry.row);
- updateRowStates();
- updateNotificationIcons();
- updateSpeedBump();
-
+ updateNotifications();
return entry.notification;
}
@@ -1166,35 +1178,17 @@
return entry;
}
- protected void addNotificationViews(NotificationData.Entry entry) {
+ protected void addNotificationViews(Entry entry, Ranking ranking) {
if (entry == null) {
return;
}
// Add the expanded view and icon.
- int pos = mNotificationData.add(entry);
- if (DEBUG) {
- Log.d(TAG, "addNotificationViews: added at " + pos);
- }
- updateRowStates();
- updateNotificationIcons();
- updateSpeedBump();
+ mNotificationData.add(entry, ranking);
+ updateNotifications();
}
- protected void updateSpeedBump() {
- int n = mNotificationData.size();
- int speedBumpIndex = -1;
- for (int i = n-1; i >= 0; i--) {
- NotificationData.Entry entry = mNotificationData.get(i);
- if (entry.row.getVisibility() != View.GONE && speedBumpIndex == -1
- && entry.row.isBelowSpeedBump() ) {
- speedBumpIndex = n - 1 - i;
- }
- }
- mStackScroller.updateSpeedBumpIndex(speedBumpIndex);
- }
-
- private void addNotificationViews(StatusBarNotification notification) {
- addNotificationViews(createNotificationViews(notification));
+ private void addNotificationViews(StatusBarNotification notification, Ranking ranking) {
+ addNotificationViews(createNotificationViews(notification), ranking);
}
/**
@@ -1208,17 +1202,17 @@
protected void updateRowStates() {
int maxKeyguardNotifications = getMaxKeyguardNotifications();
mKeyguardIconOverflowContainer.getIconsView().removeAllViews();
- int n = mNotificationData.size();
+ final int N = mNotificationData.size();
int visibleNotifications = 0;
boolean onKeyguard = mState == StatusBarState.KEYGUARD;
- for (int i = n-1; i >= 0; i--) {
+ for (int i = 0; i < N; i++) {
NotificationData.Entry entry = mNotificationData.get(i);
if (onKeyguard) {
entry.row.setExpansionDisabled(true);
} else {
entry.row.setExpansionDisabled(false);
if (!entry.row.isUserLocked()) {
- boolean top = (i == n-1);
+ boolean top = (i == 0);
entry.row.setSystemExpanded(top);
}
}
@@ -1245,6 +1239,9 @@
} else {
mKeyguardIconOverflowContainer.setVisibility(View.GONE);
}
+ // Move overflow container to last position.
+ mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
+ mStackScroller.getChildCount() - 1);
}
private boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
@@ -1254,7 +1251,7 @@
protected void setZenMode(int mode) {
if (!isDeviceProvisioned()) return;
mZenMode = mode;
- updateNotificationIcons();
+ updateNotifications();
}
protected void setShowLockscreenNotifications(boolean show) {
@@ -1263,41 +1260,37 @@
protected abstract void haltTicker();
protected abstract void setAreThereNotifications();
- protected abstract void updateNotificationIcons();
+ protected abstract void updateNotifications();
protected abstract void tick(StatusBarNotification n, boolean firstTime);
protected abstract void updateExpandedViewPos(int expandedPosition);
protected abstract boolean shouldDisableNavbarGestures();
- protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
- return parent != null && parent.indexOfChild(entry.row) == 0;
- }
-
-
@Override
public void addNotification(StatusBarNotification notification) {
if (!USE_NOTIFICATION_LISTENER) {
- addNotificationInternal(notification);
+ addNotificationInternal(notification, null);
}
}
- public abstract void addNotificationInternal(StatusBarNotification notification);
+ public abstract void addNotificationInternal(StatusBarNotification notification,
+ Ranking ranking);
@Override
public void removeNotification(String key) {
if (!USE_NOTIFICATION_LISTENER) {
- removeNotificationInternal(key);
+ removeNotificationInternal(key, null);
}
}
- protected abstract void removeNotificationInternal(String key);
+ protected abstract void removeNotificationInternal(String key, Ranking ranking);
public void updateNotification(StatusBarNotification notification) {
if (!USE_NOTIFICATION_LISTENER) {
- updateNotificationInternal(notification);
+ updateNotificationInternal(notification, null);
}
}
- public void updateNotificationInternal(StatusBarNotification notification) {
+ public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
@@ -1369,18 +1362,12 @@
&& oldPublicContentView.getPackage().equals(publicContentView.getPackage())
&& oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
- ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
- boolean orderUnchanged =
- notification.getNotification().when == oldNotification.getNotification().when
- && notification.getScore() == oldNotification.getScore();
- // score now encompasses/supersedes isOngoing()
boolean updateTicker = notification.getNotification().tickerText != null
&& !TextUtils.equals(notification.getNotification().tickerText,
oldEntry.notification.getNotification().tickerText);
- boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
- if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged
- && (orderUnchanged || isTopAnyway)) {
+ if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
+ && publicUnchanged) {
if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey());
oldEntry.notification = notification;
try {
@@ -1408,22 +1395,20 @@
handleNotificationError(notification, "Couldn't update icon: " + ic);
return;
}
- updateRowStates();
- updateSpeedBump();
+ mNotificationData.updateRanking(ranking);
+ updateNotifications();
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
- removeNotificationViews(notification.getKey());
- addNotificationViews(notification);
+ removeNotificationViews(notification.getKey(), ranking);
+ addNotificationViews(notification, ranking);
}
} else {
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey());
if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
- removeNotificationViews(notification.getKey());
- addNotificationViews(notification); // will also replace the heads up
+ removeNotificationViews(notification.getKey(), ranking);
+ addNotificationViews(notification, ranking); // will also replace the heads up
final NotificationData.Entry newEntry = mNotificationData.findByKey(
notification.getKey());
final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
@@ -1570,5 +1555,12 @@
mWindowManager.removeViewImmediate(mSearchPanelView);
}
mContext.unregisterReceiver(mBroadcastReceiver);
+ if (USE_NOTIFICATION_LISTENER) {
+ try {
+ mNotificationListener.unregisterAsSystemService();
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
index 7d576cb..5f1325b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
@@ -18,6 +18,7 @@
import android.animation.ValueAnimator;
import android.content.Context;
+import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -46,6 +47,8 @@
private float mMaxLengthSeconds;
private float mHighVelocityPxPerSecond;
+ private AnimatorProperties mAnimatorProperties = new AnimatorProperties();
+
public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
mMaxLengthSeconds = maxLengthSeconds;
mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1);
@@ -80,18 +83,59 @@
* @param currValue the current value
* @param endValue the end value of the animator
* @param velocity the current velocity of the motion
+ */
+ public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity) {
+ apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
* @param maxDistance the maximum distance for this interaction; the maximum animation length
* gets multiplied by the ratio between the actual distance and this value
*/
public void apply(ValueAnimator animator, float currValue, float endValue, float velocity,
float maxDistance) {
+ AnimatorProperties properties = getProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ * @param maxDistance the maximum distance for this interaction; the maximum animation length
+ * gets multiplied by the ratio between the actual distance and this value
+ */
+ public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity, float maxDistance) {
+ AnimatorProperties properties = getProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ private AnimatorProperties getProperties(float currValue,
+ float endValue, float velocity, float maxDistance) {
float maxLengthSeconds = (float) (mMaxLengthSeconds
* Math.sqrt(Math.abs(endValue - currValue) / maxDistance));
float diff = Math.abs(endValue - currValue);
float velAbs = Math.abs(velocity);
float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs;
if (durationSeconds <= maxLengthSeconds) {
- animator.setInterpolator(mLinearOutSlowIn);
+ mAnimatorProperties.interpolator = mLinearOutSlowIn;
} else if (velAbs >= mMinVelocityPxPerSecond) {
// Cross fade between fast-out-slow-in and linear interpolator with current velocity.
@@ -100,14 +144,15 @@
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn);
- animator.setInterpolator(superInterpolator);
+ mAnimatorProperties.interpolator = superInterpolator;
} else {
// Just use a normal interpolator which doesn't take the velocity into account.
durationSeconds = maxLengthSeconds;
- animator.setInterpolator(mFastOutSlowIn);
+ mAnimatorProperties.interpolator = mFastOutSlowIn;
}
- animator.setDuration((long) (durationSeconds * 1000));
+ mAnimatorProperties.duration = (long) (durationSeconds * 1000);
+ return mAnimatorProperties;
}
/**
@@ -124,6 +169,34 @@
*/
public void applyDismissing(ValueAnimator animator, float currValue, float endValue,
float velocity, float maxDistance) {
+ AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion for the case when the animation is making something
+ * disappear.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ * @param maxDistance the maximum distance for this interaction; the maximum animation length
+ * gets multiplied by the ratio between the actual distance and this value
+ */
+ public void applyDismissing(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity, float maxDistance) {
+ AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ private AnimatorProperties getDismissingProperties(float currValue, float endValue,
+ float velocity, float maxDistance) {
float maxLengthSeconds = (float) (mMaxLengthSeconds
* Math.pow(Math.abs(endValue - currValue) / maxDistance, 0.5f));
float diff = Math.abs(endValue - currValue);
@@ -135,7 +208,7 @@
Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, 1, y2);
float durationSeconds = startGradient * diff / velAbs;
if (durationSeconds <= maxLengthSeconds) {
- animator.setInterpolator(mLinearOutFasterIn);
+ mAnimatorProperties.interpolator = mLinearOutFasterIn;
} else if (velAbs >= mMinVelocityPxPerSecond) {
// Cross fade between linear-out-faster-in and linear interpolator with current
@@ -145,14 +218,15 @@
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
velocityInterpolator, mLinearOutFasterIn, mLinearOutSlowIn);
- animator.setInterpolator(superInterpolator);
+ mAnimatorProperties.interpolator = superInterpolator;
} else {
// Just use a normal interpolator which doesn't take the velocity into account.
durationSeconds = maxLengthSeconds;
- animator.setInterpolator(mFastOutLinearIn);
+ mAnimatorProperties.interpolator = mFastOutLinearIn;
}
- animator.setDuration((long) (durationSeconds * 1000));
+ mAnimatorProperties.duration = (long) (durationSeconds * 1000);
+ return mAnimatorProperties;
}
/**
@@ -221,4 +295,10 @@
return time * mVelocity / mDiff;
}
}
+
+ private static class AnimatorProperties {
+ Interpolator interpolator;
+ long duration;
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index 0555879..24da5c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -31,7 +31,6 @@
public class InterceptedNotifications {
private static final String TAG = "InterceptedNotifications";
private static final String EXTRA_INTERCEPT = "android.intercept";
- private static final String SYNTHETIC_KEY = "InterceptedNotifications.SYNTHETIC_KEY";
private final Context mContext;
private final PhoneStatusBar mBar;
@@ -50,7 +49,7 @@
for (int i = 0; i < n; i++) {
final StatusBarNotification sbn = mIntercepted.valueAt(i);
sbn.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
- mBar.addNotificationInternal(sbn);
+ mBar.addNotificationInternal(sbn, null);
}
mIntercepted.clear();
updateSyntheticNotification();
@@ -71,7 +70,7 @@
}
public boolean isSyntheticEntry(Entry ent) {
- return ent.key.equals(SYNTHETIC_KEY);
+ return ent.key.equals(mSynKey);
}
public void update(StatusBarNotification notification) {
@@ -88,7 +87,7 @@
private void updateSyntheticNotification() {
if (mIntercepted.isEmpty()) {
if (mSynKey != null) {
- mBar.removeNotificationInternal(mSynKey);
+ mBar.removeNotificationInternal(mSynKey, null);
mSynKey = null;
}
return;
@@ -107,9 +106,9 @@
mBar.getCurrentUserHandle());
if (mSynKey == null) {
mSynKey = sbn.getKey();
- mBar.addNotificationInternal(sbn);
+ mBar.addNotificationInternal(sbn, null);
} else {
- mBar.updateNotificationInternal(sbn);
+ mBar.updateNotificationInternal(sbn, null);
}
final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey);
entry.row.setOnClickListener(mSynClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 5696246..d829ac0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,15 +16,19 @@
package com.android.systemui.statusbar;
+import android.app.Notification;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.view.View;
-import android.widget.ImageView;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
/**
* The list of currently displaying notifications.
+ *
+ * TODO: Rename to NotificationList.
*/
public class NotificationData {
public static final class Entry {
@@ -34,7 +38,6 @@
public ExpandableNotificationRow row; // the outer expanded view
public View expanded; // the inflated RemoteViews
public View expandedPublic; // for insecure lockscreens
- public ImageView largeIcon;
public View expandedBig;
private boolean interruption;
public Entry() {}
@@ -64,18 +67,23 @@
}
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
- private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() {
- // sort first by score, then by when
+ private Ranking mRanking;
+ private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
+ @Override
public int compare(Entry a, Entry b) {
+ if (mRanking != null) {
+ return mRanking.getRank(a.key) - mRanking.getRank(b.key);
+ }
+
final StatusBarNotification na = a.notification;
final StatusBarNotification nb = b.notification;
- int d = na.getScore() - nb.getScore();
+ int d = nb.getScore() - na.getScore();
if (a.interruption != b.interruption) {
- return a.interruption ? 1 : -1;
+ return a.interruption ? -1 : 1;
} else if (d != 0) {
return d;
} else {
- return (int) (na.getNotification().when - nb.getNotification().when);
+ return (int) (nb.getNotification().when - na.getNotification().when);
}
}
};
@@ -97,26 +105,47 @@
return null;
}
- public int add(Entry entry) {
- int i;
- int N = mEntries.size();
- for (i = 0; i < N; i++) {
- if (mEntryCmp.compare(mEntries.get(i), entry) > 0) {
- break;
- }
- }
- mEntries.add(i, entry);
- return i;
+ public void add(Entry entry, Ranking ranking) {
+ mEntries.add(entry);
+ updateRankingAndSort(ranking);
}
- public Entry remove(String key) {
+ public Entry remove(String key, Ranking ranking) {
Entry e = findByKey(key);
- if (e != null) {
- mEntries.remove(e);
+ if (e == null) {
+ return null;
}
+ mEntries.remove(e);
+ updateRankingAndSort(ranking);
return e;
}
+ public void updateRanking(Ranking ranking) {
+ updateRankingAndSort(ranking);
+ }
+
+ public boolean isAmbient(String key) {
+ // TODO: Remove when switching to NotificationListener.
+ if (mRanking == null) {
+ for (Entry entry : mEntries) {
+ if (key.equals(entry.key)) {
+ return entry.notification.getNotification().priority ==
+ Notification.PRIORITY_MIN;
+ }
+ }
+ } else {
+ return mRanking.isAmbient(key);
+ }
+ return false;
+ }
+
+ private void updateRankingAndSort(Ranking ranking) {
+ if (ranking != null) {
+ mRanking = ranking;
+ }
+ Collections.sort(mEntries, mRankingComparator);
+ }
+
/**
* Return whether there are any visible items (i.e. items without an error).
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 714ad06..994b329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -23,7 +23,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
@@ -33,26 +32,23 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
import com.android.systemui.R;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
*/
-public class KeyguardBottomAreaView extends FrameLayout
- implements SwipeAffordanceView.AffordanceListener,
+public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
UnlockMethodCache.OnUnlockMethodChangedListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
- private SwipeAffordanceView mCameraButton;
- private SwipeAffordanceView mPhoneButton;
+ private ImageView mCameraImageView;
+ private ImageView mPhoneImageView;
private ImageView mLockIcon;
- private PowerManager mPowerManager;
private ActivityStarter mActivityStarter;
private UnlockMethodCache mUnlockMethodCache;
@@ -76,11 +72,9 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mCameraButton = (SwipeAffordanceView) findViewById(R.id.camera_button);
- mPhoneButton = (SwipeAffordanceView) findViewById(R.id.phone_button);
+ mCameraImageView = (ImageView) findViewById(R.id.camera_button);
+ mPhoneImageView = (ImageView) findViewById(R.id.phone_button);
mLockIcon = (ImageView) findViewById(R.id.lock_icon);
- mCameraButton.setAffordanceListener(this);
- mPhoneButton.setAffordanceListener(this);
watchForDevicePolicyChanges();
watchForAccessibilityChanges();
updateCameraVisibility();
@@ -88,7 +82,6 @@
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
updateTrust();
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
public void setActivityStarter(ActivityStarter activityStarter) {
@@ -97,12 +90,12 @@
private void updateCameraVisibility() {
boolean visible = !isCameraDisabledByDpm();
- mCameraButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void updatePhoneVisibility() {
boolean visible = isPhoneVisible();
- mPhoneButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mPhoneImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private boolean isPhoneVisible() {
@@ -162,33 +155,31 @@
}
private void enableAccessibility(boolean touchExplorationEnabled) {
- mCameraButton.enableAccessibility(touchExplorationEnabled);
- mPhoneButton.enableAccessibility(touchExplorationEnabled);
+ mCameraImageView.setOnClickListener(touchExplorationEnabled ? this : null);
+ mCameraImageView.setClickable(touchExplorationEnabled);
+ mPhoneImageView.setOnClickListener(touchExplorationEnabled ? this : null);
+ mPhoneImageView.setClickable(touchExplorationEnabled);
}
- private void launchCamera() {
+ @Override
+ public void onClick(View v) {
+ if (v == mCameraImageView) {
+ launchCamera();
+ } else if (v == mPhoneImageView) {
+ launchPhone();
+ }
+ }
+
+ public void launchCamera() {
mContext.startActivityAsUser(
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE),
UserHandle.CURRENT);
}
- private void launchPhone() {
+ public void launchPhone() {
mActivityStarter.startActivity(PHONE_INTENT);
}
- @Override
- public void onUserActivity(long when) {
- mPowerManager.userActivity(when, false);
- }
-
- @Override
- public void onActionPerformed(SwipeAffordanceView view) {
- if (view == mCameraButton) {
- launchCamera();
- } else if (view == mPhoneButton) {
- launchPhone();
- }
- }
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
@@ -208,6 +199,18 @@
mLockIcon.setImageResource(iconRes);
}
+ public ImageView getPhoneImageView() {
+ return mPhoneImageView;
+ }
+
+ public ImageView getCameraImageView() {
+ return mCameraImageView;
+ }
+
+ public ImageView getLockIcon() {
+ return mLockIcon;
+ }
+
@Override
public void onMethodSecureChanged(boolean methodSecure) {
updateTrust();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
new file mode 100644
index 0000000..b4f4865
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -0,0 +1,398 @@
+/*
+ * 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.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.os.PowerManager;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewPropertyAnimator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.FlingAnimationUtils;
+
+import java.util.ArrayList;
+
+/**
+ * A touch handler of the Keyguard which is responsible for swiping the content left or right.
+ */
+public class KeyguardPageSwipeHelper {
+
+ private static final float SWIPE_MAX_ICON_SCALE_AMOUNT = 2.0f;
+ private static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.7f;
+ private final Context mContext;
+
+ private FlingAnimationUtils mFlingAnimationUtils;
+ private Callback mCallback;
+ private int mTrackingPointer;
+ private VelocityTracker mVelocityTracker;
+ private boolean mSwipingInProgress;
+ private float mInitialTouchX;
+ private float mInitialTouchY;
+ private float mTranslation;
+ private float mTranslationOnDown;
+ private int mTouchSlop;
+ private int mMinTranslationAmount;
+ private int mMinFlingVelocity;
+ private PowerManager mPowerManager;
+ private final View mLeftIcon;
+ private final View mCenterIcon;
+ private final View mRightIcon;
+ private Interpolator mFastOutSlowIn;
+ private Animator mSwipeAnimator;
+ private boolean mCallbackCalled;
+
+ KeyguardPageSwipeHelper(Callback callback, Context context) {
+ mContext = context;
+ mCallback = callback;
+ mLeftIcon = mCallback.getLeftIcon();
+ mCenterIcon = mCallback.getCenterIcon();
+ mRightIcon = mCallback.getRightIcon();
+ updateIcon(mLeftIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mCenterIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mRightIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ initDimens();
+ }
+
+ private void initDimens() {
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
+ mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_min_swipe_amount);
+ mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
+ mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_slow_in);
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+ int pointerIndex = event.findPointerIndex(mTrackingPointer);
+ if (pointerIndex < 0) {
+ pointerIndex = 0;
+ mTrackingPointer = event.getPointerId(pointerIndex);
+ }
+ final float y = event.getY(pointerIndex);
+ final float x = event.getX(pointerIndex);
+
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ if (mSwipingInProgress) {
+ cancelAnimations();
+ }
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ mTranslationOnDown = mTranslation;
+ initVelocityTracker();
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ final int upPointer = event.getPointerId(event.getActionIndex());
+ if (mTrackingPointer == upPointer) {
+ // gesture is ongoing, find a new pointer to track
+ final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+ final float newY = event.getY(newIndex);
+ final float newX = event.getX(newIndex);
+ mTrackingPointer = event.getPointerId(newIndex);
+ mInitialTouchY = newY;
+ mInitialTouchX = newX;
+ mTranslationOnDown = mTranslation;
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ final float w = x - mInitialTouchX;
+ trackMovement(event);
+ if (((leftSwipePossible() && w > mTouchSlop)
+ || (rightSwipePossible() && w < -mTouchSlop))
+ && Math.abs(w) > Math.abs(y - mInitialTouchY)
+ && !mSwipingInProgress) {
+ cancelAnimations();
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ mTranslationOnDown = mTranslation;
+ mSwipingInProgress = true;
+ }
+ if (mSwipingInProgress) {
+ setTranslation(mTranslationOnDown + x - mInitialTouchX, false);
+ onUserActivity(event.getEventTime());
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mTrackingPointer = -1;
+ trackMovement(event);
+ if (mSwipingInProgress) {
+ flingWithCurrentVelocity();
+ }
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ }
+ return true;
+ }
+
+ private boolean rightSwipePossible() {
+ return mRightIcon.getVisibility() == View.VISIBLE;
+ }
+
+ private boolean leftSwipePossible() {
+ return mLeftIcon.getVisibility() == View.VISIBLE;
+ }
+
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ private void onUserActivity(long when) {
+ mPowerManager.userActivity(when, false);
+ }
+
+ private void cancelAnimations() {
+ ArrayList<View> targetViews = mCallback.getTranslationViews();
+ for (View target : targetViews) {
+ target.animate().cancel();
+ }
+ View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
+ targetView.animate().cancel();
+ if (mSwipeAnimator != null) {
+ mSwipeAnimator.removeAllListeners();
+ mSwipeAnimator.cancel();
+ hideInactiveIcons(true);
+ }
+ }
+
+ private void flingWithCurrentVelocity() {
+ float vel = getCurrentVelocity();
+
+ // We snap back if the current translation is not far enough
+ boolean snapBack = Math.abs(mTranslation) < mMinTranslationAmount;
+
+ // or if the velocity is in the opposite direction.
+ boolean velIsInWrongDirection = vel * mTranslation < 0;
+ snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
+ vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
+ fling(vel, snapBack);
+ }
+
+ private void fling(float vel, final boolean snapBack) {
+ float target = mTranslation < 0 ? -mCallback.getPageWidth() : mCallback.getPageWidth();
+ target = snapBack ? 0 : target;
+
+ // translation Animation
+ startTranslationAnimations(vel, target);
+
+ // animate left / right icon
+ startIconAnimation(vel, snapBack, target);
+
+ ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
+ mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mTranslation = (float) animation.getAnimatedValue();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mSwipeAnimator = null;
+ mSwipingInProgress = false;
+ if (!snapBack && !mCallbackCalled) {
+
+ // ensure that the callback is called eventually
+ mCallback.onAnimationToSideStarted(mTranslation < 0);
+ mCallbackCalled = true;
+ }
+ }
+ });
+ if (!snapBack) {
+ mCallbackCalled = false;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ int frameNumber;
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (frameNumber == 2 && !mCallbackCalled) {
+
+ // we have to wait for the second frame for this call,
+ // until the render thread has definitely kicked in, to avoid a lag.
+ mCallback.onAnimationToSideStarted(mTranslation < 0);
+ mCallbackCalled = true;
+ }
+ frameNumber++;
+ }
+ });
+ } else {
+ showAllIcons(true);
+ }
+ animator.start();
+ mSwipeAnimator = animator;
+ }
+
+ private void startTranslationAnimations(float vel, float target) {
+ ArrayList<View> targetViews = mCallback.getTranslationViews();
+ for (View targetView : targetViews) {
+ ViewPropertyAnimator animator = targetView.animate();
+ mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
+ animator.translationX(target);
+ }
+ }
+
+ private void startIconAnimation(float vel, boolean snapBack, float target) {
+ float scale = snapBack ? 1.0f : SWIPE_MAX_ICON_SCALE_AMOUNT;
+ float alpha = snapBack ? SWIPE_RESTING_ALPHA_AMOUNT : 1.0f;
+ View targetView = mTranslation > 0
+ ? mLeftIcon
+ : mRightIcon;
+ if (targetView.getVisibility() == View.VISIBLE) {
+ ViewPropertyAnimator iconAnimator = targetView.animate();
+ mFlingAnimationUtils.apply(iconAnimator, mTranslation, target, vel);
+ iconAnimator.scaleX(scale);
+ iconAnimator.scaleY(scale);
+ iconAnimator.alpha(alpha);
+ }
+ }
+
+ private void setTranslation(float translation, boolean isReset) {
+ translation = rightSwipePossible() ? translation : Math.max(0, translation);
+ translation = leftSwipePossible() ? translation : Math.min(0, translation);
+ if (translation != mTranslation) {
+ ArrayList<View> translatedViews = mCallback.getTranslationViews();
+ for (View view : translatedViews) {
+ view.setTranslationX(translation);
+ }
+ if (translation == 0.0f) {
+ boolean animate = !isReset;
+ showAllIcons(animate);
+ } else {
+ View targetView = translation > 0 ? mLeftIcon : mRightIcon;
+ float progress = Math.abs(translation) / mCallback.getPageWidth();
+ progress = Math.min(progress, 1.0f);
+ float alpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - progress) + progress;
+ float scale = (1.0f - progress) + progress * SWIPE_MAX_ICON_SCALE_AMOUNT;
+ updateIcon(targetView, scale, alpha, false);
+ View otherView = translation < 0 ? mLeftIcon : mRightIcon;
+ if (mTranslation * translation <= 0) {
+ // The sign of the translation has changed so we need to hide the other icons
+ updateIcon(otherView, 0, 0, true);
+ updateIcon(mCenterIcon, 0, 0, true);
+ }
+ }
+ mTranslation = translation;
+ }
+ }
+
+ private void showAllIcons(boolean animate) {
+ float scale = 1.0f;
+ float alpha = SWIPE_RESTING_ALPHA_AMOUNT;
+ updateIcon(mRightIcon, scale, alpha, animate);
+ updateIcon(mCenterIcon, scale, alpha, animate);
+ updateIcon(mLeftIcon, scale, alpha, animate);
+ }
+
+ private void hideInactiveIcons(boolean animate){
+ View otherView = mTranslation < 0 ? mLeftIcon : mRightIcon;
+ updateIcon(otherView, 0, 0, animate);
+ updateIcon(mCenterIcon, 0, 0, animate);
+ }
+
+ private void updateIcon(View view, float scale, float alpha, boolean animate) {
+ if (view.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ if (!animate) {
+ view.setAlpha(alpha);
+ view.setScaleX(scale);
+ view.setScaleY(scale);
+ // TODO: remove this invalidate once the property setters invalidate it properly
+ view.invalidate();
+ } else {
+ if (view.getAlpha() != alpha || view.getScaleX() != scale) {
+ view.animate()
+ .setInterpolator(mFastOutSlowIn)
+ .alpha(alpha)
+ .scaleX(scale)
+ .scaleY(scale);
+ }
+ }
+ }
+
+ private void trackMovement(MotionEvent event) {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(event);
+ }
+ }
+
+ private void initVelocityTracker() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ }
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+
+ private float getCurrentVelocity() {
+ if (mVelocityTracker == null) {
+ return 0;
+ }
+ mVelocityTracker.computeCurrentVelocity(1000);
+ return mVelocityTracker.getXVelocity();
+ }
+
+ public void onConfigurationChanged() {
+ initDimens();
+ }
+
+ public void reset() {
+ setTranslation(0.0f, true);
+ mSwipingInProgress = false;
+ }
+
+ public boolean isSwipingInProgress() {
+ return mSwipingInProgress;
+ }
+
+ public interface Callback {
+
+ /**
+ * Notifies the callback when an animation to a side page was started.
+ *
+ * @param rightPage Is the page animated to the right page?
+ */
+ void onAnimationToSideStarted(boolean rightPage);
+
+ float getPageWidth();
+
+ ArrayList<View> getTranslationViews();
+
+ View getLeftIcon();
+
+ View getCenterIcon();
+
+ View getRightIcon();
+ }
+}
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 52688df..802e5e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -21,6 +21,7 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -40,10 +41,13 @@
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
+import java.util.ArrayList;
+
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
- View.OnClickListener {
+ View.OnClickListener, KeyguardPageSwipeHelper.Callback {
+ private KeyguardPageSwipeHelper mPageSwiper;
PhoneStatusBar mStatusBar;
private StatusBarHeaderView mHeader;
private View mQsContainer;
@@ -58,7 +62,7 @@
private int mTrackingPointer;
private VelocityTracker mVelocityTracker;
- private boolean mTracking;
+ private boolean mQsTracking;
/**
* Whether we are currently handling a motion gesture in #onInterceptTouchEvent, but haven't
@@ -92,6 +96,11 @@
new KeyguardClockPositionAlgorithm();
private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
new KeyguardClockPositionAlgorithm.Result();
+ private boolean mIsSwipedHorizontally;
+ private boolean mIsExpanding;
+ private KeyguardBottomAreaView mKeyguardBottomArea;
+ private boolean mBlockTouches;
+ private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -129,6 +138,10 @@
mNotificationStackScroller.setOnHeightChangedListener(this);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
+ mSwipeTranslationViews.add(mNotificationStackScroller);
+ mSwipeTranslationViews.add(mKeyguardStatusView);
+ mPageSwiper = new KeyguardPageSwipeHelper(this, getContext());
}
@Override
@@ -151,7 +164,9 @@
// Calculate quick setting heights.
mQsMinExpansionHeight = mHeader.getCollapsedHeight() + mQsPeekHeight;
mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
- if (!mQsExpanded) {
+ if (mQsExpanded) {
+ setQsStackScrollerPadding(mQsMaxExpansionHeight);
+ } else {
setQsExpansion(mQsMinExpansionHeight);
positionClockAndNotifications();
mNotificationStackScroller.setStackHeight(getExpandedHeight());
@@ -247,6 +262,13 @@
mQsExpansionEnabled = qsExpansionEnabled;
}
+ @Override
+ public void resetViews() {
+ mBlockTouches = false;
+ mPageSwiper.reset();
+ closeQs();
+ }
+
public void closeQs() {
cancelAnimation();
setQsExpansion(mQsMinExpansionHeight);
@@ -263,9 +285,7 @@
public void fling(float vel, boolean always) {
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
if (gr != null) {
- gr.tag(
- "fling " + ((vel > 0) ? "open" : "closed"),
- "notifications,v=" + vel);
+ gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel);
}
super.fling(vel, always);
}
@@ -283,6 +303,9 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (mBlockTouches) {
+ return false;
+ }
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -298,7 +321,7 @@
mInitialTouchX = x;
initVelocityTracker();
trackMovement(event);
- if (shouldIntercept(mInitialTouchX, mInitialTouchY, 0)) {
+ if (shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
@@ -316,7 +339,7 @@
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
trackMovement(event);
- if (mTracking) {
+ if (mQsTracking) {
// Already tracking because onOverscrolled was called. We need to update here
// so we don't stop for a frame until the next touch event gets handled in
@@ -327,12 +350,12 @@
return true;
}
if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)
- && shouldIntercept(mInitialTouchX, mInitialTouchY, h)) {
+ && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = y;
mInitialTouchX = x;
- mTracking = true;
+ mQsTracking = true;
mIntercepting = false;
return true;
}
@@ -341,9 +364,9 @@
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
trackMovement(event);
- if (mTracking) {
- flingWithCurrentVelocity();
- mTracking = false;
+ if (mQsTracking) {
+ flingQsWithCurrentVelocity();
+ mQsTracking = false;
}
mIntercepting = false;
break;
@@ -362,7 +385,7 @@
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
- private void flingWithCurrentVelocity() {
+ private void flingQsWithCurrentVelocity() {
float vel = getCurrentVelocity();
// TODO: Better logic whether we should expand or not.
@@ -371,65 +394,83 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (mBlockTouches) {
+ return false;
+ }
// TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
// implementation.
- if (mTracking) {
- int pointerIndex = event.findPointerIndex(mTrackingPointer);
- if (pointerIndex < 0) {
- pointerIndex = 0;
- mTrackingPointer = event.getPointerId(pointerIndex);
+ if (!mIsExpanding && !mQsExpanded && mStatusBar.getBarState() != StatusBarState.SHADE) {
+ mPageSwiper.onTouchEvent(event);
+ if (mPageSwiper.isSwipingInProgress()) {
+ return true;
}
- final float y = event.getY(pointerIndex);
- final float x = event.getX(pointerIndex);
-
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- mTracking = true;
- mInitialTouchY = y;
- mInitialTouchX = x;
- onQsExpansionStarted();
- mInitialHeightOnTouch = mQsExpansionHeight;
- initVelocityTracker();
- trackMovement(event);
- break;
-
- case MotionEvent.ACTION_POINTER_UP:
- final int upPointer = event.getPointerId(event.getActionIndex());
- if (mTrackingPointer == upPointer) {
- // gesture is ongoing, find a new pointer to track
- final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
- final float newY = event.getY(newIndex);
- final float newX = event.getX(newIndex);
- mTrackingPointer = event.getPointerId(newIndex);
- mInitialHeightOnTouch = mQsExpansionHeight;
- mInitialTouchY = newY;
- mInitialTouchX = newX;
- }
- break;
-
- case MotionEvent.ACTION_MOVE:
- final float h = y - mInitialTouchY;
- setQsExpansion(h + mInitialHeightOnTouch);
- trackMovement(event);
- break;
-
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- mTracking = false;
- mTrackingPointer = -1;
- trackMovement(event);
- flingWithCurrentVelocity();
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- break;
- }
- return true;
+ }
+ if (mQsTracking || mQsExpanded) {
+ return onQsTouch(event);
}
- // Consume touch events when QS are expanded.
- return mQsExpanded || super.onTouchEvent(event);
+ super.onTouchEvent(event);
+ return true;
+ }
+
+ @Override
+ protected boolean hasConflictingGestures() {
+ return mStatusBar.getBarState() != StatusBarState.SHADE;
+ }
+
+ private boolean onQsTouch(MotionEvent event) {
+ int pointerIndex = event.findPointerIndex(mTrackingPointer);
+ if (pointerIndex < 0) {
+ pointerIndex = 0;
+ mTrackingPointer = event.getPointerId(pointerIndex);
+ }
+ final float y = event.getY(pointerIndex);
+ final float x = event.getX(pointerIndex);
+
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mQsTracking = true;
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ onQsExpansionStarted();
+ mInitialHeightOnTouch = mQsExpansionHeight;
+ initVelocityTracker();
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ final int upPointer = event.getPointerId(event.getActionIndex());
+ if (mTrackingPointer == upPointer) {
+ // gesture is ongoing, find a new pointer to track
+ final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+ final float newY = event.getY(newIndex);
+ final float newX = event.getX(newIndex);
+ mTrackingPointer = event.getPointerId(newIndex);
+ mInitialHeightOnTouch = mQsExpansionHeight;
+ mInitialTouchY = newY;
+ mInitialTouchX = newX;
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ final float h = y - mInitialTouchY;
+ setQsExpansion(h + mInitialHeightOnTouch);
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mQsTracking = false;
+ mTrackingPointer = -1;
+ trackMovement(event);
+ flingQsWithCurrentVelocity();
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ }
+ return true;
}
@Override
@@ -439,7 +480,7 @@
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = mLastTouchY;
mInitialTouchX = mLastTouchX;
- mTracking = true;
+ mQsTracking = true;
}
}
@@ -569,7 +610,7 @@
/**
* @return Whether we should intercept a gesture to open Quick Settings.
*/
- private boolean shouldIntercept(float x, float y, float yDiff) {
+ private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
if (!mQsExpansionEnabled) {
return false;
}
@@ -647,12 +688,14 @@
protected void onExpandingStarted() {
super.onExpandingStarted();
mNotificationStackScroller.onExpansionStarted();
+ mIsExpanding = true;
}
@Override
protected void onExpandingFinished() {
super.onExpandingFinished();
mNotificationStackScroller.onExpansionStopped();
+ mIsExpanding = false;
}
@Override
@@ -686,6 +729,12 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ mPageSwiper.onConfigurationChanged();
+ }
+
+ @Override
public void onClick(View v) {
if (v == mHeader.getBackgroundView()) {
onQsExpansionStarted();
@@ -696,4 +745,40 @@
}
}
}
+
+ @Override
+ public void onAnimationToSideStarted(boolean rightPage) {
+ if (rightPage) {
+ mKeyguardBottomArea.launchCamera();
+ } else {
+ mKeyguardBottomArea.launchPhone();
+ }
+ mBlockTouches = true;
+ }
+
+
+ @Override
+ public float getPageWidth() {
+ return getWidth();
+ }
+
+ @Override
+ public ArrayList<View> getTranslationViews() {
+ return mSwipeTranslationViews;
+ }
+
+ @Override
+ public View getLeftIcon() {
+ return mKeyguardBottomArea.getPhoneImageView();
+ }
+
+ @Override
+ public View getCenterIcon() {
+ return mKeyguardBottomArea.getLockIcon();
+ }
+
+ @Override
+ public View getRightIcon() {
+ return mKeyguardBottomArea.getCameraImageView();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 1015d5b..b94f6f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -191,6 +191,7 @@
pv.setExpandedFraction(0); // just in case
pv.setVisibility(View.GONE);
pv.cancelPeek();
+ pv.resetViews();
}
}
if (DEBUG) LOG("collapseAllPanels: animate=%s waiting=%s", animate, waiting);
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 7500c10..c5a9b85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -35,7 +35,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-public class PanelView extends FrameLayout {
+public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
public static final String TAG = PanelView.class.getSimpleName();
protected float mOverExpansion;
@@ -130,21 +130,24 @@
final float y = event.getY(pointerIndex);
final float x = event.getX(pointerIndex);
+ boolean waitForTouchSlop = hasConflictingGestures();
+
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mTracking = true;
mInitialTouchY = y;
mInitialTouchX = x;
+ mInitialOffsetOnTouch = mExpandedHeight;
if (mVelocityTracker == null) {
initVelocityTracker();
}
trackMovement(event);
- if (mHeightAnimator != null) {
- mHeightAnimator.cancel(); // end any outstanding animations
+ if (!waitForTouchSlop || mHeightAnimator != null) {
+ if (mHeightAnimator != null) {
+ mHeightAnimator.cancel(); // end any outstanding animations
+ }
+ onTrackingStarted();
}
- onTrackingStarted();
- mInitialOffsetOnTouch = mExpandedHeight;
if (mExpandedHeight == 0) {
mJustPeeked = true;
runPeekAnimation();
@@ -166,15 +169,27 @@
break;
case MotionEvent.ACTION_MOVE:
- final float h = y - mInitialTouchY + mInitialOffsetOnTouch;
- if (h > mPeekHeight) {
+ float h = y - mInitialTouchY;
+ if (waitForTouchSlop && !mTracking && Math.abs(h) > mTouchSlop
+ && Math.abs(h) > Math.abs(x - mInitialTouchX)) {
+ mInitialOffsetOnTouch = mExpandedHeight;
+ mInitialTouchX = x;
+ mInitialTouchY = y;
+ if (mHeightAnimator != null) {
+ mHeightAnimator.cancel(); // end any outstanding animations
+ }
+ onTrackingStarted();
+ h = 0;
+ }
+ final float newHeight = h + mInitialOffsetOnTouch;
+ if (newHeight > mPeekHeight) {
if (mPeekAnimator != null && mPeekAnimator.isStarted()) {
mPeekAnimator.cancel();
}
mJustPeeked = false;
}
- if (!mJustPeeked) {
- setExpandedHeightInternal(h);
+ if (!mJustPeeked && (!waitForTouchSlop || mTracking)) {
+ setExpandedHeightInternal(newHeight);
mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
}
@@ -183,7 +198,6 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mTracking = false;
mTrackingPointer = -1;
trackMovement(event);
boolean expand = flingWithCurrentVelocity();
@@ -194,14 +208,18 @@
}
break;
}
- return true;
+ return !waitForTouchSlop || mTracking;
}
+ protected abstract boolean hasConflictingGestures();
+
protected void onTrackingStopped(boolean expand) {
+ mTracking = false;
mBar.onTrackingStopped(PanelView.this, expand);
}
protected void onTrackingStarted() {
+ mTracking = true;
mBar.onTrackingStarted(PanelView.this);
onExpandingStarted();
}
@@ -522,4 +540,6 @@
mHeightAnimator, ((mHeightAnimator !=null && mHeightAnimator.isStarted())?" (started)":"")
));
}
+
+ public abstract void resetViews();
}
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 ba998c5..0e5b7e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -64,6 +64,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -1043,13 +1044,15 @@
}
@Override
- public void addNotificationInternal(StatusBarNotification notification) {
+ public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
Entry shadeEntry = createNotificationViews(notification);
if (shadeEntry == null) {
return;
}
if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification)) {
+ // Forward the ranking so we can sort the new notification.
+ mNotificationData.updateRanking(ranking);
return;
}
if (mUseHeadsUp && shouldInterrupt(notification)) {
@@ -1089,7 +1092,7 @@
tick(notification, true);
}
}
- addNotificationViews(shadeEntry);
+ addNotificationViews(shadeEntry, ranking);
// Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
@@ -1105,14 +1108,14 @@
}
@Override
- public void updateNotification(StatusBarNotification notification) {
- super.updateNotification(notification);
+ public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ super.updateNotificationInternal(notification, ranking);
mIntercepted.update(notification);
}
@Override
- public void removeNotificationInternal(String key) {
- StatusBarNotification old = removeNotificationViews(key);
+ public void removeNotificationInternal(String key, Ranking ranking) {
+ StatusBarNotification old = removeNotificationViews(key, ranking);
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null) {
@@ -1149,7 +1152,7 @@
R.integer.config_show_search_delay);
}
- private void loadNotificationShade() {
+ private void updateNotificationShade() {
if (mStackScroller == null) return;
int N = mNotificationData.size();
@@ -1159,7 +1162,7 @@
final boolean provisioned = isDeviceProvisioned();
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(N-i-1);
+ Entry ent = mNotificationData.get(i);
if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
// TODO How do we want to badge notifcations from profiles.
@@ -1190,26 +1193,75 @@
for (int i=0; i<toShow.size(); i++) {
View v = toShow.get(i);
if (v.getParent() == null) {
- mStackScroller.addView(v, i);
+ mStackScroller.addView(v);
}
}
+ // So after all this work notifications still aren't sorted correctly.
+ // Let's do that now by advancing through toShow and mStackScroller in
+ // lock-step, making sure mStackScroller matches what we see in toShow.
+ int j = 0;
+ for (int i = 0; i < mStackScroller.getChildCount(); i++) {
+ View child = mStackScroller.getChildAt(i);
+ if (!(child instanceof ExpandableNotificationRow)) {
+ // We don't care about non-notification views.
+ continue;
+ }
+
+ if (child == toShow.get(j)) {
+ // Everything is well, advance both lists.
+ j++;
+ continue;
+ }
+
+ // Oops, wrong notification at this position. Put the right one
+ // here and advance both lists.
+ mStackScroller.changeViewPosition(toShow.get(j), i);
+ j++;
+ }
+ updateRowStates();
+ updateSpeedbump();
mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
}
+ private void updateSpeedbump() {
+ int speedbumpIndex = -1;
+ int currentIndex = 0;
+ for (int i = 0; i < mNotificationData.size(); i++) {
+ Entry entry = mNotificationData.get(i);
+ if (entry.row.getParent() == null) {
+ // This view isn't even added, so the stack scroller doesn't
+ // know about it. Ignore completely.
+ continue;
+ }
+ if (entry.row.getVisibility() != View.GONE &&
+ mNotificationData.isAmbient(entry.key)) {
+ speedbumpIndex = currentIndex;
+ break;
+ }
+ currentIndex++;
+ }
+ mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
+ }
+
@Override
- protected void updateNotificationIcons() {
+ protected void updateNotifications() {
+ // TODO: Move this into updateNotificationIcons()?
if (mNotificationIcons == null) return;
- loadNotificationShade();
+ updateNotificationShade();
+ updateNotificationIcons();
+ }
+ private void updateNotificationIcons() {
final LinearLayout.LayoutParams params
= new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
int N = mNotificationData.size();
if (DEBUG) {
- Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
+ Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" +
+ mNotificationIcons);
}
ArrayList<View> toShow = new ArrayList<View>();
@@ -1217,7 +1269,7 @@
final boolean provisioned = isDeviceProvisioned();
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(N-i-1);
+ Entry ent = mNotificationData.get(i);
if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
|| showNotificationEvenIfUnprovisioned(ent.notification))) continue;
if (!notificationIsForCurrentProfiles(ent.notification)) continue;
@@ -2394,7 +2446,7 @@
public void userSwitched(int newUserId) {
if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
animateCollapsePanels();
- updateNotificationIcons();
+ updateNotifications();
resetUserSetupObserver();
}
@@ -2780,7 +2832,7 @@
mKeyguardStatusView.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
- mNotificationPanel.closeQs();
+ mNotificationPanel.resetViews();
} else {
mKeyguardStatusView.setVisibility(View.GONE);
mKeyguardIndicationTextView.setVisibility(View.GONE);
@@ -2799,10 +2851,8 @@
updateStackScrollerState();
updatePublicMode();
- updateRowStates();
- updateSpeedBump();
+ updateNotifications();
checkBarModes();
- updateNotificationIcons();
updateCarrierLabelVisibility(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java
deleted file mode 100644
index 049c5fc..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java
+++ /dev/null
@@ -1,222 +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.statusbar.phone;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Button;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.KeyButtonView;
-
-/**
- * A swipeable button for affordances on the lockscreen. This is used for the camera and phone
- * affordance.
- */
-public class SwipeAffordanceView extends KeyButtonView {
-
- private static final int SWIPE_DIRECTION_START = 0;
- private static final int SWIPE_DIRECTION_END = 1;
-
- private static final int SWIPE_DIRECTION_LEFT = 0;
- private static final int SWIPE_DIRECTION_RIGHT = 1;
-
- private AffordanceListener mListener;
- private int mScaledTouchSlop;
- private float mDragDistance;
- private int mResolvedSwipeDirection;
- private int mSwipeDirection;
-
- public SwipeAffordanceView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SwipeAffordanceView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- TypedArray a = context.getTheme().obtainStyledAttributes(
- attrs,
- R.styleable.SwipeAffordanceView,
- 0, 0);
- try {
- mSwipeDirection = a.getInt(R.styleable.SwipeAffordanceView_swipeDirection, 0);
- } finally {
- a.recycle();
- }
- }
-
- @Override
- public void onRtlPropertiesChanged(int layoutDirection) {
- super.onRtlPropertiesChanged(layoutDirection);
- if (!isLayoutRtl()) {
- mResolvedSwipeDirection = mSwipeDirection;
- } else {
- mResolvedSwipeDirection = mSwipeDirection == SWIPE_DIRECTION_START
- ? SWIPE_DIRECTION_RIGHT
- : SWIPE_DIRECTION_LEFT;
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mDragDistance = getResources().getDimension(R.dimen.affordance_drag_distance);
- mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
- }
-
- public void enableAccessibility(boolean touchExplorationEnabled) {
-
- // Add a touch handler or accessibility click listener for camera button.
- if (touchExplorationEnabled) {
- setOnTouchListener(null);
- setOnClickListener(mClickListener);
- } else {
- setOnTouchListener(mTouchListener);
- setOnClickListener(null);
- }
- }
-
- public void setAffordanceListener(AffordanceListener listener) {
- mListener = listener;
- }
-
- private void onActionPerformed() {
- if (mListener != null) {
- mListener.onActionPerformed(this);
- }
- }
-
- private void onUserActivity(long when) {
- if (mListener != null) {
- mListener.onUserActivity(when);
- }
- }
-
- private final OnClickListener mClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- onActionPerformed();
- }
- };
-
- private final OnTouchListener mTouchListener = new OnTouchListener() {
- private float mStartX;
- private boolean mTouchSlopReached;
- private boolean mSkipCancelAnimation;
-
- @Override
- public boolean onTouch(final View view, MotionEvent event) {
- float realX = event.getRawX();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mStartX = realX;
- mTouchSlopReached = false;
- mSkipCancelAnimation = false;
- break;
- case MotionEvent.ACTION_MOVE:
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX > mStartX
- : realX < mStartX) {
- realX = mStartX;
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mDragDistance
- : realX > mStartX + mDragDistance) {
- view.setPressed(true);
- onUserActivity(event.getEventTime());
- } else {
- view.setPressed(false);
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mScaledTouchSlop
- : realX > mStartX + mScaledTouchSlop) {
- mTouchSlopReached = true;
- }
- view.setTranslationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? Math.max(realX - mStartX, -mDragDistance)
- : Math.min(realX - mStartX, mDragDistance));
- break;
- case MotionEvent.ACTION_UP:
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mDragDistance
- : realX > mStartX + mDragDistance) {
- onActionPerformed();
- view.animate().x(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? -view.getWidth()
- : ((View) view.getParent()).getWidth() + view.getWidth())
- .setInterpolator(new AccelerateInterpolator(2f)).withEndAction(
- new Runnable() {
- @Override
- public void run() {
- view.setTranslationX(0);
- }
- });
- mSkipCancelAnimation = true;
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mScaledTouchSlop
- : realX > mStartX + mScaledTouchSlop) {
- mTouchSlopReached = true;
- }
- if (!mTouchSlopReached) {
- mSkipCancelAnimation = true;
- view.animate().translationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? -mDragDistance / 2
- : mDragDistance / 2).
- setInterpolator(new DecelerateInterpolator()).withEndAction(
- new Runnable() {
- @Override
- public void run() {
- view.animate().translationX(0).
- setInterpolator(new AccelerateInterpolator());
- }
- });
- }
- case MotionEvent.ACTION_CANCEL:
- view.setPressed(false);
- if (!mSkipCancelAnimation) {
- view.animate().translationX(0)
- .setInterpolator(new AccelerateInterpolator(2f));
- }
- break;
- }
- return true;
- }
- };
-
- public interface AffordanceListener {
-
- /**
- * Called when the view would like to report user activity.
- *
- * @param when The timestamp of the user activity in {@link SystemClock#uptimeMillis} time
- * base.
- */
- void onUserActivity(long when);
-
- /**
- * Called when the action of the affordance has been performed.
- */
- void onActionPerformed(SwipeAffordanceView view);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 5e2d06b..cf56fa57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -27,6 +27,7 @@
boolean animateZ;
boolean animateScale;
boolean animateHeight;
+ boolean animateTopInset;
boolean animateDimmed;
boolean hasDelays;
@@ -60,6 +61,11 @@
return this;
}
+ public AnimationFilter animateTopInset() {
+ animateTopInset = true;
+ return this;
+ }
+
public AnimationFilter animateDimmed() {
animateDimmed = true;
return this;
@@ -84,6 +90,7 @@
animateZ |= filter.animateZ;
animateScale |= filter.animateScale;
animateHeight |= filter.animateHeight;
+ animateTopInset |= filter.animateTopInset;
animateDimmed |= filter.animateDimmed;
hasDelays |= filter.hasDelays;
}
@@ -94,6 +101,7 @@
animateZ = false;
animateScale = false;
animateHeight = false;
+ animateTopInset = false;
animateDimmed = false;
hasDelays = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 079b184..58176b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1599,6 +1599,7 @@
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1607,6 +1608,7 @@
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1615,6 +1617,7 @@
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1623,6 +1626,7 @@
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateDimmed()
.animateScale()
@@ -1651,6 +1655,7 @@
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index bd2541a..2b52c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -49,6 +49,7 @@
private int mBottomStackPeekSize;
private int mZDistanceBetweenElements;
private int mZBasicHeight;
+ private int mRoundedRectCornerRadius;
private StackIndentationFunctor mTopStackIndentationFunctor;
private StackIndentationFunctor mBottomStackIndentationFunctor;
@@ -111,6 +112,8 @@
mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
mBottomStackSlowDownLength = context.getResources()
.getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
+ mRoundedRectCornerRadius = context.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
}
@@ -146,6 +149,67 @@
handleDraggedViews(ambientState, resultState, algorithmState);
updateDimmedActivated(ambientState, resultState, algorithmState);
+ updateClipping(resultState, algorithmState);
+ }
+
+ private void updateClipping(StackScrollState resultState,
+ StackScrollAlgorithmState algorithmState) {
+ float previousNotificationEnd = 0;
+ float previousNotificationStart = 0;
+ boolean previousNotificationIsSwiped = false;
+ int childCount = algorithmState.visibleChildren.size();
+ for (int i = 0; i < childCount; i++) {
+ ExpandableView child = algorithmState.visibleChildren.get(i);
+ StackScrollState.ViewState state = resultState.getViewStateForView(child);
+ float newYTranslation = state.yTranslation;
+ int newHeight = state.height;
+ // apply clipping and shadow
+ float newNotificationEnd = newYTranslation + newHeight;
+
+ // In the unlocked shade we have to clip a little bit higher because of the rounded
+ // corners of the notifications.
+ float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius;
+
+ // When the previous notification is swiped, we don't clip the content to the
+ // bottom of it.
+ float clipHeight = previousNotificationIsSwiped
+ ? newHeight
+ : newNotificationEnd - (previousNotificationEnd - clippingCorrection);
+
+ updateChildClippingAndBackground(state, newHeight, clipHeight,
+ (int) (newHeight - (previousNotificationStart - newYTranslation)));
+
+ if (!child.isTransparent()) {
+ // Only update the previous values if we are not transparent,
+ // otherwise we would clip to a transparent view.
+ previousNotificationStart = newYTranslation + child.getClipTopAmount();
+ previousNotificationEnd = newNotificationEnd;
+ previousNotificationIsSwiped = child.getTranslationX() != 0;
+ }
+ }
+ }
+
+ /**
+ * Updates the shadow outline and the clipping for a view.
+ *
+ * @param state the viewState to update
+ * @param realHeight the currently applied height of the view
+ * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
+ * @param backgroundHeight the desired background height. The shadows of the view will be
+ * based on this height and the content will be clipped from the top
+ */
+ private void updateChildClippingAndBackground(StackScrollState.ViewState state, int realHeight,
+ float clipHeight, int backgroundHeight) {
+ if (realHeight > clipHeight) {
+ state.topOverLap = (int) (realHeight - clipHeight);
+ } else {
+ state.topOverLap = 0;
+ }
+ if (realHeight > backgroundHeight) {
+ state.clipTopAmount = (realHeight - backgroundHeight);
+ } else {
+ state.clipTopAmount = 0;
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 44e10be..94cb16d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.stack;
-import android.graphics.Outline;
import android.graphics.Rect;
import android.util.Log;
import android.view.View;
@@ -37,15 +36,12 @@
private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild";
private final ViewGroup mHostView;
- private final int mRoundedRectCornerRadius;
private Map<ExpandableView, ViewState> mStateMap;
private final Rect mClipRect = new Rect();
public StackScrollState(ViewGroup hostView) {
mHostView = hostView;
mStateMap = new HashMap<ExpandableView, ViewState>();
- mRoundedRectCornerRadius = mHostView.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
}
public ViewGroup getHostView() {
@@ -83,9 +79,6 @@
*/
public void apply() {
int numChildren = mHostView.getChildCount();
- float previousNotificationEnd = 0;
- float previousNotificationStart = 0;
- boolean previousNotificationIsSwiped = false;
for (int i = 0; i < numChildren; i++) {
ExpandableView child = (ExpandableView) mHostView.getChildAt(i);
ViewState state = mStateMap.get(child);
@@ -155,39 +148,41 @@
// apply dimming
child.setDimmed(state.dimmed, false /* animate */);
- // apply clipping and shadow
- float newNotificationEnd = newYTranslation + newHeight;
+ float oldClipTopAmount = child.getClipTopAmount();
+ if (oldClipTopAmount != state.clipTopAmount) {
+ child.setClipTopAmount(state.clipTopAmount);
+ }
- // In the unlocked shade we have to clip a little bit higher because of the rounded
- // corners of the notifications.
- float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius;
-
- // When the previous notification is swiped, we don't clip the content to the
- // bottom of it.
- float clipHeight = previousNotificationIsSwiped
- ? newHeight
- : newNotificationEnd - (previousNotificationEnd - clippingCorrection);
-
- updateChildClippingAndBackground(child, newHeight,
- clipHeight,
- (int) (newHeight - (previousNotificationStart - newYTranslation)));
-
- if (!child.isTransparent()) {
- // Only update the previous values if we are not transparent,
- // otherwise we would clip to a transparent view.
- previousNotificationStart = newYTranslation + child.getClipTopAmount();
- previousNotificationEnd = newNotificationEnd;
- previousNotificationIsSwiped = child.getTranslationX() != 0;
+ if (state.topOverLap != 0) {
+ updateChildClip(child, newHeight, state.topOverLap);
+ } else {
+ child.setClipBounds(null);
}
if(child instanceof SpeedBumpView) {
- performSpeedBumpAnimation(i, (SpeedBumpView) child, newNotificationEnd,
+ float speedBumpEnd = newYTranslation + newHeight;
+ performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
newYTranslation);
}
}
}
}
+ /**
+ * Updates the clipping of a view
+ *
+ * @param child the view to update
+ * @param height the currently applied height of the view
+ * @param clipInset how much should this view be clipped from the top
+ */
+ private void updateChildClip(View child, int height, int clipInset) {
+ mClipRect.set(0,
+ clipInset,
+ child.getWidth(),
+ height);
+ child.setClipBounds(mClipRect);
+ }
+
private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
float speedBumpStart) {
View nextChild = getNextChildNotGone(i);
@@ -216,45 +211,6 @@
return null;
}
- /**
- * Updates the shadow outline and the clipping for a view.
- *
- * @param child the view to update
- * @param realHeight the currently applied height of the view
- * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
- * @param backgroundHeight the desired background height. The shadows of the view will be
- * based on this height and the content will be clipped from the top
- */
- private void updateChildClippingAndBackground(ExpandableView child, int realHeight,
- float clipHeight, int backgroundHeight) {
- if (realHeight > clipHeight) {
- updateChildClip(child, realHeight, clipHeight);
- } else {
- child.setClipBounds(null);
- }
- if (realHeight > backgroundHeight) {
- child.setClipTopAmount(realHeight - backgroundHeight);
- } else {
- child.setClipTopAmount(0);
- }
- }
-
- /**
- * Updates the clipping of a view
- *
- * @param child the view to update
- * @param height the currently applied height of the view
- * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
- */
- private void updateChildClip(View child, int height, float clipHeight) {
- int clipInset = (int) (height - clipHeight);
- mClipRect.set(0,
- clipInset,
- child.getWidth(),
- height);
- child.setClipBounds(mClipRect);
- }
-
public static class ViewState {
// These are flags such that we can create masks for filtering.
@@ -276,6 +232,18 @@
boolean dimmed;
/**
+ * The amount which the view should be clipped from the top. This is calculated to
+ * perceive consistent shadows.
+ */
+ int clipTopAmount;
+
+ /**
+ * How much does the child overlap with the previous view on the top? Can be used for
+ * a clipping optimization
+ */
+ int topOverLap;
+
+ /**
* The index of the view, only accounting for views not equal to GONE
*/
int notGoneIndex;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f019e6c..f41ab3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -133,10 +133,11 @@
boolean scaleChanging = child.getScaleX() != viewState.scale;
boolean alphaChanging = alpha != child.getAlpha();
boolean heightChanging = viewState.height != child.getActualHeight();
+ boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
boolean wasAdded = mNewAddChildren.contains(child);
boolean hasDelays = mAnimationFilter.hasDelays;
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
- alphaChanging || heightChanging;
+ alphaChanging || heightChanging || topInsetChanging;
long delay = 0;
if (hasDelays && isDelayRelevant || wasAdded) {
delay = calculateChildAnimationDelay(viewState, finalState);
@@ -167,6 +168,11 @@
startHeightAnimation(child, viewState, delay);
}
+ // start top inset animation
+ if (topInsetChanging) {
+ startInsetAnimation(child, viewState, delay);
+ }
+
// start dimmed animation
child.setDimmed(viewState.dimmed, mAnimationFilter.animateDimmed);
@@ -280,6 +286,64 @@
child.setTag(TAG_END_HEIGHT, newEndValue);
}
+ private void startInsetAnimation(final ExpandableView child,
+ StackScrollState.ViewState viewState, long delay) {
+ Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET);
+ Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET);
+ int newEndValue = viewState.clipTopAmount;
+ if (previousEndValue != null && previousEndValue == newEndValue) {
+ return;
+ }
+ ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TOP_INSET);
+ if (!mAnimationFilter.animateTopInset) {
+ // just a local update was performed
+ if (previousAnimator != null) {
+ // we need to increase all animation keyframes of the previous animator by the
+ // relative change to the end value
+ PropertyValuesHolder[] values = previousAnimator.getValues();
+ int relativeDiff = newEndValue - previousEndValue;
+ int newStartValue = previousStartValue + relativeDiff;
+ values[0].setIntValues(newStartValue, newEndValue);
+ child.setTag(TAG_START_TOP_INSET, newStartValue);
+ child.setTag(TAG_END_TOP_INSET, newEndValue);
+ previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+ return;
+ } else {
+ // no new animation needed, let's just apply the value
+ child.setClipTopAmount(newEndValue);
+ return;
+ }
+ }
+
+ ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ child.setClipTopAmount((int) animation.getAnimatedValue());
+ }
+ });
+ animator.setInterpolator(mFastOutSlowInInterpolator);
+ long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+ animator.setDuration(newDuration);
+ if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
+ animator.setStartDelay(delay);
+ }
+ animator.addListener(getGlobalAnimationFinishedListener());
+ // remove the tag when the animation is finished
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ child.setTag(TAG_ANIMATOR_TOP_INSET, null);
+ child.setTag(TAG_START_TOP_INSET, null);
+ child.setTag(TAG_END_TOP_INSET, null);
+ }
+ });
+ startAnimator(animator);
+ child.setTag(TAG_ANIMATOR_TOP_INSET, animator);
+ child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount());
+ child.setTag(TAG_END_TOP_INSET, newEndValue);
+ }
+
private void startAlphaAnimation(final ExpandableView child,
final StackScrollState.ViewState viewState, long delay) {
Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 25147b4..c2bd1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,12 +17,12 @@
package com.android.systemui.statusbar.tv;
import android.os.IBinder;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -50,7 +50,7 @@
}
@Override
- public void addNotificationInternal(StatusBarNotification notification) {
+ public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
}
@Override
@@ -58,7 +58,7 @@
}
@Override
- protected void removeNotificationInternal(String key) {
+ protected void removeNotificationInternal(String key, Ranking ranking) {
}
@Override
@@ -117,7 +117,7 @@
}
@Override
- protected void updateNotificationIcons() {
+ protected void updateNotifications() {
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 06f4c2e..67f3a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -1035,8 +1035,8 @@
if (isShowing()) {
if (mDialog != null) {
mDialog.dismiss();
+ mActiveStreamType = -1;
}
- mActiveStreamType = -1;
}
synchronized (sConfirmSafeVolumeLock) {
if (sConfirmSafeVolumeDialog != null) {
diff --git a/packages/services/PacProcessor/Android.mk b/packages/services/PacProcessor/Android.mk
index 79f8a1f..3c4e951 100644
--- a/packages/services/PacProcessor/Android.mk
+++ b/packages/services/PacProcessor/Android.mk
@@ -27,8 +27,6 @@
LOCAL_JNI_SHARED_LIBRARIES := libjni_pacprocessor
-LOCAL_MULTILIB := 32
-
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/services/PacProcessor/jni/Android.mk b/packages/services/PacProcessor/jni/Android.mk
index 8a60927..f16c90b 100644
--- a/packages/services/PacProcessor/jni/Android.mk
+++ b/packages/services/PacProcessor/jni/Android.mk
@@ -35,7 +35,6 @@
LOCAL_MODULE := libjni_pacprocessor
LOCAL_MODULE_TAGS := optional
-LOCAL_32_BIT_ONLY := true
include external/stlport/libstlport.mk
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 2fea785..6b0095a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -3179,7 +3179,9 @@
com.android.internal.R.attr.dialogTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
- layoutResource = com.android.internal.R.layout.screen_action_bar;
+ layoutResource = a.getResourceId(
+ com.android.internal.R.styleable.Window_windowActionBarFullscreenDecorLayout,
+ com.android.internal.R.layout.screen_action_bar);
} else {
layoutResource = com.android.internal.R.layout.screen_title;
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3c37902..1a7c0a8 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -355,6 +355,10 @@
// the same as mCur*, but may be larger if the screen decor has supplied
// content insets.
int mContentLeft, mContentTop, mContentRight, mContentBottom;
+ // During layout, the frame in which voice content should be displayed
+ // to the user, accounting for all screen decoration except for any
+ // space they deem as available for other content.
+ int mVoiceContentLeft, mVoiceContentTop, mVoiceContentRight, mVoiceContentBottom;
// During layout, the current screen borders along which input method
// windows are placed.
int mDockLeft, mDockTop, mDockRight, mDockBottom;
@@ -479,7 +483,6 @@
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
- private static final int MSG_DISPATCH_SHOW_RECENTS = 5;
private class PolicyHandler extends Handler {
@Override
@@ -497,9 +500,6 @@
case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
break;
- case MSG_DISPATCH_SHOW_RECENTS:
- showRecentApps(false);
- break;
}
}
}
@@ -1266,6 +1266,7 @@
case TYPE_INPUT_METHOD:
case TYPE_WALLPAPER:
case TYPE_PRIVATE_PRESENTATION:
+ case TYPE_VOICE_INTERACTION:
// The window manager will check these.
break;
case TYPE_PHONE:
@@ -1432,74 +1433,77 @@
return 3;
case TYPE_SEARCH_BAR:
return 4;
+ case TYPE_VOICE_INTERACTION:
+ // voice interaction layer is almost immediately above apps.
+ return 5;
case TYPE_RECENTS_OVERLAY:
case TYPE_SYSTEM_DIALOG:
- return 5;
+ return 6;
case TYPE_TOAST:
// toasts and the plugged-in battery thing
- return 6;
+ return 7;
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
- return 7;
+ return 8;
case TYPE_DREAM:
// used for Dreams (screensavers with TYPE_DREAM windows)
- return 8;
+ return 9;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
- return 9;
+ return 10;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
- return 10;
+ return 11;
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
- return 11;
+ return 12;
case TYPE_KEYGUARD_SCRIM:
// the safety window that shows behind keyguard while keyguard is starting
- return 12;
- case TYPE_STATUS_BAR_SUB_PANEL:
return 13;
- case TYPE_STATUS_BAR:
+ case TYPE_STATUS_BAR_SUB_PANEL:
return 14;
- case TYPE_STATUS_BAR_PANEL:
+ case TYPE_STATUS_BAR:
return 15;
- case TYPE_KEYGUARD_DIALOG:
+ case TYPE_STATUS_BAR_PANEL:
return 16;
+ case TYPE_KEYGUARD_DIALOG:
+ return 17;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 17;
+ return 18;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 18;
+ return 19;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
- return 19;
+ return 20;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
- return 20;
+ return 21;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
- return 21;
+ return 22;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
- return 22;
+ return 23;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
- return 23;
+ return 24;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- return 24;
- case TYPE_SECURE_SYSTEM_OVERLAY:
return 25;
- case TYPE_BOOT_PROGRESS:
+ case TYPE_SECURE_SYSTEM_OVERLAY:
return 26;
+ case TYPE_BOOT_PROGRESS:
+ return 27;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 27;
- case TYPE_HIDDEN_NAV_CONSUMER:
return 28;
+ case TYPE_HIDDEN_NAV_CONSUMER:
+ return 29;
}
Log.e(TAG, "Unknown window type: " + type);
return 2;
@@ -1568,11 +1572,16 @@
}
@Override
- public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
+ public boolean doesForceHide(WindowManager.LayoutParams attrs) {
return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
}
@Override
+ public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
+ return attrs.type == TYPE_STATUS_BAR;
+ }
+
+ @Override
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
switch (attrs.type) {
case TYPE_STATUS_BAR:
@@ -2459,12 +2468,6 @@
}
}
- @Override
- public void showRecentApps() {
- mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS);
- mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_RECENTS);
- }
-
private void showRecentApps(boolean triggeredFromAltTab) {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
try {
@@ -2711,13 +2714,13 @@
mRestrictedScreenTop = mUnrestrictedScreenTop;
mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth;
mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight;
- mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft
+ mDockLeft = mContentLeft = mVoiceContentLeft = mStableLeft = mStableFullscreenLeft
= mCurLeft = mUnrestrictedScreenLeft;
- mDockTop = mContentTop = mStableTop = mStableFullscreenTop
+ mDockTop = mContentTop = mVoiceContentTop = mStableTop = mStableFullscreenTop
= mCurTop = mUnrestrictedScreenTop;
- mDockRight = mContentRight = mStableRight = mStableFullscreenRight
+ mDockRight = mContentRight = mVoiceContentRight = mStableRight = mStableFullscreenRight
= mCurRight = displayWidth - overscanRight;
- mDockBottom = mContentBottom = mStableBottom = mStableFullscreenBottom
+ mDockBottom = mContentBottom = mVoiceContentBottom = mStableBottom = mStableFullscreenBottom
= mCurBottom = displayHeight - overscanBottom;
mDockLayer = 0x10000000;
mStatusBarLayer = -1;
@@ -2828,10 +2831,10 @@
}
// Make sure the content and current rectangles are updated to
// account for the restrictions from the navigation bar.
- mContentTop = mCurTop = mDockTop;
- mContentBottom = mCurBottom = mDockBottom;
- mContentLeft = mCurLeft = mDockLeft;
- mContentRight = mCurRight = mDockRight;
+ mContentTop = mVoiceContentTop = mCurTop = mDockTop;
+ mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom;
+ mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft;
+ mContentRight = mVoiceContentRight = mCurRight = mDockRight;
mStatusBarLayer = mNavigationBar.getSurfaceLayer();
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
@@ -2878,10 +2881,10 @@
// status bar is visible.
mDockTop = mUnrestrictedScreenTop + mStatusBarHeight;
- mContentTop = mCurTop = mDockTop;
- mContentBottom = mCurBottom = mDockBottom;
- mContentLeft = mCurLeft = mDockLeft;
- mContentRight = mCurRight = mDockRight;
+ mContentTop = mVoiceContentTop = mCurTop = mDockTop;
+ mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom;
+ mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft;
+ mContentRight = mVoiceContentRight = mCurRight = mDockRight;
if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " +
String.format(
@@ -2952,7 +2955,12 @@
// Ungh. So to deal with that, make sure the content frame
// we end up using is not covering the IM dock.
cf.set(attached.getContentFrameLw());
- if (attached.getSurfaceLayer() < mDockLayer) {
+ if (attached.isVoiceInteraction()) {
+ if (cf.left < mVoiceContentLeft) cf.left = mVoiceContentLeft;
+ if (cf.top < mVoiceContentTop) cf.top = mVoiceContentTop;
+ if (cf.right > mVoiceContentRight) cf.right = mVoiceContentRight;
+ if (cf.bottom > mVoiceContentBottom) cf.bottom = mVoiceContentBottom;
+ } else if (attached.getSurfaceLayer() < mDockLayer) {
if (cf.left < mContentLeft) cf.left = mContentLeft;
if (cf.top < mContentTop) cf.top = mContentTop;
if (cf.right > mContentRight) cf.right = mContentRight;
@@ -3160,16 +3168,23 @@
}
if ((fl & FLAG_FULLSCREEN) == 0) {
- if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
- cf.left = mDockLeft;
- cf.top = mDockTop;
- cf.right = mDockRight;
- cf.bottom = mDockBottom;
+ if (win.isVoiceInteraction()) {
+ cf.left = mVoiceContentLeft;
+ cf.top = mVoiceContentTop;
+ cf.right = mVoiceContentRight;
+ cf.bottom = mVoiceContentBottom;
} else {
- cf.left = mContentLeft;
- cf.top = mContentTop;
- cf.right = mContentRight;
- cf.bottom = mContentBottom;
+ if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
+ cf.left = mDockLeft;
+ cf.top = mDockTop;
+ cf.right = mDockRight;
+ cf.bottom = mDockBottom;
+ } else {
+ cf.left = mContentLeft;
+ cf.top = mContentTop;
+ cf.right = mContentRight;
+ cf.bottom = mContentBottom;
+ }
}
} else {
// Full screen windows are always given a layout that is as if the
@@ -3381,6 +3396,10 @@
setLastInputMethodWindowLw(null, null);
offsetInputMethodWindowLw(win);
}
+ if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleOrBehindKeyguardLw()
+ && !win.getGivenInsetsPendingLw()) {
+ offsetVoiceInputWindowLw(win);
+ }
}
private void offsetInputMethodWindowLw(WindowState win) {
@@ -3389,6 +3408,9 @@
if (mContentBottom > top) {
mContentBottom = top;
}
+ if (mVoiceContentBottom > top) {
+ mVoiceContentBottom = top;
+ }
top = win.getVisibleFrameLw().top;
top += win.getGivenVisibleInsetsLw().top;
if (mCurBottom > top) {
@@ -3399,6 +3421,40 @@
+ mContentBottom + " mCurBottom=" + mCurBottom);
}
+ private void offsetVoiceInputWindowLw(WindowState win) {
+ final int gravity = win.getAttrs().gravity;
+ switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER)
+ << Gravity.AXIS_X_SHIFT)) {
+ case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_X_SHIFT: {
+ int right = win.getContentFrameLw().right - win.getGivenContentInsetsLw().right;
+ if (mVoiceContentLeft < right) {
+ mVoiceContentLeft = right;
+ }
+ } break;
+ case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_X_SHIFT: {
+ int left = win.getContentFrameLw().left - win.getGivenContentInsetsLw().left;
+ if (mVoiceContentRight < left) {
+ mVoiceContentRight = left;
+ }
+ } break;
+ }
+ switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER)
+ << Gravity.AXIS_Y_SHIFT)) {
+ case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_Y_SHIFT: {
+ int bottom = win.getContentFrameLw().bottom - win.getGivenContentInsetsLw().bottom;
+ if (mVoiceContentTop < bottom) {
+ mVoiceContentTop = bottom;
+ }
+ } break;
+ case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_Y_SHIFT: {
+ int top = win.getContentFrameLw().top - win.getGivenContentInsetsLw().top;
+ if (mVoiceContentBottom < top) {
+ mVoiceContentBottom = top;
+ }
+ } break;
+ }
+ }
+
/** {@inheritDoc} */
@Override
public void finishLayoutLw() {
@@ -4509,6 +4565,18 @@
}
}
+ @Override
+ public void startKeyguardExitAnimation(final long fadeoutDuration) {
+ if (mKeyguardDelegate != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mKeyguardDelegate.startKeyguardExitAnimation(fadeoutDuration);
+ }
+ });
+ }
+ }
+
void sendCloseSystemWindows() {
sendCloseSystemWindows(mContext, null);
}
@@ -5482,6 +5550,10 @@
pw.print(","); pw.print(mContentTop);
pw.print(")-("); pw.print(mContentRight);
pw.print(","); pw.print(mContentBottom); pw.println(")");
+ pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft);
+ pw.print(","); pw.print(mVoiceContentTop);
+ pw.print(")-("); pw.print(mVoiceContentRight);
+ pw.print(","); pw.print(mVoiceContentBottom); pw.println(")");
pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft);
pw.print(","); pw.print(mDockTop);
pw.print(")-("); pw.print(mDockRight);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 966924b..faf7020 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -274,6 +274,12 @@
mKeyguardState.currentUser = newUserId;
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ if (mKeyguardService != null) {
+ mKeyguardService.startKeyguardExitAnimation(fadeoutDuration);
+ }
+ }
+
private static final View createScrim(Context context) {
View view = new View(context);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
index 7cb48fa..f236ce7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -190,6 +190,14 @@
}
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ try {
+ mService.startKeyguardExitAnimation(fadeoutDuration);
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
public void showAssistant() {
// Not used by PhoneWindowManager
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 87b1d32..7a67d63 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -843,6 +843,15 @@
throw new IllegalArgumentException("Unknown component " + componentName);
}
+ // Ensure that the service specified by the passed intent belongs to the same package
+ // as provides the passed widget id.
+ String widgetIdPackage = id.provider.info.provider.getPackageName();
+ String servicePackage = componentName.getPackageName();
+ if (!servicePackage.equals(widgetIdPackage)) {
+ throw new SecurityException("Specified intent doesn't belong to the same package"
+ + " as the provided AppWidget id");
+ }
+
// If there is already a connection made for this service intent, then disconnect from
// that first. (This does not allow multiple connections to the same service under
// the same key)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1e21e1c..5527528 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5606,16 +5606,23 @@
boolean isNewDefault = false;
if (DBG) log("handleConnectionValidated for "+newNetwork.name());
// check if any NetworkRequest wants this NetworkAgent
- // first check if it satisfies the NetworkCapabilities
ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
if (VDBG) log(" new Network has: " + newNetwork.networkCapabilities);
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
+ NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
+ if (newNetwork == currentNetwork) {
+ if (VDBG) log("Network " + newNetwork.name() + " was already satisfying" +
+ " request " + nri.request.requestId + ". No change.");
+ keep = true;
+ continue;
+ }
+
+ // check if it satisfies the NetworkCapabilities
if (VDBG) log(" checking if request is satisfied: " + nri.request);
if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
newNetwork.networkCapabilities)) {
// next check if it's better than any current network we're using for
// this request
- NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
if (VDBG) {
log("currentScore = " +
(currentNetwork != null ? currentNetwork.currentScore : 0) +
@@ -5744,12 +5751,19 @@
}
if (state == NetworkInfo.State.CONNECTED) {
- // TODO - check if we want it (optimization)
try {
+ // This is likely caused by the fact that this network already
+ // exists. An example is when a network goes from CONNECTED to
+ // CONNECTING and back (like wifi on DHCP renew).
+ // TODO: keep track of which networks we've created, or ask netd
+ // to tell us whether we've already created this network or not.
mNetd.createNetwork(networkAgent.network.netId);
} catch (Exception e) {
- loge("Error creating Network " + networkAgent.network.netId);
+ loge("Error creating network " + networkAgent.network.netId + ": "
+ + e.getMessage());
+ return;
}
+
updateLinkProperties(networkAgent, null);
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index dd36645..eebb503 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -988,7 +988,8 @@
sInfo.applicationInfo.packageName, sInfo.name);
if (userId > 0) {
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
- sInfo.name, sInfo.flags)) {
+ sInfo.name, sInfo.flags)
+ && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
userId = 0;
smap = getServiceMap(0);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f2a1698..fd31b41 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -2189,7 +2190,7 @@
mBatteryStatsService.publish(mContext);
mUsageStatsService.publish(mContext);
mAppOpsService.publish(mContext);
-
+ Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
@@ -7753,7 +7754,7 @@
* in {@link ContentProvider}.
*/
private final String checkContentProviderPermissionLocked(
- ProviderInfo cpi, ProcessRecord r, int userId) {
+ ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
@@ -7770,8 +7771,10 @@
}
}
}
- userId = handleIncomingUser(callingPid, callingUid, userId,
- false, true, "checkContentProviderPermissionLocked", null);
+ if (checkUser) {
+ userId = handleIncomingUser(callingPid, callingUid, userId,
+ false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
+ }
if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
cpi.applicationInfo.uid, cpi.exported)
== PackageManager.PERMISSION_GRANTED) {
@@ -7906,13 +7909,34 @@
}
}
+ boolean checkCrossUser = true;
+
// First check if this content provider has been published...
cpr = mProviderMap.getProviderByName(name, userId);
+ // If that didn't work, check if it exists for user 0 and then
+ // verify that it's a singleton provider before using it.
+ if (cpr == null && userId != UserHandle.USER_OWNER) {
+ cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
+ if (cpr != null) {
+ cpi = cpr.info;
+ if (isSingleton(cpi.processName, cpi.applicationInfo,
+ cpi.name, cpi.flags)
+ && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
+ userId = UserHandle.USER_OWNER;
+ checkCrossUser = false;
+ } else {
+ cpr = null;
+ cpi = null;
+ }
+ }
+ }
+
boolean providerRunning = cpr != null;
if (providerRunning) {
cpi = cpr.info;
String msg;
- if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
+ if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
+ != null) {
throw new SecurityException(msg);
}
@@ -7992,15 +8016,21 @@
if (cpi == null) {
return null;
}
+ // If the provider is a singleton AND
+ // (it's a call within the same user || the provider is a
+ // privileged app)
+ // Then allow connecting to the singleton provider
singleton = isSingleton(cpi.processName, cpi.applicationInfo,
- cpi.name, cpi.flags);
+ cpi.name, cpi.flags)
+ && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
if (singleton) {
- userId = 0;
+ userId = UserHandle.USER_OWNER;
}
cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
String msg;
- if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
+ if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
+ != null) {
throw new SecurityException(msg);
}
@@ -10579,8 +10609,7 @@
// assume our apps are happy - lazy create the list
List<ActivityManager.ProcessErrorStateInfo> errList = null;
- final boolean allUsers = ActivityManager.checkUidPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
int userId = UserHandle.getUserId(Binder.getCallingUid());
@@ -10669,8 +10698,7 @@
enforceNotIsolatedCaller("getRunningAppProcesses");
// Lazy instantiation of list
List<ActivityManager.RunningAppProcessInfo> runList = null;
- final boolean allUsers = ActivityManager.checkUidPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
int userId = UserHandle.getUserId(Binder.getCallingUid());
synchronized (this) {
@@ -13110,8 +13138,7 @@
if ((requireFull || checkComponentPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS,
callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
- && checkComponentPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
callingPid, callingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
if (userId == UserHandle.USER_CURRENT_OR_SELF) {
@@ -13131,7 +13158,7 @@
builder.append(" but is calling from user ");
builder.append(UserHandle.getUserId(callingUid));
builder.append("; this requires ");
- builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ builder.append(INTERACT_ACROSS_USERS_FULL);
if (!requireFull) {
builder.append(" or ");
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
@@ -13161,8 +13188,9 @@
boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
String className, int flags) {
boolean result = false;
+ // For apps that don't have pre-defined UIDs, check for permission
if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
- if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
+ if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
if (ActivityManager.checkUidPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS,
aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
@@ -13173,12 +13201,14 @@
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
+ // Permission passed
result = true;
}
- } else if (componentProcessName == aInfo.packageName) {
- result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
} else if ("system".equals(componentProcessName)) {
result = true;
+ } else {
+ // App with pre-defined UID, check if it's a persistent app
+ result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
}
if (DEBUG_MU) {
Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
@@ -13187,6 +13217,21 @@
return result;
}
+ /**
+ * Checks to see if the caller is in the same app as the singleton
+ * component, or the component is in a special app. It allows special apps
+ * to export singleton components but prevents exporting singleton
+ * components for regular apps.
+ */
+ boolean isValidSingletonCall(int callingUid, int componentUid) {
+ int componentAppId = UserHandle.getAppId(componentUid);
+ return UserHandle.isSameApp(callingUid, componentUid)
+ || componentAppId == Process.SYSTEM_UID
+ || componentAppId == Process.PHONE_UID
+ || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
@@ -13733,8 +13778,8 @@
*/
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
- || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
- callingUid == 0) {
+ || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
+ || callingUid == 0) {
// Always okay.
} else if (callerApp == null || !callerApp.persistent) {
try {
@@ -16544,12 +16589,12 @@
}
private boolean startUser(final int userId, boolean foreground) {
- if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: switchUser() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
- + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+ + " requires " + INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
@@ -16915,12 +16960,12 @@
@Override
public int stopUser(final int userId, final IStopUserCallback callback) {
- if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: switchUser() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
- + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+ + " requires " + INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
@@ -17058,7 +17103,7 @@
public UserInfo getCurrentUser() {
if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
!= PackageManager.PERMISSION_GRANTED) && (
- checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED)) {
String msg = "Permission Denial: getCurrentUser() from pid="
+ Binder.getCallingPid()
@@ -17144,12 +17189,12 @@
@Override
public void registerUserSwitchObserver(IUserSwitchObserver observer) {
- if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: registerUserSwitchObserver() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
- + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+ + " requires " + INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b56046e..16ad153 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -30,10 +30,6 @@
import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY;
import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
-
import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
@@ -1067,6 +1063,40 @@
}
}
+ /**
+ * Determine if home should be visible below the passed record.
+ * @param record activity we are querying for.
+ * @return true if home is visible below the passed activity, false otherwise.
+ */
+ boolean isActivityOverHome(ActivityRecord record) {
+ // Start at record and go down, look for either home or a visible fullscreen activity.
+ final TaskRecord recordTask = record.task;
+ for (int taskNdx = mTaskHistory.indexOf(recordTask); taskNdx >= 0; --taskNdx) {
+ TaskRecord task = mTaskHistory.get(taskNdx);
+ final ArrayList<ActivityRecord> activities = task.mActivities;
+ final int startNdx =
+ task == recordTask ? activities.indexOf(record) : activities.size() - 1;
+ for (int activityNdx = startNdx; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r = activities.get(activityNdx);
+ if (r.isHomeActivity()) {
+ return true;
+ }
+ if (!r.finishing && r.fullscreen) {
+ // Passed activity is over a fullscreen activity.
+ return false;
+ }
+ }
+ if (task.mOnTopOfHome) {
+ // Got to the bottom of a task on top of home without finding a visible fullscreen
+ // activity. Home is visible.
+ return true;
+ }
+ }
+ // Got to the bottom of this stack and still don't know. If this is over the home stack
+ // then record is over home. May not work if we ever get more than two layers.
+ return mStackSupervisor.isFrontStack(this);
+ }
+
private void setVisibile(ActivityRecord r, boolean visible) {
r.visible = visible;
mWindowManager.setAppVisibility(r.appToken, visible);
@@ -1096,8 +1126,7 @@
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++) {
- final TaskRecord task = tasks.get(taskNdx);
- final ArrayList<ActivityRecord> activities = task.mActivities;
+ final ArrayList<ActivityRecord> activities = tasks.get(taskNdx).mActivities;
for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) {
final ActivityRecord r = activities.get(activityNdx);
@@ -1108,7 +1137,7 @@
// - Full Screen Activity OR
// - On top of Home and our stack is NOT home
if (!r.finishing && r.visible && (r.fullscreen ||
- (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) {
+ (!isHomeStack() && r.frontOfTask && tasks.get(taskNdx).mOnTopOfHome))) {
return false;
}
}
@@ -1236,7 +1265,7 @@
// At this point, nothing else needs to be shown
if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
behindFullscreen = true;
- } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
+ } else if (!isHomeStack() && r.frontOfTask && task.mOnTopOfHome) {
if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
behindFullscreen = true;
}
@@ -1390,7 +1419,6 @@
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
- final TaskRecord prevTask = prev != null ? prev.task : null;
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
@@ -1398,10 +1426,7 @@
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
+ return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
}
next.delayedResume = false;
@@ -1420,24 +1445,22 @@
}
final TaskRecord nextTask = next.task;
+ final TaskRecord prevTask = prev != null ? prev.task : null;
if (prevTask != null && prevTask.stack == this &&
- prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
+ prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) {
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
if (prevTask == nextTask) {
prevTask.setFrontOfTask();
} else if (prevTask != topTask()) {
- // This task is going away but it was supposed to return to the home stack.
+ // This task is going away but it was supposed to return to the home task.
// Now the task above it has to return to the home task instead.
final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
- mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ mTaskHistory.get(taskNdx).mOnTopOfHome = true;
} else {
if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG,
"resumeTopActivityLocked: Launching home next");
// Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
+ return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
}
}
@@ -1808,11 +1831,10 @@
ActivityStack lastStack = mStackSupervisor.getLastStack();
final boolean fromHome = lastStack.isHomeStack();
if (!isHomeStack() && (fromHome || topTask() != task)) {
- task.setTaskToReturnTo(fromHome ?
- lastStack.topTask().taskType : APPLICATION_ACTIVITY_TYPE);
+ task.mOnTopOfHome = fromHome;
}
} else {
- task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+ task.mOnTopOfHome = false;
}
mTaskHistory.remove(task);
@@ -1860,7 +1882,7 @@
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
- r.userId, r.info.configChanges);
+ r.userId, r.info.configChanges, task.voiceSession != null);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -1921,7 +1943,7 @@
mWindowManager.addAppToken(task.mActivities.indexOf(r),
r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
- r.info.configChanges);
+ r.info.configChanges, task.voiceSession != null);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -1966,7 +1988,7 @@
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
- r.info.configChanges);
+ r.info.configChanges, task.voiceSession != null);
ActivityOptions.abort(options);
options = null;
}
@@ -2357,8 +2379,8 @@
ActivityRecord next = topRunningActivityLocked(null);
if (next != r) {
final TaskRecord task = r.task;
- if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo());
+ if (r.frontOfTask && task == topTask() && task.mOnTopOfHome) {
+ mStackSupervisor.moveHomeToTop();
}
}
ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
@@ -2845,9 +2867,8 @@
if (task != null && task.removeActivity(r)) {
if (DEBUG_STACK) Slog.i(TAG,
"removeActivityFromHistoryLocked: last activity removed from " + this);
- if (mStackSupervisor.isFrontStack(this) && task == topTask() &&
- task.isOverHomeStack()) {
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo());
+ if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) {
+ mStackSupervisor.moveHomeToTop();
}
removeTask(task);
}
@@ -3162,13 +3183,12 @@
}
}
- void moveHomeStackTaskToTop(int homeStackTaskType) {
+ void moveHomeTaskToTop() {
final int top = mTaskHistory.size() - 1;
for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.taskType == homeStackTaskType) {
- if (DEBUG_TASKS || DEBUG_STACK)
- Slog.d(TAG, "moveHomeStackTaskToTop: moving " + task);
+ if (task.isHomeTask()) {
+ if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG, "moveHomeTaskToTop: moving " + task);
mTaskHistory.remove(taskNdx);
mTaskHistory.add(top, task);
updateTaskMovement(task, true);
@@ -3280,12 +3300,12 @@
int numTasks = mTaskHistory.size();
for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.isOverHomeStack()) {
+ if (task.mOnTopOfHome) {
break;
}
if (taskNdx == 1) {
// Set the last task before tr to go to home.
- task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ task.mOnTopOfHome = true;
}
}
@@ -3306,10 +3326,9 @@
}
final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
- if (task == tr && tr.isOverHomeStack() || numTasks <= 1 && isOnHomeDisplay()) {
- final int taskToReturnTo = tr.getTaskToReturnTo();
- tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null);
+ if (task == tr && tr.mOnTopOfHome || numTasks <= 1 && isOnHomeDisplay()) {
+ tr.mOnTopOfHome = false;
+ return mStackSupervisor.resumeHomeActivity(null);
}
mStackSupervisor.resumeTopActivitiesLocked();
@@ -3750,11 +3769,8 @@
final int taskNdx = mTaskHistory.indexOf(task);
final int topTaskNdx = mTaskHistory.size() - 1;
- if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
- final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
- if (!nextTask.isOverHomeStack()) {
- nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
- }
+ if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
+ mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
}
mTaskHistory.remove(task);
updateTaskMovement(task, true);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 29a1708..598e524 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -31,9 +31,6 @@
import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityManagerService.TAG;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import android.app.Activity;
import android.app.ActivityManager;
@@ -347,27 +344,18 @@
}
}
- void moveHomeStackTaskToTop(int homeStackTaskType) {
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return;
- }
+ void moveHomeToTop() {
moveHomeStack(true);
- mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+ mHomeStack.moveHomeTaskToTop();
}
- boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) {
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return false;
- }
- moveHomeStackTaskToTop(homeStackTaskType);
+ boolean resumeHomeActivity(ActivityRecord prev) {
+ moveHomeToTop();
if (prev != null) {
- prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+ prev.task.mOnTopOfHome = false;
}
-
ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
- if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
+ if (r != null && r.isHomeActivity()) {
mService.setFocusedActivityLocked(r);
return resumeTopActivitiesLocked(mHomeStack, prev, null);
}
@@ -721,7 +709,7 @@
}
void startHomeActivity(Intent intent, ActivityInfo aInfo) {
- moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE);
+ moveHomeToTop();
startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0,
null, false, null, null);
}
@@ -1656,7 +1644,7 @@
(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity.
- intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ intentActivity.task.mOnTopOfHome = true;
}
options = null;
}
@@ -1841,11 +1829,6 @@
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, true), null, true);
- if (sourceRecord == null) {
- // Launched from a service or notification or task that is finishing.
- r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ?
- mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE);
- }
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
r.task);
} else {
@@ -1857,7 +1840,7 @@
== (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity, so before starting
// their own activity we will bring home to the front.
- r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
}
}
} else if (sourceRecord != null) {
@@ -2208,7 +2191,7 @@
if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just indicate that this task returns to the home task.
- task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ task.mOnTopOfHome = true;
}
task.stack.moveTaskToFrontLocked(task, null, options);
if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
@@ -2315,11 +2298,11 @@
mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
- r.userId, r.info.configChanges);
+ r.userId, r.info.configChanges, task.voiceSession != null);
}
mWindowManager.addTask(taskId, stackId, false);
}
- resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
+ resumeHomeActivity(null);
}
void moveTaskToStack(int taskId, int stackId, boolean toTop) {
@@ -2581,7 +2564,7 @@
}
} else {
// Stack was moved to another display while user was swapped out.
- resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
+ resumeHomeActivity(null);
}
return homeInFront;
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 9d6481a..7b2b04d 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -27,6 +27,7 @@
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
@@ -858,7 +859,10 @@
r.state = BroadcastRecord.APP_RECEIVE;
String targetProcess = info.activityInfo.processName;
r.curComponent = component;
- if (r.callingUid != Process.SYSTEM_UID && isSingleton) {
+ final int receiverUid = info.activityInfo.applicationInfo.uid;
+ // If it's a singleton, it needs to be the same app or a special app
+ if (r.callingUid != Process.SYSTEM_UID && isSingleton
+ && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
}
r.curReceiver = info.activityInfo;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c07bc1e..ce83ae6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -17,9 +17,6 @@
package com.android.server.am;
import static com.android.server.am.ActivityManagerService.TAG;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
import android.app.Activity;
@@ -57,6 +54,7 @@
private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
private static final String ATTR_USERID = "user_id";
private static final String ATTR_TASKTYPE = "task_type";
+ private static final String ATTR_ONTOPOFHOME = "on_top_of_home";
private static final String ATTR_LASTDESCRIPTION = "last_description";
private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
@@ -106,11 +104,9 @@
/** True if persistable, has changed, and has not yet been persisted */
boolean needsPersisting = false;
-
- /** Indication of what to run next when task exits. Use ActivityRecord types.
- * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
- * task stack. */
- private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
+ /** Launch the home activity when leaving this task. Will be false for tasks that are not on
+ * Display.DEFAULT_DISPLAY. */
+ boolean mOnTopOfHome = false;
final ActivityManagerService mService;
@@ -127,8 +123,9 @@
TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
String _affinity, ComponentName _realActivity, ComponentName _origActivity,
- boolean _rootWasReset, boolean _askedCompatMode, int _taskType, int _userId,
- String _lastDescription, ArrayList<ActivityRecord> activities, long lastTimeMoved) {
+ boolean _rootWasReset, boolean _askedCompatMode, int _taskType, boolean _onTopOfHome,
+ int _userId, String _lastDescription, ArrayList<ActivityRecord> activities,
+ long lastTimeMoved) {
mService = service;
taskId = _taskId;
intent = _intent;
@@ -141,7 +138,7 @@
rootWasReset = _rootWasReset;
askedCompatMode = _askedCompatMode;
taskType = _taskType;
- mTaskToReturnTo = HOME_ACTIVITY_TYPE;
+ mOnTopOfHome = _onTopOfHome;
userId = _userId;
lastDescription = _lastDescription;
mActivities = activities;
@@ -209,14 +206,6 @@
}
}
- void setTaskToReturnTo(int taskToReturnTo) {
- mTaskToReturnTo = taskToReturnTo;
- }
-
- int getTaskToReturnTo() {
- return mTaskToReturnTo;
- }
-
void disposeThumbnail() {
super.disposeThumbnail();
for (int i=mActivities.size()-1; i>=0; i--) {
@@ -488,15 +477,11 @@
}
boolean isHomeTask() {
- return taskType == HOME_ACTIVITY_TYPE;
+ return taskType == ActivityRecord.HOME_ACTIVITY_TYPE;
}
boolean isApplicationTask() {
- return taskType == APPLICATION_ACTIVITY_TYPE;
- }
-
- boolean isOverHomeStack() {
- return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
+ return taskType == ActivityRecord.APPLICATION_ACTIVITY_TYPE;
}
public TaskAccessInfo getTaskAccessInfoLocked() {
@@ -638,6 +623,7 @@
out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
out.attribute(null, ATTR_USERID, String.valueOf(userId));
out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
+ out.attribute(null, ATTR_ONTOPOFHOME, String.valueOf(mOnTopOfHome));
out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
if (lastDescription != null) {
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
@@ -683,6 +669,7 @@
boolean rootHasReset = false;
boolean askedCompatMode = false;
int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+ boolean onTopOfHome = true;
int userId = 0;
String lastDescription = null;
long lastTimeOnTop = 0;
@@ -710,6 +697,8 @@
userId = Integer.valueOf(attrValue);
} else if (ATTR_TASKTYPE.equals(attrName)) {
taskType = Integer.valueOf(attrValue);
+ } else if (ATTR_ONTOPOFHOME.equals(attrName)) {
+ onTopOfHome = Boolean.valueOf(attrValue);
} else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
lastDescription = attrValue;
} else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
@@ -747,7 +736,8 @@
final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
affinityIntent, affinity, realActivity, origActivity, rootHasReset,
- askedCompatMode, taskType, userId, lastDescription, activities, lastTimeOnTop);
+ askedCompatMode, taskType, onTopOfHome, userId, lastDescription, activities,
+ lastTimeOnTop);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
@@ -766,7 +756,7 @@
pw.print(" userId="); pw.print(userId);
pw.print(" taskType="); pw.print(taskType);
pw.print(" numFullscreen="); pw.print(numFullscreen);
- pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
+ pw.print(" mOnTopOfHome="); pw.println(mOnTopOfHome);
}
if (affinity != null) {
pw.print(prefix); pw.print("affinity="); pw.println(affinity);
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index c7d2871..8fd55e7 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -230,7 +230,7 @@
// Notify for any user other than the caller's own requires permission.
final int callingUserHandle = UserHandle.getCallingUserId();
if (userHandle != callingUserHandle) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
"no permission to notify other users");
}
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
new file mode 100644
index 0000000..d46cc7b
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
@@ -0,0 +1,361 @@
+/*
+ * 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.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Feature action that handles device discovery sequences.
+ * Device discovery is launched when TV device is woken from "Standby" state
+ * or enabled "Control for Hdmi" from disabled state.
+ *
+ * <p>Device discovery goes through the following steps.
+ * <ol>
+ * <li>Poll all non-local devices by sending <Polling Message>
+ * <li>Gather "Physical address" and "device type" of all acknowledged devices
+ * <li>Gather "OSD (display) name" of all acknowledge devices
+ * <li>Gather "Vendor id" of all acknowledge devices
+ * </ol>
+ */
+final class DeviceDiscoveryAction extends FeatureAction {
+ private static final String TAG = "DeviceDiscoveryAction";
+
+ // State in which the action is waiting for device polling.
+ private static final int STATE_WAITING_FOR_DEVICE_POLLING = 1;
+ // State in which the action is waiting for gathering physical address of non-local devices.
+ private static final int STATE_WAITING_FOR_PHYSICAL_ADDRESS = 2;
+ // State in which the action is waiting for gathering osd name of non-local devices.
+ private static final int STATE_WAITING_FOR_OSD_NAME = 3;
+ // State in which the action is waiting for gathering vendor id of non-local devices.
+ private static final int STATE_WAITING_FOR_VENDOR_ID = 4;
+
+ private static final int DEVICE_POLLING_RETRY = 1;
+
+ // TODO: Move this to common place
+ private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
+
+ /**
+ * Interface used to report result of device discovery.
+ */
+ interface DeviceDiscoveryCallback {
+ /**
+ * Called when device discovery is done.
+ *
+ * @param deviceInfos a list of all non-local devices. It can be empty list.
+ */
+ void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos);
+ }
+
+ // An internal container used to keep track of device information during
+ // this action.
+ private static final class DeviceInfo {
+ private final int mLogicalAddress;
+
+ private int mPhysicalAddress = INVALID_PHYSICAL_ADDRESS;
+ private int mVendorId = HdmiCec.UNKNOWN_VENDOR_ID;
+ private String mDisplayName = "";
+ private int mDeviceType = HdmiCec.DEVICE_INACTIVE;
+
+ private DeviceInfo(int logicalAddress) {
+ mLogicalAddress = logicalAddress;
+ }
+
+ private HdmiCecDeviceInfo toHdmiCecDeviceInfo() {
+ return new HdmiCecDeviceInfo(mLogicalAddress, mPhysicalAddress, mDeviceType, mVendorId,
+ mDisplayName);
+ }
+ }
+
+ private final ArrayList<DeviceInfo> mDevices = new ArrayList<>();
+ private final DeviceDiscoveryCallback mCallback;
+ private int mProcessedDeviceCount = 0;
+
+ /**
+ * @Constructor
+ *
+ * @param service
+ * @param sourceAddress
+ */
+ DeviceDiscoveryAction(HdmiControlService service, int sourceAddress,
+ DeviceDiscoveryCallback callback) {
+ super(service, sourceAddress);
+ mCallback = Preconditions.checkNotNull(callback);
+ }
+
+ @Override
+ boolean start() {
+ mDevices.clear();
+ mState = STATE_WAITING_FOR_DEVICE_POLLING;
+
+ mService.pollDevices(new DevicePollingCallback() {
+ @Override
+ public void onPollingFinished(List<Integer> ackedAddress) {
+ if (ackedAddress.isEmpty()) {
+ Slog.i(TAG, "No device is detected.");
+ finish();
+ return;
+ }
+
+ Slog.i(TAG, "Device detected: " + ackedAddress);
+ allocateDevices(ackedAddress);
+ startPhysicalAddressStage();
+ }
+ }, DEVICE_POLLING_RETRY);
+ return true;
+ }
+
+ private void allocateDevices(List<Integer> addresses) {
+ for (Integer i : addresses) {
+ DeviceInfo info = new DeviceInfo(i);
+ mDevices.add(info);
+ }
+ }
+
+ private void startPhysicalAddressStage() {
+ mProcessedDeviceCount = 0;
+ mState = STATE_WAITING_FOR_PHYSICAL_ADDRESS;
+
+ checkAndProceedStage();
+ }
+
+ private boolean verifyValidLogicalAddress(int address) {
+ return address >= HdmiCec.ADDR_TV && address < HdmiCec.ADDR_UNREGISTERED;
+ }
+
+ private void queryPhysicalAddress(int address) {
+ if (!verifyValidLogicalAddress(address)) {
+ checkAndProceedStage();
+ return;
+ }
+
+ mActionTimer.clearTimerMessage();
+ sendCommand(HdmiCecMessageBuilder.buildGivePhysicalAddress(mSourceAddress, address));
+ addTimer(mState, TIMEOUT_MS);
+ }
+
+ private void startOsdNameStage() {
+ mProcessedDeviceCount = 0;
+ mState = STATE_WAITING_FOR_OSD_NAME;
+
+ checkAndProceedStage();
+ }
+
+ private void queryOsdName(int address) {
+ if (!verifyValidLogicalAddress(address)) {
+ checkAndProceedStage();
+ return;
+ }
+
+ mActionTimer.clearTimerMessage();
+ sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(mSourceAddress, address));
+ addTimer(mState, TIMEOUT_MS);
+ }
+
+ private void startVendorIdStage() {
+ mProcessedDeviceCount = 0;
+ mState = STATE_WAITING_FOR_VENDOR_ID;
+
+ checkAndProceedStage();
+ }
+
+ private void queryVendorId(int address) {
+ if (!verifyValidLogicalAddress(address)) {
+ checkAndProceedStage();
+ return;
+ }
+
+ mActionTimer.clearTimerMessage();
+ sendCommand(HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(mSourceAddress, address));
+ addTimer(mState, TIMEOUT_MS);
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ switch (mState) {
+ case STATE_WAITING_FOR_PHYSICAL_ADDRESS:
+ if (cmd.getOpcode() == HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS) {
+ handleReportPhysicalAddress(cmd);
+ return true;
+ }
+ return false;
+ case STATE_WAITING_FOR_OSD_NAME:
+ if (cmd.getOpcode() == HdmiCec.MESSAGE_SET_OSD_NAME) {
+ handleSetOsdName(cmd);
+ return true;
+ }
+ return false;
+ case STATE_WAITING_FOR_VENDOR_ID:
+ if (cmd.getOpcode() == HdmiCec.MESSAGE_DEVICE_VENDOR_ID) {
+ handleVendorId(cmd);
+ return true;
+ }
+ return false;
+ case STATE_WAITING_FOR_DEVICE_POLLING:
+ // Fall through.
+ default:
+ return false;
+ }
+ }
+
+ private void handleReportPhysicalAddress(HdmiCecMessage cmd) {
+ Preconditions.checkState(mProcessedDeviceCount < mDevices.size());
+
+ DeviceInfo current = mDevices.get(mProcessedDeviceCount);
+ if (current.mLogicalAddress != cmd.getSource()) {
+ Slog.w(TAG, "Unmatched address[expected:" + current.mLogicalAddress + ", actual:" +
+ cmd.getSource());
+ return;
+ }
+
+ byte params[] = cmd.getParams();
+ if (params.length == 3) {
+ current.mPhysicalAddress = ((params[0] & 0xFF) << 8) | (params[1] & 0xFF);
+ current.mDeviceType = params[2] & 0xFF;
+
+ increaseProcessedDeviceCount();
+ checkAndProceedStage();
+ } else {
+ // Physical address is a critical element in device info.
+ // If failed, remove device from device list and proceed to the next device.
+ removeDevice(mProcessedDeviceCount);
+ checkAndProceedStage();
+ }
+ }
+
+ private void handleSetOsdName(HdmiCecMessage cmd) {
+ Preconditions.checkState(mProcessedDeviceCount < mDevices.size());
+
+ DeviceInfo current = mDevices.get(mProcessedDeviceCount);
+ if (current.mLogicalAddress != cmd.getSource()) {
+ Slog.w(TAG, "Unmatched address[expected:" + current.mLogicalAddress + ", actual:" +
+ cmd.getSource());
+ return;
+ }
+
+ String displayName = null;
+ try {
+ displayName = new String(cmd.getParams(), "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ Slog.w(TAG, "Failed to decode display name: " + cmd.toString());
+ // If failed to get display name, use the default name of device.
+ displayName = HdmiCec.getDefaultDeviceName(current.mLogicalAddress);
+ }
+ current.mDisplayName = displayName;
+ increaseProcessedDeviceCount();
+ checkAndProceedStage();
+ }
+
+ private void handleVendorId(HdmiCecMessage cmd) {
+ Preconditions.checkState(mProcessedDeviceCount < mDevices.size());
+
+ DeviceInfo current = mDevices.get(mProcessedDeviceCount);
+ if (current.mLogicalAddress != cmd.getSource()) {
+ Slog.w(TAG, "Unmatched address[expected:" + current.mLogicalAddress + ", actual:" +
+ cmd.getSource());
+ return;
+ }
+
+ byte[] params = cmd.getParams();
+ if (params.length == 3) {
+ int vendorId = ((params[0] & 0xFF) << 16)
+ | ((params[1] & 0xFF) << 8)
+ | (params[2] & 0xFF);
+ current.mVendorId = vendorId;
+ } else {
+ Slog.w(TAG, "Invalid vendor id: " + cmd.toString());
+ }
+ increaseProcessedDeviceCount();
+ checkAndProceedStage();
+ }
+
+ private void increaseProcessedDeviceCount() {
+ mProcessedDeviceCount++;
+ }
+
+ private void removeDevice(int index) {
+ mDevices.remove(index);
+ }
+
+ private void wrapUpAndFinish() {
+ ArrayList<HdmiCecDeviceInfo> result = new ArrayList<>();
+ for (DeviceInfo info : mDevices) {
+ HdmiCecDeviceInfo cecDeviceInfo = info.toHdmiCecDeviceInfo();
+ result.add(cecDeviceInfo);
+ }
+ mCallback.onDeviceDiscoveryDone(result);
+ finish();
+ }
+
+ private void checkAndProceedStage() {
+ if (mDevices.isEmpty()) {
+ wrapUpAndFinish();
+ return;
+ }
+
+ // If finished current stage, move on to next stage.
+ if (mProcessedDeviceCount == mDevices.size()) {
+ mProcessedDeviceCount = 0;
+ switch (mState) {
+ case STATE_WAITING_FOR_PHYSICAL_ADDRESS:
+ startOsdNameStage();
+ return;
+ case STATE_WAITING_FOR_OSD_NAME:
+ startVendorIdStage();
+ return;
+ case STATE_WAITING_FOR_VENDOR_ID:
+ wrapUpAndFinish();
+ return;
+ default:
+ return;
+ }
+ } else {
+ int address = mDevices.get(mProcessedDeviceCount).mLogicalAddress;
+ switch (mState) {
+ case STATE_WAITING_FOR_PHYSICAL_ADDRESS:
+ queryPhysicalAddress(address);
+ return;
+ case STATE_WAITING_FOR_OSD_NAME:
+ queryOsdName(address);
+ return;
+ case STATE_WAITING_FOR_VENDOR_ID:
+ queryVendorId(address);
+ default:
+ return;
+ }
+ }
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState == STATE_NONE || mState != state) {
+ return;
+ }
+
+ removeDevice(mProcessedDeviceCount);
+ checkAndProceedStage();
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 3c18a59..e0a01f0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -21,6 +21,7 @@
import android.hardware.hdmi.HdmiCecMessage;
import android.os.Handler;
import android.os.Looper;
+import android.os.MessageQueue;
import android.util.Slog;
import android.util.SparseArray;
@@ -29,7 +30,6 @@
import libcore.util.EmptyArray;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -99,7 +99,7 @@
*/
static HdmiCecController create(HdmiControlService service) {
HdmiCecController controller = new HdmiCecController();
- long nativePtr = nativeInit(controller);
+ long nativePtr = nativeInit(controller, service.getServiceLooper().getQueue());
if (nativePtr == 0L) {
controller = null;
return null;
@@ -261,18 +261,23 @@
}
/**
+ * Clear all device info.
+ *
+ * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
+ */
+ void clearDeviceInfoList() {
+ assertRunOnServiceThread();
+ mDeviceInfos.clear();
+ }
+
+ /**
* Return a list of all {@link HdmiCecDeviceInfo}.
*
* <p>Declared as package-private. accessed by {@link HdmiControlService} only.
*/
List<HdmiCecDeviceInfo> getDeviceInfoList() {
assertRunOnServiceThread();
-
- List<HdmiCecDeviceInfo> deviceInfoList = new ArrayList<>(mDeviceInfos.size());
- for (int i = 0; i < mDeviceInfos.size(); ++i) {
- deviceInfoList.add(mDeviceInfos.valueAt(i));
- }
- return deviceInfoList;
+ return sparseArrayToList(mDeviceInfos);
}
/**
@@ -389,6 +394,24 @@
runDevicePolling(pollingCandidates, retryCount, callback);
}
+ /**
+ * Return a list of all {@link HdmiCecLocalDevice}s.
+ *
+ * <p>Declared as package-private. accessed by {@link HdmiControlService} only.
+ */
+ List<HdmiCecLocalDevice> getLocalDeviceList() {
+ assertRunOnServiceThread();
+ return sparseArrayToList(mLocalDevices);
+ }
+
+ private static <T> List<T> sparseArrayToList(SparseArray<T> array) {
+ ArrayList<T> list = new ArrayList<>();
+ for (int i = 0; i < array.size(); ++i) {
+ list.add(array.valueAt(i));
+ }
+ return list;
+ }
+
private boolean isAllocatedLocalDeviceAddress(int address) {
for (int i = 0; i < mLocalDevices.size(); ++i) {
if (mLocalDevices.valueAt(i).isAddressOf(address)) {
@@ -471,19 +494,19 @@
private void onReceiveCommand(HdmiCecMessage message) {
assertRunOnServiceThread();
- if (isAcceptableAddress(message.getDestination()) &&
- mService.handleCecCommand(message)) {
+ if (isAcceptableAddress(message.getDestination())
+ && mService.handleCecCommand(message)) {
return;
}
- // TODO: Use device's source address for broadcast message.
- int sourceAddress = message.getDestination() != HdmiCec.ADDR_BROADCAST ?
- message.getDestination() : 0;
- // Reply <Feature Abort> to initiator (source) for all requests.
- HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand
- (sourceAddress, message.getSource(), message.getOpcode(),
- HdmiCecMessageBuilder.ABORT_REFUSED);
- sendCommand(cecMessage, null);
+ if (message.getDestination() != HdmiCec.ADDR_BROADCAST) {
+ int sourceAddress = message.getDestination();
+ // Reply <Feature Abort> to initiator (source) for all requests.
+ HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ sourceAddress, message.getSource(), message.getOpcode(),
+ HdmiCecMessageBuilder.ABORT_REFUSED);
+ sendCommand(cecMessage, null);
+ }
}
void sendCommand(HdmiCecMessage cecMessage) {
@@ -517,17 +540,8 @@
* Called by native when incoming CEC message arrived.
*/
private void handleIncomingCecCommand(int srcAddress, int dstAddress, byte[] body) {
- byte opcode = body[0];
- byte params[] = Arrays.copyOfRange(body, 1, body.length);
- final HdmiCecMessage cecMessage = new HdmiCecMessage(srcAddress, dstAddress, opcode, params);
-
- // Delegate message to main handler so that it handles in main thread.
- runOnServiceThread(new Runnable() {
- @Override
- public void run() {
- onReceiveCommand(cecMessage);
- }
- });
+ assertRunOnServiceThread();
+ onReceiveCommand(HdmiCecMessageBuilder.of(srcAddress, dstAddress, body));
}
/**
@@ -539,7 +553,7 @@
mService.onHotplug(0, connected);
}
- private static native long nativeInit(HdmiCecController handler);
+ private static native long nativeInit(HdmiCecController handler, MessageQueue messageQueue);
private static native int nativeSendCecCommand(long controllerPtr, int srcAddress,
int dstAddress, byte[] body);
private static native int nativeAddLogicalAddress(long controllerPtr, int logicalAddress);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index be270b9..9a76734 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -20,6 +20,7 @@
import android.hardware.hdmi.HdmiCecMessage;
import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
/**
* A helper class to build {@link HdmiCecMessage} from various cec commands.
@@ -39,6 +40,20 @@
private HdmiCecMessageBuilder() {}
/**
+ * Build {@link HdmiCecMessage} from raw data.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @param body body of message. It includes opcode.
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage of(int src, int dest, byte[] body) {
+ byte opcode = body[0];
+ byte params[] = Arrays.copyOfRange(body, 1, body.length);
+ return new HdmiCecMessage(src, dest, opcode, params);
+ }
+
+ /**
* Build <Feature Abort> command. <Feature Abort> consists of
* 1 byte original opcode and 1 byte reason fields with basic fields.
*
@@ -58,6 +73,17 @@
}
/**
+ * Build <Give Physical Address> command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildGivePhysicalAddress(int src, int dest) {
+ return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS);
+ }
+
+ /**
* Build <Give Osd Name> command.
*
* @param src source address of command
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 475852f..072b97f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -33,6 +33,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.server.SystemService;
+import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
import java.util.ArrayList;
import java.util.Iterator;
@@ -289,8 +290,7 @@
// TODO: Add remaining system information query such as
// <Give Device Power Status> and <Request Active Source> handler.
default:
- Slog.w(TAG, "Unsupported cec command:" + message.toString());
- return false;
+ return dispatchMessageToAction(message);
}
}
@@ -393,6 +393,16 @@
}
}
+ private boolean dispatchMessageToAction(HdmiCecMessage message) {
+ for (FeatureAction action : mActions) {
+ if (action.processCommand(message)) {
+ return true;
+ }
+ }
+ Slog.w(TAG, "Unsupported cec command:" + message);
+ return false;
+ }
+
// Record class that monitors the event of the caller of being killed. Used to clean up
// the listener list and record list accordingly.
private final class HotplugEventListenerRecord implements IBinder.DeathRecipient {
@@ -411,6 +421,38 @@
}
}
+ void addCecDevice(HdmiCecDeviceInfo info) {
+ mCecController.addDeviceInfo(info);
+ }
+
+ // Launch device discovery sequence.
+ // It starts with clearing the existing device info list.
+ // Note that it assumes that logical address of all local devices is already allocated.
+ void launchDeviceDiscovery() {
+ // At first, clear all existing device infos.
+ mCecController.clearDeviceInfoList();
+
+ // TODO: check whether TV is one of local devices.
+ DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, HdmiCec.ADDR_TV,
+ new DeviceDiscoveryCallback() {
+ @Override
+ public void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos) {
+ for (HdmiCecDeviceInfo info : deviceInfos) {
+ mCecController.addDeviceInfo(info);
+ }
+
+ // Add device info of all local devices.
+ for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
+ mCecController.addDeviceInfo(device.getDeviceInfo());
+ }
+
+ // TODO: start hot-plug detection sequence here.
+ // addAndStartAction(new HotplugDetectionAction());
+ }
+ });
+ addAndStartAction(action);
+ }
+
private void enforceAccessPermission() {
getContext().enforceCallingOrSelfPermission(PERMISSION, TAG);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6d75ee5..13cc98c 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11778,8 +11778,8 @@
}
}
if (removed.size() > 0) {
- for (int j=0; j<removed.size(); j++) {
- PreferredActivity pa = removed.get(i);
+ for (int r=0; r<removed.size(); r++) {
+ PreferredActivity pa = removed.get(r);
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
pir.removeFilter(pa);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index bb92611..69aeae6 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1944,7 +1944,8 @@
// TODO: check whether this is okay! as it is very
// similar to how preferred-activities are treated
readPersistentPreferredActivitiesLPw(parser, 0);
- } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)) {
+ } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
+ || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
// TODO: check whether this is okay! as it is very
// similar to how preferred-activities are treated
readCrossProfileIntentFiltersLPw(parser, 0);
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index e2d2ac6..4f8b9d7 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -24,9 +24,7 @@
import android.os.Debug;
import android.os.Handler;
import android.os.IRemoteCallback;
-import android.os.SystemProperties;
import android.util.Slog;
-import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -299,7 +297,7 @@
return null;
}
- Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
+ Animation loadAnimationAttr(WindowManager.LayoutParams lp, int animAttr) {
int anim = 0;
Context context = mContext;
if (animAttr >= 0) {
@@ -315,7 +313,19 @@
return null;
}
- private Animation loadAnimation(String packageName, int resId) {
+ Animation loadAnimationRes(WindowManager.LayoutParams lp, int resId) {
+ Context context = mContext;
+ if (resId >= 0) {
+ AttributeCache.Entry ent = getCachedAnimations(lp);
+ if (ent != null) {
+ context = ent.context;
+ }
+ return AnimationUtils.loadAnimation(context, resId);
+ }
+ return null;
+ }
+
+ private Animation loadAnimationRes(String packageName, int resId) {
int anim = 0;
Context context = mContext;
if (resId >= 0) {
@@ -695,11 +705,31 @@
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
- int appWidth, int appHeight, int orientation,
- Rect containingFrame, Rect contentInsets, boolean isFullScreen) {
+ int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
+ boolean isFullScreen, boolean isVoiceInteraction) {
Animation a;
- if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
- a = loadAnimation(mNextAppTransitionPackage, enter ?
+ if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
+ || transit == TRANSIT_TASK_OPEN
+ || transit == TRANSIT_TASK_TO_FRONT)) {
+ a = loadAnimationRes(lp, enter
+ ? com.android.internal.R.anim.voice_activity_open_enter
+ : com.android.internal.R.anim.voice_activity_open_exit);
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+ "applyAnimation voice:"
+ + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
+ + " Callers=" + Debug.getCallers(3));
+ } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
+ || transit == TRANSIT_TASK_CLOSE
+ || transit == TRANSIT_TASK_TO_BACK)) {
+ a = loadAnimationRes(lp, enter
+ ? com.android.internal.R.anim.voice_activity_close_enter
+ : com.android.internal.R.anim.voice_activity_close_exit);
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+ "applyAnimation voice:"
+ + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
+ + " Callers=" + Debug.getCallers(3));
+ } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
+ a = loadAnimationRes(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
@@ -782,7 +812,7 @@
: WindowAnimation_wallpaperIntraCloseExitAnimation;
break;
}
- a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
+ a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null;
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
+ " anim=" + a
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index ca4ad8a..12c15e2 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -50,6 +50,8 @@
final WindowAnimator mAnimator;
+ final boolean voiceInteraction;
+
int groupId = -1;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -107,11 +109,13 @@
boolean mDeferRemoval;
- AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
+ AppWindowToken(WindowManagerService _service, IApplicationToken _token,
+ boolean _voiceInteraction) {
super(_service, _token.asBinder(),
WindowManager.LayoutParams.TYPE_APPLICATION, true);
appWindowToken = this;
appToken = _token;
+ voiceInteraction = _voiceInteraction;
mInputApplicationHandle = new InputApplicationHandle(this);
mAnimator = service.mAnimator;
mAppAnimator = new AppWindowAnimator(this);
@@ -249,7 +253,7 @@
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
if (appToken != null) {
- pw.print(prefix); pw.println("app=true");
+ pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
}
if (allAppWindows.size() > 0) {
pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 266527d..6fdd535 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -36,6 +36,7 @@
import android.view.Display;
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
+import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import com.android.server.wm.WindowManagerService.LayoutFields;
@@ -50,6 +51,9 @@
public class WindowAnimator {
private static final String TAG = "WindowAnimator";
+ /** How long to give statusbar to clear the private keyguard flag when animating out */
+ private static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
+
final WindowManagerService mService;
final Context mContext;
final WindowManagerPolicy mPolicy;
@@ -82,6 +86,8 @@
boolean mInitialized = false;
+ boolean mKeyguardGoingAway;
+
// forceHiding states.
static final int KEYGUARD_NOT_SHOWN = 0;
static final int KEYGUARD_ANIMATING_IN = 1;
@@ -213,6 +219,29 @@
final WindowList windows = mService.getWindowListLocked(displayId);
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
+
+ if (mKeyguardGoingAway) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState win = windows.get(i);
+ if (!mPolicy.isKeyguardHostWindow(win.mAttrs)) {
+ continue;
+ }
+ final WindowStateAnimator winAnimator = win.mWinAnimator;
+ if (mPolicy.doesForceHide(win.mAttrs)) {
+ if (!winAnimator.mAnimating) {
+ // Create a new animation to delay until keyguard is gone on its own.
+ winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
+ winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
+ winAnimator.mAnimationIsEntrance = false;
+ }
+ } else {
+ mKeyguardGoingAway = false;
+ winAnimator.clearAnimation();
+ }
+ break;
+ }
+ }
+
mForceHiding = KEYGUARD_NOT_SHOWN;
for (int i = windows.size() - 1; i >= 0; i--) {
@@ -239,7 +268,7 @@
}
}
- if (mPolicy.doesForceHide(win, win.mAttrs)) {
+ if (mPolicy.doesForceHide(win.mAttrs)) {
if (!wasAnimating && nowAnimating) {
if (WindowManagerService.DEBUG_ANIM ||
WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
@@ -252,6 +281,11 @@
getPendingLayoutChanges(displayId));
}
mService.mFocusMayChange = true;
+ } else if (mKeyguardGoingAway && !nowAnimating) {
+ // Timeout!!
+ Slog.e(TAG, "Timeout waiting for animation to startup");
+ mPolicy.startKeyguardExitAnimation(0);
+ mKeyguardGoingAway = false;
}
if (win.isReadyForDisplay()) {
if (nowAnimating) {
@@ -265,7 +299,7 @@
}
}
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
- "Force hide " + mForceHiding
+ "Force hide " + forceHidingToString()
+ " hasSurface=" + win.mHasSurface
+ " policyVis=" + win.mPolicyVisibility
+ " destroying=" + win.mDestroying
@@ -349,12 +383,18 @@
// If we have windows that are being show due to them no longer
// being force-hidden, apply the appropriate animation to them.
if (unForceHiding != null) {
+ boolean startKeyguardExit = true;
for (int i=unForceHiding.size()-1; i>=0; i--) {
Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding);
if (a != null) {
final WindowStateAnimator winAnimator = unForceHiding.get(i);
winAnimator.setAnimation(a);
winAnimator.mAnimationIsEntrance = true;
+ if (startKeyguardExit) {
+ // Do one time only.
+ mPolicy.startKeyguardExitAnimation(a.getStartOffset());
+ startKeyguardExit = false;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c23d1ea..05502cf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2215,6 +2215,11 @@
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
+ if (type == TYPE_VOICE_INTERACTION) {
+ Slog.w(TAG, "Attempted to add voice interaction window with unknown token "
+ + attrs.token + ". Aborting.");
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ }
if (type == TYPE_WALLPAPER) {
Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
+ attrs.token + ". Aborting.");
@@ -2250,6 +2255,12 @@
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
+ } else if (type == TYPE_VOICE_INTERACTION) {
+ if (token.windowType != TYPE_VOICE_INTERACTION) {
+ Slog.w(TAG, "Attempted to add voice interaction window with bad token "
+ + attrs.token + ". Aborting.");
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ }
} else if (type == TYPE_WALLPAPER) {
if (token.windowType != TYPE_WALLPAPER) {
Slog.w(TAG, "Attempted to add wallpaper window with bad token "
@@ -3173,7 +3184,7 @@
}
private boolean applyAnimationLocked(AppWindowToken atoken,
- WindowManager.LayoutParams lp, int transit, boolean enter) {
+ WindowManager.LayoutParams lp, int transit, boolean enter, boolean isVoiceInteraction) {
// Only apply an animation if the display isn't frozen. If it is
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
@@ -3203,7 +3214,8 @@
}
Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height,
- mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen);
+ mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen,
+ isVoiceInteraction);
if (a != null) {
if (DEBUG_ANIM) {
RuntimeException e = null;
@@ -3423,7 +3435,7 @@
@Override
public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
- int configChanges) {
+ int configChanges, boolean voiceInteraction) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3449,7 +3461,7 @@
Slog.w(TAG, "Attempted to add existing app token: " + token);
return;
}
- atoken = new AppWindowToken(this, token);
+ atoken = new AppWindowToken(this, token, voiceInteraction);
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
atoken.groupId = taskId;
atoken.appFullscreen = fullscreen;
@@ -4201,7 +4213,7 @@
}
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
- boolean visible, int transit, boolean performLayout) {
+ boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
boolean delayed = false;
if (wtoken.clientHidden == visible) {
@@ -4222,7 +4234,7 @@
if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
wtoken.mAppAnimator.animation = null;
}
- if (applyAnimationLocked(wtoken, lp, transit, visible)) {
+ if (applyAnimationLocked(wtoken, lp, transit, visible, isVoiceInteraction)) {
delayed = runningAppAnimation = true;
}
WindowState window = wtoken.findMainWindow();
@@ -4400,7 +4412,7 @@
final long origId = Binder.clearCallingIdentity();
setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
- true);
+ true, wtoken.voiceInteraction);
wtoken.updateReportedVisibilityLocked();
Binder.restoreCallingIdentity(origId);
}
@@ -4547,7 +4559,7 @@
if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
delayed = setTokenVisibilityLocked(wtoken, null, false,
- AppTransition.TRANSIT_UNSET, true);
+ AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction);
wtoken.inPendingTransaction = false;
mOpeningApps.remove(wtoken);
wtoken.waitingToShow = false;
@@ -5127,6 +5139,18 @@
}
@Override
+ public void keyguardGoingAway() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DISABLE_KEYGUARD permission");
+ }
+ synchronized (mWindowMap) {
+ mAnimator.mKeyguardGoingAway = true;
+ requestTraversalLocked();
+ }
+ }
+
+ @Override
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
final int numDisplays = mDisplayContents.size();
@@ -5802,7 +5826,9 @@
// whether the screenshot should use the identity transformation matrix
// (e.g., enable it when taking a screenshot for recents, since we might be in
// the middle of the rotation animation, but don't want a rotated recent image).
- rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false);
+ // TODO: Replace 'new Rect()' with the portion of the screen to capture for the
+ // screenshot.
+ rawss = SurfaceControl.screenshot(new Rect(), dw, dh, minLayer, maxLayer, false);
}
} while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
@@ -7149,9 +7175,7 @@
public static final int TAP_OUTSIDE_STACK = 31;
public static final int NOTIFY_ACTIVITY_DRAWN = 32;
- public static final int REMOVE_STARTING_TIMEOUT = 33;
-
- public static final int SHOW_DISPLAY_MASK = 34;
+ public static final int SHOW_DISPLAY_MASK = 33;
@Override
public void handleMessage(Message msg) {
@@ -8528,6 +8552,7 @@
LayoutParams animLp = null;
int bestAnimLayer = -1;
boolean fullscreenAnim = false;
+ boolean voiceInteraction = false;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New wallpaper target=" + mWallpaperTarget
@@ -8572,6 +8597,8 @@
}
}
+ voiceInteraction |= wtoken.voiceInteraction;
+
if (wtoken.appFullscreen) {
WindowState ws = wtoken.findMainWindow();
if (ws != null) {
@@ -8644,7 +8671,7 @@
appAnimator.clearThumbnail();
wtoken.inPendingTransaction = false;
appAnimator.animation = null;
- setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
+ setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
@@ -8676,7 +8703,7 @@
wtoken.mAppAnimator.clearThumbnail();
wtoken.inPendingTransaction = false;
wtoken.mAppAnimator.animation = null;
- setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
+ setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToHide = false;
// Force the allDrawn flag, because we want to start
@@ -10266,10 +10293,6 @@
mPolicy.lockNow(options);
}
- public void showRecentApps() {
- mPolicy.showRecentApps();
- }
-
@Override
public boolean isSafeModeEnabled() {
return mSafeMode;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c88382c..4a80e3e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -714,6 +714,11 @@
return mAppToken != null ? mAppToken.appToken : null;
}
+ @Override
+ public boolean isVoiceInteraction() {
+ return mAppToken != null ? mAppToken.voiceInteraction : false;
+ }
+
boolean setInsetsChanged() {
mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets);
mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1e79dcb..e257ebc 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1658,7 +1658,7 @@
break;
}
if (attr >= 0) {
- a = mService.mAppTransition.loadAnimation(mWin.mAttrs, attr);
+ a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
}
}
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
index 27c8876..c6de676 100644
--- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
+++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
@@ -21,12 +21,15 @@
#include "JNIHelp.h"
#include "ScopedPrimitiveArray.h"
-#include <string>
+#include <cstring>
+#include <android_os_MessageQueue.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include <hardware/hdmi_cec.h>
#include <sys/param.h>
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
namespace android {
@@ -37,7 +40,8 @@
class HdmiCecController {
public:
- HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj);
+ HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj,
+ const sp<Looper>& looper);
void init();
@@ -54,51 +58,137 @@
// Get vendor id used for vendor command.
uint32_t getVendorId();
-private:
- // Propagate the message up to Java layer.
- void propagateCecCommand(const cec_message_t& message);
- void propagateHotplugEvent(const hotplug_event_t& event);
+ jobject getCallbacksObj() const {
+ return mCallbacksObj;
+ }
+private:
static void onReceived(const hdmi_event_t* event, void* arg);
- static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
hdmi_cec_device_t* mDevice;
jobject mCallbacksObj;
+ sp<Looper> mLooper;
};
-HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj) :
+// RefBase wrapper for hdmi_event_t. As hdmi_event_t coming from HAL
+// may keep its own lifetime, we need to copy it in order to delegate
+// it to service thread.
+class CecEventWrapper : public LightRefBase<CecEventWrapper> {
+public:
+ CecEventWrapper(const hdmi_event_t& event) {
+ // Copy message.
+ switch (event.type) {
+ case HDMI_EVENT_CEC_MESSAGE:
+ mEvent.cec.initiator = event.cec.initiator;
+ mEvent.cec.destination = event.cec.destination;
+ mEvent.cec.length = event.cec.length;
+ std::memcpy(mEvent.cec.body, event.cec.body, event.cec.length);
+ break;
+ case HDMI_EVENT_HOT_PLUG:
+ mEvent.hotplug.connected = event.hotplug.connected;
+ mEvent.hotplug.port = event.hotplug.port;
+ break;
+ case HDMI_EVENT_TX_STATUS:
+ mEvent.tx_status.status = event.tx_status.status;
+ mEvent.tx_status.opcode = event.tx_status.opcode;
+ break;
+ default:
+ // TODO: add more type whenever new type is introduced.
+ break;
+ }
+ }
+
+ const cec_message_t& cec() const {
+ return mEvent.cec;
+ }
+
+ const hotplug_event_t& hotplug() const {
+ return mEvent.hotplug;
+ }
+
+ virtual ~CecEventWrapper() {}
+
+private:
+ hdmi_event_t mEvent;
+};
+
+// Handler class to delegate incoming message to service thread.
+class HdmiCecEventHandler : public MessageHandler {
+public:
+ HdmiCecEventHandler(HdmiCecController* controller, const sp<CecEventWrapper>& event)
+ : mController(controller),
+ mEventWrapper(event) {
+ }
+
+ virtual ~HdmiCecEventHandler() {}
+
+ void handleMessage(const Message& message) {
+ switch (message.what) {
+ case HDMI_EVENT_CEC_MESSAGE:
+ propagateCecCommand(mEventWrapper->cec());
+ break;
+ case HDMI_EVENT_HOT_PLUG:
+ propagateHotplugEvent(mEventWrapper->hotplug());
+ break;
+ case HDMI_EVENT_TX_STATUS:
+ // TODO: propagate this to controller.
+ default:
+ // TODO: add more type whenever new type is introduced.
+ break;
+ }
+ }
+
+private:
+ // Propagate the message up to Java layer.
+ void propagateCecCommand(const cec_message_t& message) {
+ jint srcAddr = message.initiator;
+ jint dstAddr = message.destination;
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jbyteArray body = env->NewByteArray(message.length);
+ const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body);
+ env->SetByteArrayRegion(body, 0, message.length, bodyPtr);
+
+ env->CallVoidMethod(mController->getCallbacksObj(),
+ gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr,
+ dstAddr, body);
+ env->DeleteLocalRef(body);
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ }
+
+ void propagateHotplugEvent(const hotplug_event_t& event) {
+ // Note that this method should be called in service thread.
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mController->getCallbacksObj(),
+ gHdmiCecControllerClassInfo.handleHotplug, event.connected);
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ }
+
+ // static
+ static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
+ if (env->ExceptionCheck()) {
+ ALOGE("An exception was thrown by callback '%s'.", methodName);
+ LOGE_EX(env);
+ env->ExceptionClear();
+ }
+ }
+
+ HdmiCecController* mController;
+ sp<CecEventWrapper> mEventWrapper;
+};
+
+HdmiCecController::HdmiCecController(hdmi_cec_device_t* device,
+ jobject callbacksObj, const sp<Looper>& looper) :
mDevice(device),
- mCallbacksObj(callbacksObj) {
+ mCallbacksObj(callbacksObj),
+ mLooper(looper) {
}
void HdmiCecController::init() {
mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this);
}
-void HdmiCecController::propagateCecCommand(const cec_message_t& message) {
- jint srcAddr = message.initiator;
- jint dstAddr = message.destination;
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jbyteArray body = env->NewByteArray(message.length);
- const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body);
- env->SetByteArrayRegion(body, 0, message.length, bodyPtr);
-
- env->CallVoidMethod(mCallbacksObj,
- gHdmiCecControllerClassInfo.handleIncomingCecCommand,
- srcAddr, dstAddr, body);
- env->DeleteLocalRef(body);
-
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-void HdmiCecController::propagateHotplugEvent(const hotplug_event_t& event) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj,
- gHdmiCecControllerClassInfo.handleHotplug, event.connected);
-
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
int HdmiCecController::sendMessage(const cec_message_t& message) {
// TODO: propagate send_message's return value.
return mDevice->send_message(mDevice, &message);
@@ -132,15 +222,6 @@
return vendorId;
}
-// static
-void HdmiCecController::checkAndClearExceptionFromCallback(JNIEnv* env,
- const char* methodName) {
- if (env->ExceptionCheck()) {
- ALOGE("An exception was thrown by callback '%s'.", methodName);
- LOGE_EX(env);
- env->ExceptionClear();
- }
-}
// static
void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) {
@@ -149,17 +230,9 @@
return;
}
- switch (event->type) {
- case HDMI_EVENT_CEC_MESSAGE:
- controller->propagateCecCommand(event->cec);
- break;
- case HDMI_EVENT_HOT_PLUG:
- controller->propagateHotplugEvent(event->hotplug);
- break;
- default:
- ALOGE("Unsupported event type: %d", event->type);
- break;
- }
+ sp<CecEventWrapper> spEvent(new CecEventWrapper(*event));
+ sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(controller, spEvent));
+ controller->mLooper->sendMessage(handler, event->type);
}
//------------------------------------------------------------------------------
@@ -167,31 +240,38 @@
var = env->GetMethodID(clazz, methodName, methodDescriptor); \
LOG_FATAL_IF(! var, "Unable to find method " methodName);
-static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj) {
+// TODO: replace above code with following once
+// replace old HdmiCecService with HdmiControlService
+#undef HDMI_CEC_HARDWARE_MODULE_ID
+#define HDMI_CEC_HARDWARE_MODULE_ID "hdmi_cec_module"
+#undef HDMI_CEC_HARDWARE_INTERFACE
+#define HDMI_CEC_HARDWARE_INTERFACE "hdmi_cec_module_hw_if"
+
+static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj,
+ jobject messageQueueObj) {
int err;
- // If use same hardware module id between HdmiCecService and
- // HdmiControlSservice it may conflict and cause abnormal state of HAL.
- // TODO: use HDMI_CEC_HARDWARE_MODULE_ID of hdmi_cec.h for module id
- // once migration to HdmiControlService is done.
hw_module_t* module;
- err = hw_get_module("hdmi_cec_module",
+ err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID,
const_cast<const hw_module_t **>(&module));
if (err != 0) {
ALOGE("Error acquiring hardware module: %d", err);
return 0;
}
+
hw_device_t* device;
- // TODO: use HDMI_CEC_HARDWARE_INTERFACE of hdmi_cec.h for interface name
- // once migration to HdmiControlService is done.
- err = module->methods->open(module, "hdmi_cec_module_hw_if", &device);
+ err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device);
if (err != 0) {
ALOGE("Error opening hardware module: %d", err);
return 0;
}
+ sp<MessageQueue> messageQueue =
+ android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+
HdmiCecController* controller = new HdmiCecController(
reinterpret_cast<hdmi_cec_device*>(device),
- env->NewGlobalRef(callbacksObj));
+ env->NewGlobalRef(callbacksObj),
+ messageQueue->getLooper());
controller->init();
GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz,
@@ -255,8 +335,9 @@
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
- { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecController;)J",
- (void *) nativeInit },
+ { "nativeInit",
+ "(Lcom/android/server/hdmi/HdmiCecController;Landroid/os/MessageQueue;)J",
+ (void *) nativeInit },
{ "nativeSendCecCommand", "(JII[B)I", (void *) nativeSendCecCommand },
{ "nativeAddLogicalAddress", "(JI)I", (void *) nativeAddLogicalAddress },
{ "nativeClearLogicalAddress", "(J)V", (void *) nativeClearLogicalAddress },
@@ -268,7 +349,8 @@
#define CLASS_PATH "com/android/server/hdmi/HdmiCecController"
int register_android_server_hdmi_HdmiCecController(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods));
+ int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods,
+ NELEM(sMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
return 0;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index bc34e0ef..0f24ff6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -186,7 +186,7 @@
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
- SystemProperties.set("persist.sys.dalvik.vm.lib.1", VMRuntime.getRuntime().vmLibrary());
+ SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Enable the sampling profiler.
if (SamplingProfilerIntegration.isEnabled()) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 9b6daad..62ff121 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -113,7 +113,7 @@
if (mBound) {
try {
mIWindowManager.addWindowToken(mToken,
- WindowManager.LayoutParams.TYPE_INPUT_METHOD);
+ WindowManager.LayoutParams.TYPE_VOICE_INTERACTION);
} catch (RemoteException e) {
Slog.w(TAG, "Failed adding window token", e);
}
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 59bdf64..874279b 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -98,6 +98,7 @@
public static final int CMD_IS_PROVISIONING_APN = BASE + 38;
public static final int EVENT_PROVISIONING_APN_ALARM = BASE + 39;
public static final int CMD_NET_STAT_POLL = BASE + 40;
+ public static final int EVENT_DATA_RAT_CHANGED = BASE + 41;
/***** Constants *****/
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index db802c5..6b70631 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -902,5 +902,14 @@
<category android:name="com.android.test.hwui.TEST" />
</intent-filter>
</activity>
+
+ <activity
+ android:name=".ZOrderingActivity"
+ android:label="Reordering/Z Ordering">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.hwui.TEST" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/HwAccelerationTest/res/layout/z_ordering.xml b/tests/HwAccelerationTest/res/layout/z_ordering.xml
new file mode 100644
index 0000000..970c5fd
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/z_ordering.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:id="@+id/parent">
+ <RelativeLayout
+ android:layout_width="400dp"
+ android:layout_height="200dp"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView style="@style/TopLeftReorderTextView"/>
+ <TextView style="@style/BottomLeftReorderTextView"/>
+ <TextView style="@style/TopRightReorderTextView"/>
+ <TextView style="@style/BottomRightReorderTextView"/>
+ </RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/values/styles.xml b/tests/HwAccelerationTest/res/values/styles.xml
index cde5d20..108709b 100644
--- a/tests/HwAccelerationTest/res/values/styles.xml
+++ b/tests/HwAccelerationTest/res/values/styles.xml
@@ -1,34 +1,37 @@
<resources>
<style name="ReorderTextView" parent="@android:style/TextAppearance.Medium">
- <item name="android:layout_width">match_parent</item>
+ <item name="android:background">@drawable/appwidget_background</item>
+ <item name="android:layout_width">300dp</item>
<item name="android:layout_height">100dp</item>
<item name="android:gravity">center</item>
</style>
<style name="LeftReorderTextView" parent="@style/ReorderTextView">
- <item name="android:translationX">20dp</item>
+ <item name="android:translationX">50dp</item>
+ <item name="android:layout_alignParentLeft">true</item>
</style>
<style name="RightReorderTextView" parent="@style/ReorderTextView">
- <item name="android:translationX">-20dp</item>
+ <item name="android:translationX">-50dp</item>
+ <item name="android:layout_alignParentRight">true</item>
</style>
<style name="TopLeftReorderTextView" parent="@style/LeftReorderTextView">
- <item name="android:background">#666</item>
- <item name="android:text">100</item>
- <item name="android:translationZ">100dp</item>
- </style>
- <style name="BottomLeftReorderTextView" parent="@style/LeftReorderTextView">
- <item name="android:background">#bbb</item>
- <item name="android:text">300</item>
- <item name="android:translationZ">300dp</item>
- </style>
- <style name="TopRightReorderTextView" parent="@style/RightReorderTextView">
- <item name="android:background">#888</item>
<item name="android:text">200</item>
<item name="android:translationZ">200dp</item>
+ <item name="android:layout_alignParentTop">true</item>
+ </style>
+ <style name="BottomLeftReorderTextView" parent="@style/LeftReorderTextView">
+ <item name="android:text">300</item>
+ <item name="android:translationZ">300dp</item>
+ <item name="android:layout_alignParentBottom">true</item>
+ </style>
+ <style name="TopRightReorderTextView" parent="@style/RightReorderTextView">
+ <item name="android:text">100</item>
+ <item name="android:translationZ">100dp</item>
+ <item name="android:layout_alignParentTop">true</item>
</style>
<style name="BottomRightReorderTextView" parent="@style/RightReorderTextView">
- <item name="android:background">#ccc</item>
<item name="android:text">400</item>
<item name="android:translationZ">400dp</item>
+ <item name="android:layout_alignParentBottom">true</item>
</style>
</resources>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java
new file mode 100644
index 0000000..45e77ed
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java
@@ -0,0 +1,28 @@
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class ZOrderingActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.z_ordering);
+
+ ViewGroup grandParent = (ViewGroup) findViewById(R.id.parent);
+ if (grandParent == null) throw new IllegalStateException();
+ View.OnClickListener l = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {}
+ };
+ for (int i = 0; i < grandParent.getChildCount(); i++) {
+ ViewGroup parent = (ViewGroup) grandParent.getChildAt(i);
+ for (int j = 0; j < parent.getChildCount(); j++) {
+ parent.getChildAt(j).setOnClickListener(l);
+ }
+ }
+ }
+}
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
index d0f2a2d..66a9452 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
@@ -13,8 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:versionCode="1" >
+<vector xmlns:android="http://schemas.android.com/apk/res/android">
<size
android:height="48dp"
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml
index db5697c..40f23f0 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml
@@ -15,21 +15,22 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="64dp"
+ android:height="64dp"/>
<viewport android:viewportWidth="320"
android:viewportHeight="320"/>
-
- <path
+ <group
+ android:rotation="180"
+ android:pivotX="70"
+ android:pivotY="120">
+ <path
android:name="house"
android:pathData="M 130,225 L 130,115 L 130,115 L 70,15 L 10,115 L 10,115 L 10,225 z"
android:fill="#ff440000"
android:stroke="#FF00FF00"
android:strokeWidth="10"
- android:rotation="180"
- android:pivotX="70"
- android:pivotY="120"
android:trimPathStart=".1"
android:trimPathEnd=".9"/>
+ </group>
</vector>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
index 8e8250d9..5b4c4ab 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
@@ -1,4 +1,5 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+ 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.
@@ -15,57 +16,62 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:height="64dp"
+ android:width="64dp" />
<viewport
- android:viewportWidth="7.30625"
- android:viewportHeight="12.25"/>
+ android:viewportHeight="12.25"
+ android:viewportWidth="7.30625" />
- <path
+ <group
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ android:rotation="-30" >
+ <path
android:name="clip1"
- android:pathData="
- M 0, 0
- l 7.3, 0
- l 0, 0
- l -7.3, 0
- z"
android:clipToPath="true"
- android:rotation="-30"
- android:pivotX="3.65"
- android:pivotY="6.125"
- />
- <path
+ android:pathData="
+ M 0, 6.125
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z" />
+ </group>
+ <group>
+ <path
android:name="one"
+ android:fill="#ff88ff"
android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
- l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
- l -5.046875,0.0 0.0,-1.0Z"
- android:fill="#ff88ff"
- />
- <path
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z" />
+ </group>
+ <group
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ android:rotation="-30" >
+ <path
android:name="clip2"
- android:pathData="
- M 0, 0
- l 7.3, 0
- l 0, 12.25
- l -7.3, 0
- z"
android:clipToPath="true"
- android:rotation="-30"
- android:pivotX="3.65"
- android:pivotY="6.125"
- />
- <path
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 6.125
+ l -7.3, 0
+ z" />
+ </group>
+ <group>
+ <path
android:name="two"
- android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
- q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
- q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
- q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
- q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
- q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
- q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
- q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
- q -0.78125024,0.8125 -2.2187502,2.265625Z"
android:fill="#ff88ff"
- />
-</vector>
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
index 2e379d6..c93c85f 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
@@ -23,14 +23,14 @@
android:viewportHeight="200"
android:viewportWidth="200" />
- <group>
+ <group
+ android:pivotX="100"
+ android:pivotY="100"
+ android:rotation="90">
<path
android:name="house"
android:fill="#ffffffff"
- android:pathData="M 100,20 l 0,0 0,140 -80,0 z M 100,20 l 0,0 80,140 -80,0 z"
- android:pivotX="100"
- android:pivotY="100"
- android:rotation="90" />
+ android:pathData="M 100,20 l 0,0 0,140 -80,0 z M 100,20 l 0,0 80,140 -80,0 z"/>
</group>
</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml
index 2b6c5d3..3422bbf 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml
@@ -28,7 +28,6 @@
android:name="battery"
android:fill="#3388ff"
android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
- android:rotation="0"
android:stroke="#ff8833"
android:strokeWidth="1" />
<path
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml
index 681eb4f..d0edd8c 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml
@@ -35,10 +35,7 @@
<path
android:name="v"
android:fill="#FF00FF00"
- android:pathData="M300,70 l 0,-70 70,70 -70,70z"
- android:pivotX="300"
- android:pivotY="300"
- android:rotation="0" />
+ android:pathData="M300,70 l 0,-70 70,70 -70,70z"/>
</group>
</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml
index ef1b8e4..8c946df 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml
@@ -34,9 +34,6 @@
android:name="half"
android:fill="#FFFF0000"
android:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
- android:pivotX="300"
- android:pivotY="200"
- android:rotation="0"
android:stroke="#FF0000FF"
android:strokeWidth="5" />
</group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml
index 77bf723..1abe1e1 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml
@@ -23,7 +23,10 @@
android:viewportHeight="500"
android:viewportWidth="800" />
- <group>
+ <group
+ android:pivotX="90"
+ android:pivotY="100"
+ android:rotation="20">
<path
android:name="pie2"
android:pathData="M200,350 l 50,-25
@@ -31,9 +34,6 @@
a25,25 -30 0,1 100,-50 l 50,-25
a25,37 -30 0,1 100,-50 l 50,-25
a25,50 -30 0,1 100,-50 l 50,-25"
- android:pivotX="90"
- android:pivotY="100"
- android:rotation="20"
android:stroke="#FF00FF00"
android:strokeWidth="10" />
</group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml
index df5838c..b08e157 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml
@@ -23,14 +23,14 @@
android:viewportHeight="400"
android:viewportWidth="500" />
- <group>
+ <group
+ android:pivotX="250"
+ android:pivotY="200"
+ android:rotation="180">
<path
android:name="house"
android:fill="#ff440000"
android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
- android:pivotX="250"
- android:pivotY="200"
- android:rotation="180"
android:stroke="#FFFF0000"
android:strokeWidth="10" />
</group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml
index 0bdcda5..ae85d9b 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml
@@ -25,11 +25,25 @@
<group>
<path
- android:name="house"
+ android:name="background1"
+ android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z"
+ android:fill="#FF000000"/>
+ <path
+ android:name="background2"
+ android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z"
+ android:fill="#FF000000"/>
+ </group>
+ <group
+ android:pivotX="100"
+ android:pivotY="100"
+ android:rotation="90"
+ android:scaleX="0.75"
+ android:scaleY="0.5"
+ android:translateX="0.0"
+ android:translateY="100.0">
+ <path
+ android:name="twoLines"
android:pathData="M 100,10 v 90 M 10,100 h 90"
- android:pivotX="100"
- android:pivotY="100"
- android:rotation="360"
android:stroke="#FF00FF00"
android:strokeWidth="10" />
</group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml
index 4453ae4..8e98d02 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml
@@ -26,10 +26,7 @@
android:name="house"
android:pathData="M200,300 Q400,50 600,300 T1000,300"
android:stroke="#FFFF0000"
- android:strokeWidth="10"
- android:rotation="360"
- android:pivotX="600"
- android:pivotY="300"/>
+ android:strokeWidth="10"/>
</group>
</vector>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml
index dfae9ac..6d74ebd 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml
@@ -27,9 +27,6 @@
<path
android:name="house"
android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
- android:pivotX="250"
- android:pivotY="200"
- android:rotation="360"
android:stroke="#FFFFFF00"
android:strokeWidth="10" />
</group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable21.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable21.xml
new file mode 100644
index 0000000..e0013e7
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable21.xml
@@ -0,0 +1,51 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="200"
+ android:viewportWidth="200" />
+
+ <group>
+ <path
+ android:name="background1"
+ android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z"
+ android:fill="#FF000000"/>
+ <path
+ android:name="background2"
+ android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z"
+ android:fill="#FF000000"/>
+ </group>
+ <group
+ android:pivotX="0"
+ android:pivotY="0"
+ android:rotation="90"
+ android:scaleX="0.75"
+ android:scaleY="0.5"
+ android:translateX="100.0"
+ android:translateY="100.0">
+ <path
+ android:name="twoLines"
+ android:pathData="M 100,10 v 90 M 10,100 h 90"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index dcc7769..e0624e5 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -47,7 +47,8 @@
R.drawable.vector_drawable17,
R.drawable.vector_drawable18,
R.drawable.vector_drawable19,
- R.drawable.vector_drawable20
+ R.drawable.vector_drawable20,
+ R.drawable.vector_drawable21
};
@Override
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index ac0f701..2d08163 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -2,7 +2,8 @@
package="com.android.test.voiceinteraction">
<application>
- <activity android:name="VoiceInteractionMain" android:label="Voice Interaction">
+ <activity android:name="VoiceInteractionMain" android:label="Voice Interaction"
+ android:theme="@android:style/Theme.Quantum">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index 9fcbf3e..563fa44 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -19,6 +19,7 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffffff"
+ android:fitsSystemWindows="true"
>
<TextView android:id="@+id/text"
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 6f5788a..a6c09f3 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@
}
try {
- mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0);
+ mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false);
fail("IWindowManager.addAppToken did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index cc621c4..105803e 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -826,6 +826,11 @@
return null;
}
+ @Override
+ public int[] extractThemeAttrs() {
+ return null;
+ }
+
/**
* Retrieve the raw TypedValue for the attribute at <var>index</var>.
*
@@ -912,4 +917,9 @@
public String toString() {
return Arrays.toString(mResourceData);
}
- }
+
+ static TypedArray obtain(Resources res, int len) {
+ return res instanceof BridgeResources ?
+ new BridgeTypedArray(((BridgeResources) res), null, len, true) : null;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
index 5d89f83..faa8852 100644
--- a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
@@ -30,7 +30,6 @@
@LayoutlibDelegate
/*package*/ static TypedArray obtain(Resources res, int len) {
- // FIXME
- return null;
+ return BridgeTypedArray.obtain(res, len);
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
index cdbbe46..610c867 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -79,13 +79,6 @@
return sManager.addNewDelegate(newDelegate);
}
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate(long native_shader, long native_bitmap,
- int shaderTileModeX, int shaderTileModeY) {
- // pass, not needed.
- return 0;
- }
-
// ---- Private delegate/helper methods ----
private BitmapShader_Delegate(java.awt.image.BufferedImage image,
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
index fae8aef..59ddcc6 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
@@ -78,19 +78,6 @@
return sManager.addNewDelegate(newDelegate);
}
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate1(long native_shader, long native_skiaShaderA,
- long native_skiaShaderB, long native_mode) {
- // pass, not needed.
- return 0;
- }
-
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate2(long native_shader, long native_skiaShaderA,
- long native_skiaShaderB, int porterDuffMode) {
- // pass, not needed.
- return 0;
- }
// ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 5e7543a0..9ea4538 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -146,6 +146,8 @@
@LayoutlibDelegate
/*package*/ static void nUnrefFamily(long nativePtr) {
+ // Removing the java reference for the object doesn't mean that it's freed for garbage
+ // collection. Typeface_Delegate may still hold a reference for it.
sManager.removeJavaReferenceFor(nativePtr);
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index ac77377..55c4b98 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -71,22 +71,6 @@
tileMode);
}
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate1(LinearGradient thisGradient,
- long native_shader, float x0, float y0, float x1, float y1,
- int colors[], float positions[], int tileMode) {
- // nothing to be done here.
- return 0;
- }
-
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate2(LinearGradient thisGradient,
- long native_shader, float x0, float y0, float x1, float y1,
- int color0, int color1, int tileMode) {
- // nothing to be done here.
- return 0;
- }
-
// ---- Private delegate/helper methods ----
/**
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index 4f16dcf..80179ee 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -68,20 +68,6 @@
tileMode);
}
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate1(long native_shader, float x, float y, float radius,
- int colors[], float positions[], int tileMode) {
- // nothing to be done here.
- return 0;
- }
-
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate2(long native_shader, float x, float y, float radius,
- int color0, int color1, int tileMode) {
- // nothing to be done here.
- return 0;
- }
-
// ---- Private delegate/helper methods ----
/**
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 70a0a43..14e9960 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -76,13 +76,12 @@
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static void nativeDestructor(long native_shader, long native_skiaShader) {
+ /*package*/ static void nativeDestructor(long native_shader) {
sManager.removeJavaReferenceFor(native_shader);
}
@LayoutlibDelegate
- /*package*/ static void nativeSetLocalMatrix(long native_shader, long native_skiaShader,
- long matrix_instance) {
+ /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) {
// get the delegate from the native int.
Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
if (shaderDelegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index f2b3e8d..95a57a9 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -62,20 +62,6 @@
return nativeCreate1(x, y, new int[] { color0, color1 }, null /*positions*/);
}
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate1(long native_shader, float cx, float cy,
- int[] colors, float[] positions) {
- // nothing to be done here.
- return 0;
- }
-
- @LayoutlibDelegate
- /*package*/ static long nativePostCreate2(long native_shader, float cx, float cy,
- int color0, int color1) {
- // nothing to be done here.
- return 0;
- }
-
// ---- Private delegate/helper methods ----
/**
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index ed8f3b4..9746b48 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -54,7 +54,7 @@
// ---- delegate data ----
- private final long[] mFontFamilies; // the reference to FontFamily_Delegate.
+ private final FontFamily_Delegate[] mFontFamilies; // the reference to FontFamily_Delegate.
private int mStyle;
private static long sDefaultTypeface;
@@ -71,8 +71,7 @@
public List<Font> getFonts(boolean compact) {
List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
- for (long fontFamily : mFontFamilies) {
- FontFamily_Delegate ffd = FontFamily_Delegate.getDelegate(fontFamily);
+ for (FontFamily_Delegate ffd : mFontFamilies) {
if (ffd != null) {
Font font = ffd.getFont(mStyle, compact);
if (font != null) {
@@ -122,7 +121,11 @@
@LayoutlibDelegate
/*package*/ static synchronized long nativeCreateFromArray(long[] familyArray) {
- Typeface_Delegate delegate = new Typeface_Delegate(familyArray, Typeface.NORMAL);
+ FontFamily_Delegate[] fontFamilies = new FontFamily_Delegate[familyArray.length];
+ for (int i = 0; i < familyArray.length; i++) {
+ fontFamilies[i] = FontFamily_Delegate.getDelegate(familyArray[i]);
+ }
+ Typeface_Delegate delegate = new Typeface_Delegate(fontFamilies, Typeface.NORMAL);
return sManager.addNewDelegate(delegate);
}
@@ -153,9 +156,8 @@
// ---- Private delegate/helper methods ----
- private Typeface_Delegate(long[] fontFamilies, int style) {
+ private Typeface_Delegate(FontFamily_Delegate[] fontFamilies, int style) {
mFontFamilies = fontFamilies;
mStyle = style;
}
-
}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 757cdd2..e1a9719 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -72,7 +72,7 @@
@Override
public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, int arg4,
- boolean arg5, boolean arg6, int arg7, int arg8)
+ boolean arg5, boolean arg6, int arg7, int arg8, boolean arg9)
throws RemoteException {
// TODO Auto-generated method stub
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index 936ab4f..e59ccd7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -171,7 +171,7 @@
// Set action bar to be split, if needed.
ActionBarContainer splitView = (ActionBarContainer) findViewById(R.id.split_action_bar);
mActionBarView.setSplitView(splitView);
- mActionBarView.setSplitActionBar(mSplit);
+ mActionBarView.setSplitToolbar(mSplit);
inflateMenus();