diff options
238 files changed, 6633 insertions, 2022 deletions
diff --git a/api/current.txt b/api/current.txt index 05a3072353b0..a2a8661d7c81 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1243,6 +1243,8 @@ package android { 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 @@ package android.app { 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 @@ package android.graphics { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.hardware.camera2 { 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 @@ package android.os.storage { 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 @@ package android.provider { 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 @@ package android.service.voice { 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 @@ package android.widget { 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 @@ package android.widget { 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 @@ package android.widget { 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 @@ package android.widget { 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 @@ package android.widget { 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 2efe4d30cd37..6296dd1bbf50 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -141,7 +141,7 @@ int main(int argc, char** argv) 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 3c3df0156300..f05f4c7c18d3 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -1291,6 +1291,7 @@ public abstract class ActionBar { 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 abstract class ActionBar { 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 07de85c3e3c1..b5281ffe6340 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4194,7 +4194,11 @@ public class Activity extends ContextThemeWrapper */ 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 class Activity extends ContextThemeWrapper */ 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 70f270fdf72d..90aeaae98926 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3355,6 +3355,14 @@ public class Notification implements Parcelable */ 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 @@ public class Notification implements Parcelable * 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 @@ public class Notification implements Parcelable } /** - * 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 d3e908948e2b..e5bf7d0caa79 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -317,9 +317,9 @@ public class AppWidgetManager { 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 @@ public class AppWidgetManager { * <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 @@ public class AppWidgetManager { * 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 @@ public class AppWidgetManager { * <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 15740908b0a3..d89806028556 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -104,6 +104,12 @@ public interface BluetoothProfile { 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 1c838c36fd1c..ab8bf61ec7e0 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2174,7 +2174,6 @@ public class PackageParser { } 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 c08424a4f98c..cea68d2db166 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -296,8 +296,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * {@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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 accceb12ad77..4a89fe72e362 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -219,6 +219,7 @@ public final class CameraManager { private CameraDevice openCameraDeviceUserAsync(String cameraId, CameraDevice.StateListener listener, Handler handler) throws CameraAccessException { + CameraCharacteristics characteristics = getCameraCharacteristics(cameraId); CameraDevice device = null; try { @@ -230,7 +231,8 @@ public final class CameraManager { 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 4cde601c7831..b3e165e793eb 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -236,9 +236,17 @@ public abstract class CameraMetadata<TKey> { /** * <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 @@ public abstract class CameraMetadata<TKey> { * <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 abstract class CameraMetadata<TKey> { 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 @@ public abstract class CameraMetadata<TKey> { * </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 @@ public abstract class CameraMetadata<TKey> { * 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 @@ public abstract class CameraMetadata<TKey> { /** * <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 a4aa29693307..6aa24e6e3780 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -537,30 +537,24 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * * @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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * @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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * * @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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> 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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * * @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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * </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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * </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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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 9aa56cf6636e..42020eb16107 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -383,30 +383,24 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * * @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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * @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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * * @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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { 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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * * @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,59 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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.</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>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, + * 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 + */ + 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 {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}.</p> + * 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>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ] - * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} = + * <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, @@ -2301,8 +2344,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 + * @hide */ public static final Key<float[]> STATISTICS_LENS_SHADING_MAP = new Key<float[]>("android.statistics.lensShadingMap", float[].class); @@ -2402,17 +2444,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * @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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * </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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * </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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 7b249766a977..9a4c53155704 100644 --- a/core/java/android/hardware/camera2/impl/CameraDevice.java +++ b/core/java/android/hardware/camera2/impl/CameraDevice.java @@ -20,6 +20,8 @@ import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE; 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 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { 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 class CameraDevice implements android.hardware.camera2.CameraDevice { } }; - 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 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { @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 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { 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 ab2c49a398f1..dc0c65250386 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.MarshalQueryableStreamConfiguration 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.io.IOException; 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 @@ public class CameraMetadataNative implements Parcelable { // 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 class CameraMetadataNative implements Parcelable { 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 @@ public class CameraMetadataNative implements Parcelable { 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 @@ public class CameraMetadataNative implements Parcelable { 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 @@ public class CameraMetadataNative implements Parcelable { 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 @@ public class CameraMetadataNative implements Parcelable { 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 @@ public class CameraMetadataNative implements Parcelable { 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 fa8c8eaafe2c..b4289db2c57b 100644 --- a/core/java/android/hardware/camera2/params/ColorSpaceTransform.java +++ b/core/java/android/hardware/camera2/params/ColorSpaceTransform.java @@ -139,8 +139,8 @@ public final class ColorSpaceTransform { 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 final class ColorSpaceTransform { 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 final class ColorSpaceTransform { 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 b328f5786321..9bbc33a85f17 100644 --- a/core/java/android/hardware/camera2/params/LensShadingMap.java +++ b/core/java/android/hardware/camera2/params/LensShadingMap.java @@ -28,7 +28,7 @@ import java.util.Arrays; /** * 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 final class LensShadingMap { 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 @@ public final class LensShadingMap { 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 a26c57d5e7c4..a7a3b597da45 100644 --- a/core/java/android/hardware/camera2/params/MeteringRectangle.java +++ b/core/java/android/hardware/camera2/params/MeteringRectangle.java @@ -57,7 +57,7 @@ public final class MeteringRectangle { * @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 @@ public final class MeteringRectangle { * @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 @@ public final class MeteringRectangle { * @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 @@ public final class MeteringRectangle { && 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 83da29a07655..f0bd237fca66 100644 --- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java +++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java @@ -90,7 +90,7 @@ public final class HdmiPlaybackClient { 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 4bccaf1d6f52..3417de12a189 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -39,6 +39,7 @@ import android.text.method.MovementMethod; 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 @@ public class InputMethodService extends AbstractInputMethodService { 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 a9bace15ed1d..38a65c58d6cd 100644 --- a/core/java/android/inputmethodservice/SoftInputWindow.java +++ b/core/java/android/inputmethodservice/SoftInputWindow.java @@ -37,6 +37,8 @@ public class SoftInputWindow extends Dialog { 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 class SoftInputWindow extends Dialog { */ 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 @@ public class SoftInputWindow extends Dialog { } /** - * 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 class SoftInputWindow extends Dialog { */ 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 @@ public class SoftInputWindow extends Dialog { 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 e489e052d9dd..64516e62d161 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -94,11 +94,26 @@ public class Network implements Parcelable { 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 @@ public class Network implements Parcelable { @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 57ed97977312..474192fd0c90 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -70,6 +70,8 @@ public final class Trace { 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 496399113754..68b91cb7dfdf 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -58,24 +58,6 @@ import java.util.concurrent.atomic.AtomicInteger; * 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 @@ public class StorageManager { 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 b53ea811b299..6db78f482f38 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1152,8 +1152,6 @@ public final class ContactsContract { * 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 @@ public final class ContactsContract { * 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 @@ public final class ContactsContract { * 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 @@ public final class ContactsContract { * 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 a83544d08c1a..cd357b790df3 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -22,6 +22,7 @@ import android.content.Context; 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.Message; 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 abstract class VoiceInteractionSession implements KeyEvent.Callback { */ 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 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { 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 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { 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 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { 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 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { 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 7d13399120f3..af1618516e98 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -79,7 +79,7 @@ interface IWindowManager 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 @@ interface IWindowManager 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 c15ce44eb2a2..5cd3d6272571 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -38,11 +38,11 @@ public class SurfaceControl { 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 class SurfaceControl { 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 class SurfaceControl { */ 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 @@ public class SurfaceControl { * @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 @@ public class SurfaceControl { * 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 @@ public class SurfaceControl { * 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 @@ public class SurfaceControl { // 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 @@ public class SurfaceControl { 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 8417887c8782..9c9a939c0a0f 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -33,8 +33,6 @@ import java.io.PrintWriter; /** * 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 @@ public class ThreadedRenderer extends HardwareRenderer { @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 @@ public class ThreadedRenderer extends HardwareRenderer { 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 b821a3e52166..0f40ee7d4679 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -456,6 +456,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager break; } } + if (preorderedList != null) preorderedList.clear(); } } @@ -1778,23 +1785,28 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager break; } } + if (preorderedList != null) preorderedList.clear(); } if (newTouchTarget == null && mFirstTouchTarget != null) { @@ -2928,7 +2953,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager 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 310486209467..af1de78916cb 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -253,9 +253,10 @@ public class ViewPropertyAnimator { 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 @@ public class ViewPropertyAnimator { // 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 @@ public class ViewPropertyAnimator { // 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 @@ public class ViewPropertyAnimator { } } 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 031ad80f3261..4eecc6a0b62c 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -218,7 +218,8 @@ public interface WindowManager extends ViewManager { @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 interface WindowManager extends ViewManager { 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 1bb20c99fedc..d45d686d47a4 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -274,6 +274,11 @@ public interface WindowManagerPolicy { 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 @@ public interface WindowManagerPolicy { * 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 @@ public interface WindowManagerPolicy { * 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 interface WindowManagerPolicy { 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 @@ public interface WindowManagerPolicy { * @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 51759c5b227d..1fddf3e78c35 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -544,6 +544,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter 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 3975edf002b4..a9a5eae45266 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -69,6 +69,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo /** @hide */ public void setPresenter(ActionMenuPresenter presenter) { mPresenter = presenter; + mPresenter.setMenuView(this); } @Override @@ -488,7 +489,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); - mPresenter.dismissPopupMenus(); + dismissPopupMenus(); } /** @hide */ @@ -578,6 +579,56 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } /** + * 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 f9033463a080..8c67bb770b5a 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.MenuItem; 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 @@ import java.util.List; * 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 @@ public class Toolbar extends ViewGroup { } }; + private ToolbarWidgetWrapper mWrapper; + private ActionMenuPresenter mOuterActionMenuPresenter; + private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; + public Toolbar(Context context) { this(context, null); } @@ -137,7 +164,9 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 class Toolbar extends ViewGroup { */ 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 @@ public class Toolbar extends ViewGroup { * @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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { } /** + * 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 @@ public class Toolbar extends ViewGroup { * @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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { } } + 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { } 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 @@ public class Toolbar extends ViewGroup { // 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 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { } @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 @@ public class Toolbar extends ViewGroup { } @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @@ -1083,6 +1371,25 @@ public class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { * * @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 class Toolbar extends ViewGroup { 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 @@ public class Toolbar extends ViewGroup { } }; } + + 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 41f33375f5ed..7e1185031703 100644 --- a/core/java/com/android/internal/app/ProcessStats.java +++ b/core/java/com/android/internal/app/ProcessStats.java @@ -1100,7 +1100,7 @@ public final class ProcessStats implements Parcelable { 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 a238ae36991a..5c7a4e63fd7d 100644 --- a/core/java/com/android/internal/app/WindowDecorActionBar.java +++ b/core/java/com/android/internal/app/WindowDecorActionBar.java @@ -18,7 +18,10 @@ package com.android.internal.app; 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.ActionBarContainer; 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.Window; 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements mTabScrollView.setVisibility(View.GONE); } } - mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode); + mDecorToolbar.setCollapsible(!mHasEmbeddedTabs && isInTabMode); mOverlayLayout.setHasNonEmbeddedTabs(!mHasEmbeddedTabs && isInTabMode); } @@ -263,7 +278,7 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements @Override public void setHomeButtonEnabled(boolean enable) { - mActionView.setHomeButtonEnabled(enable); + mDecorToolbar.setHomeButtonEnabled(enable); } @Override @@ -370,12 +386,12 @@ public class WindowDecorActionBar extends ActionBar implements } 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 class WindowDecorActionBar extends ActionBar implements } 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 class WindowDecorActionBar extends ActionBar implements } 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements 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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements // 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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements mOverlayLayout.requestFitSystemWindows(); } } - mActionView.setNavigationMode(mode); + mDecorToolbar.setNavigationMode(mode); switch (mode) { case NAVIGATION_MODE_TABS: ensureTabsExist(); @@ -1249,7 +1269,7 @@ public class WindowDecorActionBar extends ActionBar implements } 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 @@ public class WindowDecorActionBar extends ActionBar implements @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 @@ public class WindowDecorActionBar extends ActionBar implements 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 b78c70fbb72d..f22800c0983a 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -56,4 +56,10 @@ interface IKeyguardService { 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 183478faca52..9e7ff938cc00 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -34,7 +34,7 @@ import android.view.animation.DecelerateInterpolator; 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 @@ public abstract class AbsActionBarView extends ViewGroup { 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 @@ public abstract class AbsActionBarView extends ViewGroup { * 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 @@ public abstract class AbsActionBarView extends ViewGroup { return mContentHeight; } - public void setSplitView(ActionBarContainer splitView) { + public void setSplitView(ViewGroup splitView) { mSplitView = splitView; } @@ -214,6 +214,10 @@ public abstract class AbsActionBarView extends ViewGroup { 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 ed075142b355..790b6116d127 100644 --- a/core/java/com/android/internal/widget/ActionBarContainer.java +++ b/core/java/com/android/internal/widget/ActionBarContainer.java @@ -36,7 +36,7 @@ import android.widget.FrameLayout; 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 @@ public class ActionBarContainer extends FrameLayout { @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 @@ public class ActionBarContainer extends FrameLayout { 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 @@ public class ActionBarContainer extends FrameLayout { 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 @@ public class ActionBarContainer extends FrameLayout { } } 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 e10070fb30c0..6ff77a0487ce 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -83,7 +83,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi 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 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi } @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 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi 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 7ab4bedebaa2..8a9cb228da68 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.ViewPropertyAnimator; 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar @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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar } 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 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar @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 60631b994984..af827782f699 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -18,7 +18,6 @@ package com.android.internal.widget; 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 @@ import com.android.internal.view.menu.SubMenuBuilder; /** * @hide */ -public class ActionBarView extends AbsActionBarView { +public class ActionBarView extends AbsActionBarView implements DecorToolbar { private static final String TAG = "ActionBarView"; /** @@ -117,8 +116,7 @@ public class ActionBarView extends AbsActionBarView { 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 @@ public class ActionBarView extends AbsActionBarView { private ActionMenuItem mLogoNavItem; private SpinnerAdapter mSpinnerAdapter; - private OnNavigationListener mCallback; + private AdapterView.OnItemSelectedListener mNavItemSelectedListener; private Runnable mTabSelector; @@ -138,18 +136,6 @@ public class ActionBarView extends AbsActionBarView { 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 @@ public class ActionBarView extends AbsActionBarView { 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 @@ public class ActionBarView extends AbsActionBarView { } if (mHomeDescriptionRes != 0) { - setHomeActionContentDescription(mHomeDescriptionRes); + setNavigationContentDescription(mHomeDescriptionRes); } if (mTabScrollView != null && mIncludeTabs) { @@ -313,7 +297,7 @@ public class ActionBarView extends AbsActionBarView { } @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 @@ public class ActionBarView extends AbsActionBarView { 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 class ActionBarView extends AbsActionBarView { } } - public void setCallback(OnNavigationListener callback) { - mCallback = callback; - } - public void setMenuPrepared() { mMenuPrepared = true; } @@ -473,7 +461,7 @@ public class ActionBarView extends AbsActionBarView { } } - 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 class ActionBarView extends AbsActionBarView { } } - 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 @@ public class ActionBarView extends AbsActionBarView { return mSpinner.getSelectedItemPosition(); } - public View getCustomNavigationView() { + public View getCustomView() { return mCustomNavView; } @@ -797,6 +786,11 @@ public class ActionBarView extends AbsActionBarView { } @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 @@ public class ActionBarView extends AbsActionBarView { 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 @@ public class ActionBarView extends AbsActionBarView { @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 @@ public class ActionBarView extends AbsActionBarView { 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 class ActionBarView extends AbsActionBarView { } } - 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 000000000000..ee6988e57d84 --- /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 000000000000..f90aaea38732 --- /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 0c7eefaa0c94..e06987608c54 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -789,7 +789,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) } // 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 5a935a96eaff..4594cc31adac 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -61,6 +61,13 @@ static struct { 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 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { 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 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display 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 @@ static JNINativeMethod sSurfaceControlMethods[] = { (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 @@ int register_android_view_SurfaceControl(JNIEnv* env) 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 5bc0f6248d23..6f256f0ae4dc 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -293,6 +293,12 @@ static void android_view_ThreadedRenderer_destroyLayer(JNIEnv* env, jobject claz 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 @@ static JNINativeMethod gMethods[] = { { "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 e87352f2a0a7..4c4f6a494164 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 cb47b3cd8815..4a956d7d6fd6 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 c29fd1a057ba..f7a6a65884f9 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 000000000000..4f3d3d55d86b --- /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 000000000000..023b0120db07 --- /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 000000000000..57fba2a38461 --- /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 000000000000..4f3d3d55d86b --- /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 000000000000..57fba2a38461 --- /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 000000000000..023b0120db07 --- /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 000000000000..290c7daaf1b3 --- /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 a7cd9a7515da..3d043c45e8fe 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 dbe2d7f19602..f3b84951b6de 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 3b275a5d0e6c..71f55fbf3a3e 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 4640f2a5d62f..d235eaa27a05 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 9eb6f7426595..0ef23e326098 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 42ed318df544..9c33d8052cc1 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 1f4c88d14405..63f26740661a 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -171,8 +171,8 @@ please see styles_device_defaults.xml. <!-- 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 @@ please see styles_device_defaults.xml. <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 @@ please see styles_device_defaults.xml. <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 2e7a5b179758..ea3268136160 100644 --- a/core/res/res/values/styles_quantum.xml +++ b/core/res/res/values/styles_quantum.xml @@ -773,7 +773,7 @@ please see styles_device_defaults.xml. <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 @@ please see styles_device_defaults.xml. <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 69f73e50527f..6e1629b8dfad 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 aaab9495a22a..41f4ff8f65e9 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -192,6 +192,7 @@ please see themes_device_defaults.xml. <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 bb787bba50cc..484c694db13f 100644 --- a/core/res/res/values/themes_quantum.xml +++ b/core/res/res/values/themes_quantum.xml @@ -162,6 +162,7 @@ please see themes_device_defaults.xml. <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 @@ please see themes_device_defaults.xml. <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 d4ea7a907f4b..5e4e42bda14c 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -713,6 +713,9 @@ public class Canvas { * @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 @@ public class Canvas { * * @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 492376fea725..afd529ced30c 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -39,7 +39,6 @@ import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; /** @@ -59,7 +58,23 @@ import java.util.HashMap; * 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 @@ import java.util.HashMap; * <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 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { throw new XmlPullParserException("no " + tag + " defined"); } - // post parse cleanup - pathRenderer.parseFinish(); return pathRenderer; } @@ -373,7 +381,6 @@ public class VectorDrawable extends Drawable { 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 class VectorDrawable extends Drawable { 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 class VectorDrawable extends Drawable { 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 class VectorDrawable extends Drawable { } 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); - final Paint strokePaint = mStrokePaint; - if (vPath.mStrokeLineJoin != null) { - strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); + if (vPath.mClip) { + canvas.clipPath(mRenderPath, Region.Op.REPLACE); } - if (vPath.mStrokeLineCap != null) { - strokePaint.setStrokeCap(vPath.mStrokeLineCap); + 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); } - strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale); - strokePaint.setColor(vPath.mStrokeColor); - strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale); - canvas.drawPath(mRenderPath, strokePaint); - } - } + if (vPath.mStrokeColor != 0) { + if (mStrokePaint == null) { + mStrokePaint = new Paint(); + mStrokePaint.setColorFilter(mColorFilter); + mStrokePaint.setStyle(Paint.Style.STROKE); + mStrokePaint.setAntiAlias(true); + } - /** - * 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]); + 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); + } } } @@ -587,17 +590,84 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { 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 @@ public class VectorDrawable extends Drawable { R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); updateColorAlphas(); + a.recycle(); } private void updateColorAlphas() { @@ -921,33 +965,6 @@ public class VectorDrawable extends Drawable { } 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 b6b3428a5c9c..160fbea318dd 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -556,6 +556,13 @@ bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) 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 a54b33ee6f60..da85d44898eb 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -63,6 +63,8 @@ public: 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 2e103d887e75..8e772f2b5996 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -282,6 +282,18 @@ void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) { 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 8aeb264e15d0..22d4e222b62e 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 @@ public: 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 f4affa03899f..47a8ce5ba467 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -2818,18 +2818,22 @@ public class AudioManager { } /** - * 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 cf189027e0d2..98a7c658b309 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -169,7 +169,8 @@ public class AudioService extends IAudioService.Stub { // 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 @@ public class AudioService extends IAudioService.Stub { 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 @@ public class AudioService extends IAudioService.Stub { } 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 @@ public class AudioService extends IAudioService.Stub { } 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 class AudioService extends IAudioService.Stub { } } - 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 @@ public class AudioService extends IAudioService.Stub { 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 @@ public class AudioService extends IAudioService.Stub { } // 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 @@ public class AudioService extends IAudioService.Stub { 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 @@ public class AudioService extends IAudioService.Stub { } } + 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 @@ public class AudioService extends IAudioService.Stub { } } - 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 0c454437e3e3..5abf4b6cfe9a 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -299,7 +299,7 @@ public class AudioSystem 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 @@ public class AudioSystem 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 30de4f9d3d70..e59623b4205c 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -232,7 +232,7 @@ interface IAudioService { 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 a3caba24ee56..fe512152ba1c 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.RggbChannelVector; 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 static com.android.mediaframeworktest.unit.ByteArrayHelpers.*; 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 @@ public class CameraMetadataTest extends junit.framework.TestCase { 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 @@ public class CameraMetadataTest extends junit.framework.TestCase { } } + 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 8c9030dc3403..e8944ec2ad72 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 a804c8c32ac5..a8e330be7537 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 18b59f117605..a2e54a76234f 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 3830df7f252d..01d9ab3633ea 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 000000000000..ea896d5484d8 --- /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 4dfda9165e04..1f3c17692c7b 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.TextWatcher; 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 @@ import android.widget.TextView.OnEditorActionListener; 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 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView 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 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView @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 ba3c0427e800..c89f9bfe56e4 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 000000000000..295b4f54b1d3 --- /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 000000000000..295b4f54b1d3 --- /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 936f73be5675..9bf42b2cfc90 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 bc7288de80f3..046862f985ee 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 ae04bf503a8b..0936cc2550f1 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 e43464c52f03..c45254e0bb49 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 ce3d14b17666..5c4d98bd84a2 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 c9ddc234df1d..d7c5651661cc 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 d396b8cc5d2c..240580416bdd 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 51790b51efa4..982e0c6c4361 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 91b8f6eef6eb..570e1bb76c59 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 1d1ca0a28fa8..127192a21024 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 a79193d5996d..c9c7b8e27909 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 32b7090390b9..1d90dae23b6c 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 d26cfae18c8b..a9c6678d426a 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 d26cfae18c8b..a9c6678d426a 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 c93fbf6b9924..6ca4ebca5809 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 3bded8b99549..d0e9c0ad00ba 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 1979c55e5e52..c692b280e830 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 399740a362d4..ee2c48dc011b 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 be7eb9b258bf..44d35b308d8d 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 390ec81a9d6e..d9790f6992aa 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 a0c5cfe82c91..d95fe06cf54a 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 6850b3df3f59..60d7de19437e 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 b00c382be3f5..09dde429b879 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 b75c7f3d9ca4..dc8541616e01 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 904b9980afbf..b11a00416851 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 98373c9ce6b4..f62209fc5e72 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 412d001d6095..6cf13be4719b 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 33a67014364f..4f070061373e 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 3ed729b3b7e8..84bbf8ba300a 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 409b9badea76..c31ea24f3399 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 f3b4e9ea9047..a9cf7d66f107 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 2b39e1405e02..bb2e5c16ee6b 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 5d2ccbccc5c9..7220777b9090 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 cede14c051b8..d0ebd5493a92 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 280ce40192ca..23ce4a9ace1c 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 773a6fbe786a..c00b7edd135b 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 82216de1d1f0..263fc46a07b6 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 7ffd381ac86a..75706a2031db 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 e79adf92063a..c4bef68a083e 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 aec7e876f081..825dfecfbabb 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 93c7f60eaec3..f9ac82815a39 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 b0e58e4cc657..1c13e62193c7 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 b9d121a5a7cf..00bf8c0f77fa 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 c48733f2274a..7ffa77c62df9 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 c726014f84f0..d726428c203b 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 45bb2ad24ae4..8debc9a967be 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 99470d6620de..6171c16c561f 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 1e40ed602724..14782e6f90f1 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 e4d7471ea163..a7fb15ddba77 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 3525b5e3a9aa..b8d8c58c0003 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 3217daa76706..dc75e78abe2c 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 2f8ae2fb8225..0713ddd6cd2b 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 506d27edb2a9..c0ba2508fb10 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 5b3c5b2abd42..e149d7b8973b 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 c6fddfeb053e..f99c3415f43a 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 d8e1c35cb31f..6940b2c0da70 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 ce9e260dd051..04c00f523dd6 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 cafb68867e73..4ffb01bb3a27 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 4865f7be75f5..4c4497282b07 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 35496897b94c..c45361874f1c 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 6e35230dd991..610b37606dcc 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 41c0e78fa775..4c7f3dfa4a87 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 @@ public class KeyguardService extends Service { 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 b2872fab9b8d..7110d8ddac17 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.EventLog; 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 @@ public class KeyguardViewMediator extends SystemUI { 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 @@ public class KeyguardViewMediator extends SystemUI { /** 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 @@ public class KeyguardViewMediator extends SystemUI { 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 @@ public class KeyguardViewMediator extends SystemUI { case DISMISS: handleDismiss(); break; + case START_KEYGUARD_EXIT_ANIM: + handleStartKeyguardExitAnimation((Long) msg.obj); + break; } } }; @@ -1207,6 +1216,19 @@ public class KeyguardViewMediator extends SystemUI { 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 @@ public class KeyguardViewMediator extends SystemUI { 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 bdac7a096078..626fc0da2524 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 @@ public class QSPanel extends ViewGroup { 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 130f9ce60523..20bbf8b69457 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 @@ public class NotificationsTile extends QSTile<NotificationsTile.NotificationsSta // 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 @@ public class NotificationsTile extends QSTile<NotificationsTile.NotificationsSta @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 000000000000..06dc4e6b8984 --- /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 cda84cf8f8c6..21b41c731582 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.provider.Settings; 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.R; 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 abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements // so we just dump our cache ... mUsersAllowingPrivateNotifications.clear(); // ... and refresh all the notifications - updateNotificationIcons(); + updateNotifications(); } }; @@ -284,11 +286,12 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements @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 @@ public abstract class BaseStatusBar extends SystemUI implements @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 @@ public abstract class BaseStatusBar extends SystemUI implements } } - 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 @@ public abstract class BaseStatusBar extends SystemUI implements 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(); - } - - 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); + mNotificationData.add(entry, ranking); + updateNotifications(); } - private void addNotificationViews(StatusBarNotification notification) { - addNotificationViews(createNotificationViews(notification)); + private void addNotificationViews(StatusBarNotification notification, Ranking ranking) { + addNotificationViews(createNotificationViews(notification), ranking); } /** @@ -1208,17 +1202,17 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements } 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 @@ public abstract class BaseStatusBar extends SystemUI implements protected void setZenMode(int mode) { if (!isDeviceProvisioned()) return; mZenMode = mode; - updateNotificationIcons(); + updateNotifications(); } protected void setShowLockscreenNotifications(boolean show) { @@ -1263,41 +1260,37 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements && 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 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ public abstract class BaseStatusBar extends SystemUI implements 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 7d576cb34243..5f1325b56ebd 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 @@ package com.android.systemui.statusbar; 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 @@ public class FlingAnimationUtils { 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 @@ public class FlingAnimationUtils { * @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 @@ public class FlingAnimationUtils { = 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 class FlingAnimationUtils { */ 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 @@ public class FlingAnimationUtils { 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 @@ public class FlingAnimationUtils { = 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 @@ public class FlingAnimationUtils { 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 05558795f6f2..24da5c232400 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 @@ import com.android.systemui.statusbar.phone.PhoneStatusBar; 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 @@ public class InterceptedNotifications { 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 class InterceptedNotifications { } 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 @@ public class InterceptedNotifications { private void updateSyntheticNotification() { if (mIntercepted.isEmpty()) { if (mSynKey != null) { - mBar.removeNotificationInternal(mSynKey); + mBar.removeNotificationInternal(mSynKey, null); mSynKey = null; } return; @@ -107,9 +106,9 @@ public class InterceptedNotifications { 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 569624678953..d829ac0af5d7 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 class NotificationData { 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 @@ public class NotificationData { } 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 @@ public class NotificationData { 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 714ad06ef095..994b3292e551 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.Context; 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.View; 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 @@ public class KeyguardBottomAreaView extends FrameLayout @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 @@ public class KeyguardBottomAreaView extends FrameLayout mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); mUnlockMethodCache.addListener(this); updateTrust(); - mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); } public void setActivityStarter(ActivityStarter activityStarter) { @@ -97,12 +90,12 @@ public class KeyguardBottomAreaView extends FrameLayout 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 @@ public class KeyguardBottomAreaView extends FrameLayout } 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 @@ public class KeyguardBottomAreaView extends FrameLayout 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 000000000000..b4f4865395d2 --- /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 52688df0576b..802e5e578add 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.AnimatorListenerAdapter; 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.StatusBarState; 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements // 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 @@ public class NotificationPanelView extends PanelView implements mQsExpansionEnabled = qsExpansionEnabled; } + @Override + public void resetViews() { + mBlockTouches = false; + mPageSwiper.reset(); + closeQs(); + } + public void closeQs() { cancelAnimation(); setQsExpansion(mQsMinExpansionHeight); @@ -263,9 +285,7 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements @Override public boolean onInterceptTouchEvent(MotionEvent event) { + if (mBlockTouches) { + return false; + } int pointerIndex = event.findPointerIndex(mTrackingPointer); if (pointerIndex < 0) { pointerIndex = 0; @@ -298,7 +321,7 @@ public class NotificationPanelView extends PanelView implements mInitialTouchX = x; initVelocityTracker(); trackMovement(event); - if (shouldIntercept(mInitialTouchX, mInitialTouchY, 0)) { + if (shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) { getParent().requestDisallowInterceptTouchEvent(true); } break; @@ -316,7 +339,7 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements @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); + } + if (mQsTracking || mQsExpanded) { + return onQsTouch(event); + } - 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; + super.onTouchEvent(event); + return true; + } - case MotionEvent.ACTION_MOVE: - final float h = y - mInitialTouchY; - setQsExpansion(h + mInitialHeightOnTouch); - trackMovement(event); - break; + @Override + protected boolean hasConflictingGestures() { + return mStatusBar.getBarState() != StatusBarState.SHADE; + } - 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; + 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; - // Consume touch events when QS are expanded. - return mQsExpanded || super.onTouchEvent(event); + 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 @@ public class NotificationPanelView extends PanelView implements mInitialHeightOnTouch = mQsExpansionHeight; mInitialTouchY = mLastTouchY; mInitialTouchX = mLastTouchX; - mTracking = true; + mQsTracking = true; } } @@ -569,7 +610,7 @@ public class NotificationPanelView extends PanelView implements /** * @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 @@ public class NotificationPanelView extends PanelView implements protected void onExpandingStarted() { super.onExpandingStarted(); mNotificationStackScroller.onExpansionStarted(); + mIsExpanding = true; } @Override protected void onExpandingFinished() { super.onExpandingFinished(); mNotificationStackScroller.onExpansionStopped(); + mIsExpanding = false; } @Override @@ -686,6 +729,12 @@ public class NotificationPanelView extends PanelView implements } @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 @@ public class NotificationPanelView extends PanelView implements } } } + + @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 1015d5bd5202..b94f6f3d2fba 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 @@ public class PanelBar extends FrameLayout { 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 7500c105e9f9..c5a9b850581a 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 com.android.systemui.statusbar.FlingAnimationUtils; 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 @@ public class PanelView extends FrameLayout { 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 @@ public class PanelView extends FrameLayout { 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 @@ public class PanelView extends FrameLayout { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - mTracking = false; mTrackingPointer = -1; trackMovement(event); boolean expand = flingWithCurrentVelocity(); @@ -194,14 +208,18 @@ public class PanelView extends FrameLayout { } 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 @@ public class PanelView extends FrameLayout { 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 ba998c5e3739..0e5b7e133c5f 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.SystemClock; 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, R.integer.config_show_search_delay); } - private void loadNotificationShade() { + private void updateNotificationShade() { if (mStackScroller == null) return; int N = mNotificationData.size(); @@ -1159,7 +1162,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void userSwitched(int newUserId) { if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); animateCollapsePanels(); - updateNotificationIcons(); + updateNotifications(); resetUserSetupObserver(); } @@ -2780,7 +2832,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 049c5fc5786d..000000000000 --- 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 5e2d06b70196..cf56fa57120d 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 @@ public class AnimationFilter { boolean animateZ; boolean animateScale; boolean animateHeight; + boolean animateTopInset; boolean animateDimmed; boolean hasDelays; @@ -60,6 +61,11 @@ public class AnimationFilter { return this; } + public AnimationFilter animateTopInset() { + animateTopInset = true; + return this; + } + public AnimationFilter animateDimmed() { animateDimmed = true; return this; @@ -84,6 +90,7 @@ public class AnimationFilter { animateZ |= filter.animateZ; animateScale |= filter.animateScale; animateHeight |= filter.animateHeight; + animateTopInset |= filter.animateTopInset; animateDimmed |= filter.animateDimmed; hasDelays |= filter.hasDelays; } @@ -94,6 +101,7 @@ public class AnimationFilter { 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 079b184e510d..58176b9a7d56 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 @@ public class NotificationStackScrollLayout extends ViewGroup new AnimationFilter() .animateAlpha() .animateHeight() + .animateTopInset() .animateY() .animateZ() .hasDelays(), @@ -1607,6 +1608,7 @@ public class NotificationStackScrollLayout extends ViewGroup new AnimationFilter() .animateAlpha() .animateHeight() + .animateTopInset() .animateY() .animateZ() .hasDelays(), @@ -1615,6 +1617,7 @@ public class NotificationStackScrollLayout extends ViewGroup new AnimationFilter() .animateAlpha() .animateHeight() + .animateTopInset() .animateY() .animateZ() .hasDelays(), @@ -1623,6 +1626,7 @@ public class NotificationStackScrollLayout extends ViewGroup new AnimationFilter() .animateAlpha() .animateHeight() + .animateTopInset() .animateY() .animateDimmed() .animateScale() @@ -1651,6 +1655,7 @@ public class NotificationStackScrollLayout extends ViewGroup 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 bd2541a5e5c4..2b52c7e5ef45 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 @@ public class StackScrollAlgorithm { private int mBottomStackPeekSize; private int mZDistanceBetweenElements; private int mZBasicHeight; + private int mRoundedRectCornerRadius; private StackIndentationFunctor mTopStackIndentationFunctor; private StackIndentationFunctor mBottomStackIndentationFunctor; @@ -111,6 +112,8 @@ public class StackScrollAlgorithm { 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 @@ public class StackScrollAlgorithm { 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 44e10bea8a2d..94cb16da39f6 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 @@ public class StackScrollState { 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 class StackScrollState { */ 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 @@ public class StackScrollState { // apply dimming child.setDimmed(state.dimmed, false /* animate */); - // 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(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; + float oldClipTopAmount = child.getClipTopAmount(); + if (oldClipTopAmount != state.clipTopAmount) { + child.setClipTopAmount(state.clipTopAmount); + } + + 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 @@ public class StackScrollState { 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 @@ public class StackScrollState { 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 f019e6cbffd7..f41ab3a03a91 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 @@ public class StackStateAnimator { 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 @@ public class StackStateAnimator { 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 @@ public class StackStateAnimator { 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 25147b4b4f7f..c2bd1cbf402c 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 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void addNotificationInternal(StatusBarNotification notification) { + public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) { } @Override @@ -58,7 +58,7 @@ public class TvStatusBar extends BaseStatusBar { } @Override - protected void removeNotificationInternal(String key) { + protected void removeNotificationInternal(String key, Ranking ranking) { } @Override @@ -117,7 +117,7 @@ public class TvStatusBar extends BaseStatusBar { } @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 06f4c2e17e13..67f3a3debfec 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 @@ public class VolumePanel extends Handler { 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 79f8a1f18434..3c4e951f9e73 100644 --- a/packages/services/PacProcessor/Android.mk +++ b/packages/services/PacProcessor/Android.mk @@ -27,8 +27,6 @@ LOCAL_CERTIFICATE := platform 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 8a60927c968f..f16c90b367dd 100644 --- a/packages/services/PacProcessor/jni/Android.mk +++ b/packages/services/PacProcessor/jni/Android.mk @@ -35,7 +35,6 @@ LOCAL_SHARED_LIBRARIES := \ 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 2fea785cbd52..6b0095a5ba1f 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 3c379027573f..1a7c0a8900eb 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - @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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { + 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 966924b2f2b5..faf702088f12 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 @@ public class KeyguardServiceDelegate { 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 7cb48fa7f576..f236ce703ea6 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 class KeyguardServiceWrapper implements IKeyguardService { } } + 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 87b1d3203c7c..7a67d6399265 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 @@ class AppWidgetServiceImpl { 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 1e21e1cc5134..5527528fd25e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -5606,16 +5606,23 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { } 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 dd3664548cb3..eebb50360144 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 @@ public final class ActiveServices { 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 f2a169804e6d..fd31b4142f22 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 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.publish(mContext); mUsageStatsService.publish(mContext); mAppOpsService.publish(mContext); - + Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); } @@ -7753,7 +7754,7 @@ public final class ActivityManagerService extends ActivityManagerNative * 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 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - 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 @@ public final class ActivityManagerService extends ActivityManagerNative } } + 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative */ 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 @@ public final class ActivityManagerService extends ActivityManagerNative } 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 @@ public final class ActivityManagerService extends ActivityManagerNative @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 final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative @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 b56046e5280e..16ad1533645e 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_USER_LEAVING; 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 @@ final class ActivityStack { } } + /** + * 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { // - 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 @@ final class ActivityStack { // 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 class ActivityStack { 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 @@ final class ActivityStack { 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 class ActivityStack { } 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { } } - 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 @@ final class ActivityStack { 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 class ActivityStack { } 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 class ActivityStack { 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 29a1708baae1..598e524c5cc3 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_TASKS; 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 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - 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 @@ public final class ActivityStackSupervisor implements DisplayListener { } 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 @@ public final class ActivityStackSupervisor implements DisplayListener { (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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { == (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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { } } 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 9d6481ac4fbf..7b2b04da278f 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.ComponentName; 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 @@ public final class BroadcastQueue { 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 c07bc1e9a4ed..ce83ae6fb0e7 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 @@ final class TaskRecord extends ThumbnailHolder { 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 @@ final class TaskRecord extends ThumbnailHolder { /** 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 @@ final class TaskRecord extends ThumbnailHolder { 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 @@ final class TaskRecord extends ThumbnailHolder { rootWasReset = _rootWasReset; askedCompatMode = _askedCompatMode; taskType = _taskType; - mTaskToReturnTo = HOME_ACTIVITY_TYPE; + mOnTopOfHome = _onTopOfHome; userId = _userId; lastDescription = _lastDescription; mActivities = activities; @@ -209,14 +206,6 @@ final class TaskRecord extends ThumbnailHolder { } } - 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 @@ final class TaskRecord extends ThumbnailHolder { } 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 @@ final class TaskRecord extends ThumbnailHolder { 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 @@ final class TaskRecord extends ThumbnailHolder { 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 @@ final class TaskRecord extends ThumbnailHolder { 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 class TaskRecord extends ThumbnailHolder { 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 @@ final class TaskRecord extends ThumbnailHolder { 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 c7d28714e4db..8fd55e7a46ab 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 @@ public final class ContentService extends IContentService.Stub { // 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 000000000000..d46cc7bf25d0 --- /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 3c18a5991472..e0a01f0bafeb 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.HdmiCecDeviceInfo; 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 com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import libcore.util.EmptyArray; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -99,7 +99,7 @@ final class HdmiCecController { */ 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 @@ final class HdmiCecController { } /** + * 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 @@ final class HdmiCecController { 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 @@ final class HdmiCecController { 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 @@ final class HdmiCecController { * 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 @@ final class HdmiCecController { 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 be270b9b999d..9a76734943d6 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.HdmiCec; 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 @@ public class HdmiCecMessageBuilder { 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 @@ public class HdmiCecMessageBuilder { } /** + * 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 475852f8edd2..072b97f1d50f 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 android.util.Slog; 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 @@ public final class HdmiControlService extends SystemService { // 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 @@ public final class HdmiControlService extends SystemService { } } + 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 @@ public final class HdmiControlService extends SystemService { } } + 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 6d75ee5db76b..13cc98c67041 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } 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 bb926111e32d..69aeae6b7cb0 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 @@ final class Settings { // 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 e2d2ac6f9850..4f8b9d70c0a2 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.graphics.Rect; 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 @@ public class AppTransition implements Dump { 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 @@ public class AppTransition implements Dump { 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 @@ public class AppTransition implements Dump { 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 @@ public class AppTransition implements Dump { : 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 ca4ad8a32e0d..12c15e27d3e3 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 @@ class AppWindowToken extends WindowToken { final WindowAnimator mAnimator; + final boolean voiceInteraction; + int groupId = -1; boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -107,11 +109,13 @@ class AppWindowToken extends WindowToken { 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 @@ class AppWindowToken extends WindowToken { 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 266527d32e97..6fdd535fc3ff 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.util.TimeUtils; 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 @@ import java.util.ArrayList; 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 @@ public class WindowAnimator { 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 @@ public class WindowAnimator { 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 @@ public class WindowAnimator { } } - 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 @@ public class WindowAnimator { 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 @@ public class WindowAnimator { } } 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 @@ public class WindowAnimator { // 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 c23d1ead9068..05502cf1b778 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 @@ public class WindowManagerService extends IWindowManager.Stub + 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 @@ public class WindowManagerService extends IWindowManager.Stub + 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 @@ public class WindowManagerService extends IWindowManager.Stub } 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 @@ public class WindowManagerService extends IWindowManager.Stub } 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 @@ public class WindowManagerService extends IWindowManager.Stub @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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } @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 @@ public class WindowManagerService extends IWindowManager.Stub // 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 class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } } + voiceInteraction |= wtoken.voiceInteraction; + if (wtoken.appFullscreen) { WindowState ws = wtoken.findMainWindow(); if (ws != null) { @@ -8644,7 +8671,7 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 c88382c67a17..4a80e3e11767 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { 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 1e79dcb3a3eb..e257ebc90b48 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 @@ class WindowStateAnimator { 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 27c8876fdf9c..c6de67658c78 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 @@ static struct { 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,49 +58,135 @@ public: // 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) : - mDevice(device), - mCallbacksObj(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; + } + } -void HdmiCecController::init() { - mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); -} + const cec_message_t& cec() const { + return mEvent.cec; + } -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); + const hotplug_event_t& hotplug() const { + return mEvent.hotplug; + } - env->CallVoidMethod(mCallbacksObj, - gHdmiCecControllerClassInfo.handleIncomingCecCommand, - srcAddr, dstAddr, body); - env->DeleteLocalRef(body); + virtual ~CecEventWrapper() {} - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} +private: + hdmi_event_t mEvent; +}; -void HdmiCecController::propagateHotplugEvent(const hotplug_event_t& event) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mCallbacksObj, - gHdmiCecControllerClassInfo.handleHotplug, event.connected); +// 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; + } + } - checkAndClearExceptionFromCallback(env, __FUNCTION__); +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), + mLooper(looper) { +} + +void HdmiCecController::init() { + mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); } int HdmiCecController::sendMessage(const cec_message_t& message) { @@ -132,15 +222,6 @@ uint32_t HdmiCecController::getVendorId() { 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 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { 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 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { 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 jint nativeGetVendorId(JNIEnv* env, jclass clazz, jlong controllerPtr) { 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 @@ static JNINativeMethod sMethods[] = { #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 bc34e0ef31ae..0f24ff61f00b 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -186,7 +186,7 @@ public final class SystemServer { // 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 9b6daad47717..62ff121f78b2 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 @@ class VoiceInteractionManagerServiceImpl { 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 59bdf64d1d2b..874279b4b09b 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -98,6 +98,7 @@ public class DctConstants { 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 db802c56a03b..6b70631aaf7a 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 000000000000..970c5fd6e275 --- /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 cde5d2075335..108709bd76b2 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> + <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:background">#bbb</item> <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:background">#888</item> - <item name="android:text">200</item> - <item name="android:translationZ">200dp</item> + <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 000000000000..45e77edb03da --- /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 d0f2a2db366a..66a9452d5380 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 db5697c23253..40f23f0c4bc1 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 8e8250d9ee21..5b4c4abe3aa6 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: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 + 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" /> + </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 2e379d675b09..c93c85fef3bd 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 2b6c5d31b32a..3422bbfe9d05 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 681eb4faf099..d0edd8cf199f 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 ef1b8e4cba33..8c946df20d5e 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 77bf7232c9af..1abe1e1f1753 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 df5838c53e01..b08e157f00ca 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 0bdcda564603..ae85d9b14caa 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 4453ae4b3569..8e98d02513d3 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 dfae9acb122d..6d74ebd96ce9 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 000000000000..e0013e7d28dd --- /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 dcc7769881d6..e0624e55db2b 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 @@ public class VectorDrawablePerformance extends Activity { 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 ac0f70146dcc..2d08163d4fcb 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 9fcbf3e2d9ee..563fa4400f03 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 6f5788a61f56..a6c09f338b5d 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 @@ public class WindowManagerPermissionTests extends TestCase { } 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 cc621c431372..105803e5ef70 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 @@ public final class BridgeTypedArray extends TypedArray { return null; } + @Override + public int[] extractThemeAttrs() { + return null; + } + /** * Retrieve the raw TypedValue for the attribute at <var>index</var>. * @@ -912,4 +917,9 @@ public final class BridgeTypedArray extends TypedArray { 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 5d89f83f5231..faa8852b494e 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 @@ public class TypedArray_Delegate { @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 cdbbe467ab67..610c867dd09d 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 @@ public class BitmapShader_Delegate extends Shader_Delegate { 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 fae8aefbba29..59ddcc6a6ca8 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 @@ public class ComposeShader_Delegate extends Shader_Delegate { 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 5e7543a034ad..9ea45386055f 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 @@ public class FontFamily_Delegate { @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 ac77377d315b..55c4b98306b3 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 @@ public final class LinearGradient_Delegate extends Gradient_Delegate { 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 4f16dcf081fd..80179ee5703d 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 @@ public class RadialGradient_Delegate extends Gradient_Delegate { 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 70a0a432ddb1..14e9960f8285 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 @@ public abstract class Shader_Delegate { // ---- 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 f2b3e8d0fd07..95a57a99c5be 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 @@ public class SweepGradient_Delegate extends Gradient_Delegate { 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 ed8f3b4552c3..9746b48faf05 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 @@ public final class Typeface_Delegate { // ---- 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 final class Typeface_Delegate { 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 @@ public final class Typeface_Delegate { @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 @@ public final class Typeface_Delegate { // ---- 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 757cdd27ad9e..e1a971904338 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -72,7 +72,7 @@ public class IWindowManagerImpl implements IWindowManager { @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 936ab4f7dee6..e59ccd735f4d 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 @@ public class ActionBarLayout extends LinearLayout { // 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(); |