Merge "EthernetDataTracker: Update hardware address when interface is changed"
diff --git a/Android.mk b/Android.mk
index 5c48dfe..a691987 100644
--- a/Android.mk
+++ b/Android.mk
@@ -616,6 +616,7 @@
$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
-api $(INTERNAL_PLATFORM_API_FILE) \
+ -removedApi $(INTERNAL_PLATFORM_REMOVED_API_FILE) \
-nodocs
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
diff --git a/api/current.txt b/api/current.txt
index eb6de96..4f71a80 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -314,6 +314,7 @@
field public static final int backgroundSplit = 16843659; // 0x101038b
field public static final int backgroundStacked = 16843658; // 0x101038a
field public static final int backupAgent = 16843391; // 0x101027f
+ field public static final int banner = 16843762; // 0x10103f2
field public static final int baseline = 16843548; // 0x101031c
field public static final int baselineAlignBottom = 16843042; // 0x1010122
field public static final int baselineAligned = 16843046; // 0x1010126
@@ -345,7 +346,7 @@
field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
- field public static final int castsShadow = 16843774; // 0x10103fe
+ field public static final int castsShadow = 16843775; // 0x10103ff
field public static final int category = 16843752; // 0x10103e8
field public static final int centerBright = 16842956; // 0x10100cc
field public static final int centerColor = 16843275; // 0x101020b
@@ -399,10 +400,10 @@
field public static final int content = 16843355; // 0x101025b
field public static final int contentAuthority = 16843408; // 0x1010290
field public static final int contentDescription = 16843379; // 0x1010273
- field public static final int controlX1 = 16843768; // 0x10103f8
- field public static final int controlX2 = 16843770; // 0x10103fa
- field public static final int controlY1 = 16843769; // 0x10103f9
- field public static final int controlY2 = 16843771; // 0x10103fb
+ field public static final int controlX1 = 16843769; // 0x10103f9
+ field public static final int controlX2 = 16843771; // 0x10103fb
+ field public static final int controlY1 = 16843770; // 0x10103fa
+ field public static final int controlY2 = 16843772; // 0x10103fc
field public static final int cropToPadding = 16843043; // 0x1010123
field public static final int cursorVisible = 16843090; // 0x1010152
field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -505,7 +506,7 @@
field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
- field public static final int fastScrollStyle = 16843763; // 0x10103f3
+ field public static final int fastScrollStyle = 16843764; // 0x10103f4
field public static final int fastScrollTextColor = 16843609; // 0x1010359
field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
@@ -531,7 +532,7 @@
field public static final int format12Hour = 16843722; // 0x10103ca
field public static final int format24Hour = 16843723; // 0x10103cb
field public static final int fragment = 16843491; // 0x10102e3
- field public static final int fragmentBreadCrumbsStyle = 16843762; // 0x10103f2
+ field public static final int fragmentBreadCrumbsStyle = 16843763; // 0x10103f3
field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
@@ -825,7 +826,7 @@
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
- field public static final int pinned = 16843776; // 0x1010400
+ field public static final int pinned = 16843777; // 0x1010401
field public static final int pivotX = 16843189; // 0x10101b5
field public static final int pivotY = 16843190; // 0x10101b6
field public static final int popupAnimationStyle = 16843465; // 0x10102c9
@@ -889,7 +890,7 @@
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
field public static final int requiredForAllUsers = 16843728; // 0x10103d0
- field public static final int requiredForProfile = 16843775; // 0x10103ff
+ field public static final int requiredForProfile = 16843776; // 0x1010400
field public static final int requiresFadingEdge = 16843685; // 0x10103a5
field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
field public static final int resizeMode = 16843619; // 0x1010363
@@ -960,7 +961,7 @@
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
- field public static final int sharedElementName = 16843772; // 0x10103fc
+ field public static final int sharedElementName = 16843773; // 0x10103fd
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1137,7 +1138,7 @@
field public static final int tileMode = 16843265; // 0x1010201
field public static final int timeZone = 16843724; // 0x10103cc
field public static final int tint = 16843041; // 0x1010121
- field public static final int tintMode = 16843767; // 0x10103f7
+ field public static final int tintMode = 16843768; // 0x10103f8
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1159,11 +1160,11 @@
field public static final int transformPivotX = 16843552; // 0x1010320
field public static final int transformPivotY = 16843553; // 0x1010321
field public static final int transition = 16843743; // 0x10103df
- field public static final int transitionGroup = 16843773; // 0x10103fd
+ field public static final int transitionGroup = 16843774; // 0x10103fe
field public static final int transitionOrdering = 16843744; // 0x10103e0
field public static final int translationX = 16843554; // 0x1010322
field public static final int translationY = 16843555; // 0x1010323
- field public static final int translationZ = 16843766; // 0x10103f6
+ field public static final int translationZ = 16843767; // 0x10103f7
field public static final int type = 16843169; // 0x10101a1
field public static final int typeface = 16842902; // 0x1010096
field public static final int uiOptions = 16843672; // 0x1010398
@@ -1220,8 +1221,8 @@
field public static final int windowBackground = 16842836; // 0x1010054
field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
field public static final int windowContentOverlay = 16842841; // 0x1010059
- field public static final int windowContentTransitionManager = 16843765; // 0x10103f5
- field public static final int windowContentTransitions = 16843764; // 0x10103f4
+ field public static final int windowContentTransitionManager = 16843766; // 0x10103f6
+ field public static final int windowContentTransitions = 16843765; // 0x10103f5
field public static final int windowDisablePreview = 16843298; // 0x1010222
field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
field public static final int windowEnterAnimation = 16842932; // 0x10100b4
@@ -6848,6 +6849,7 @@
field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
+ field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 268959744; // 0x10080000
field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
field public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; // 0x10000
field public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; // 0x40000000
@@ -7417,6 +7419,7 @@
ctor public ComponentInfo();
ctor public ComponentInfo(android.content.pm.ComponentInfo);
ctor protected ComponentInfo(android.os.Parcel);
+ method public final int getBannerResource();
method public final int getIconResource();
method public final int getLogoResource();
method public boolean isEnabled();
@@ -7520,11 +7523,13 @@
ctor protected PackageItemInfo(android.os.Parcel);
method protected void dumpBack(android.util.Printer, java.lang.String);
method protected void dumpFront(android.util.Printer, java.lang.String);
+ method public android.graphics.drawable.Drawable loadBanner(android.content.pm.PackageManager);
method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
method public android.graphics.drawable.Drawable loadLogo(android.content.pm.PackageManager);
method public android.content.res.XmlResourceParser loadXmlMetaData(android.content.pm.PackageManager, java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
+ field public int banner;
field public int icon;
field public int labelRes;
field public int logo;
@@ -7552,12 +7557,16 @@
method public abstract void clearPackagePreferredActivities(java.lang.String);
method public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]);
method public abstract void extendVerificationTimeout(int, int, long);
+ method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
+ method public abstract android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
+ method public abstract android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract int getApplicationEnabledSetting(java.lang.String);
method public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
method public abstract android.graphics.drawable.Drawable getApplicationIcon(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -7637,6 +7646,7 @@
field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand";
field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen";
field public static final java.lang.String FEATURE_INPUT_METHODS = "android.software.input_methods";
+ field public static final java.lang.String FEATURE_LEANBACK = "android.software.leanback";
field public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper";
field public static final java.lang.String FEATURE_LOCATION = "android.hardware.location";
field public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
@@ -7660,7 +7670,7 @@
field public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony";
field public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
field public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
- field public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
+ field public static final deprecated java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
field public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
@@ -11286,6 +11296,7 @@
field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_AVAILABLE_MODES;
field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MAX_REGIONS;
field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE;
+ field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
field public static final android.hardware.camera2.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL;
field public static final android.hardware.camera2.CameraMetadata.Key JPEG_AVAILABLE_THUMBNAIL_SIZES;
field public static final android.hardware.camera2.CameraMetadata.Key LENS_FACING;
@@ -11326,6 +11337,7 @@
field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION;
field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+ field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
field public static final android.hardware.camera2.CameraMetadata.Key SYNC_MAX_LATENCY;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS;
@@ -11620,6 +11632,7 @@
field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+ field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
@@ -11657,7 +11670,6 @@
field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key FLASH_STATE;
- field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MAP;
field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
@@ -11694,6 +11706,8 @@
field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+ field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP;
+ field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_SCENE_FLICKER;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
@@ -25474,12 +25488,16 @@
method public void clearPackagePreferredActivities(java.lang.String);
method public java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]);
method public void extendVerificationTimeout(int, int, long);
+ method public android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
+ method public android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
+ method public android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int getApplicationEnabledSetting(java.lang.String);
method public android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
method public android.graphics.drawable.Drawable getApplicationIcon(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
diff --git a/api/removed.txt b/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/removed.txt
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 01e7615..92cb52c 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -114,6 +114,8 @@
" am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
" am stack list\n" +
" am stack info <STACK_ID>\n" +
+ " am lock-task <TASK_ID>\n" +
+ " am lock-task stop\n" +
"\n" +
"am start: start an Activity. Options are:\n" +
" -D: enable debugging\n" +
@@ -218,6 +220,8 @@
"\n" +
"am stack info: display the information about activity stack <STACK_ID>.\n" +
"\n" +
+ "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+ "\n" +
"<INTENT> specifications include these flags and arguments:\n" +
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
" [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -309,6 +313,8 @@
runStopUser();
} else if (op.equals("stack")) {
runStack();
+ } else if (op.equals("lock-task")) {
+ runLockTask();
} else {
showError("Error: unknown command '" + op + "'");
}
@@ -1641,4 +1647,19 @@
} catch (RemoteException e) {
}
}
+
+ private void runLockTask() throws Exception {
+ String taskIdStr = nextArgRequired();
+ try {
+ if (taskIdStr.equals("stop")) {
+ mAm.stopLockTaskMode();
+ } else {
+ int taskId = Integer.valueOf(taskIdStr);
+ mAm.startLockTaskMode(taskId);
+ }
+ System.err.println("Activity manager is " + (mAm.isInLockTaskMode() ? "" : "not ") +
+ "in lockTaskMode");
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 287c463..606d803 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5606,6 +5606,22 @@
}
}
+ /** @hide */
+ public void startLockTask() {
+ try {
+ ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /** @hide */
+ public void stopLockTask() {
+ try {
+ ActivityManagerNative.getDefault().stopLockTaskMode();
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Interface for informing a translucent {@link Activity} once all visible activities below it
* have completed drawing. This is necessary only after an {@link Activity} has been made
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 7f7616f..a2183e6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -155,6 +155,13 @@
public static final int START_SWITCHES_CANCELED = 4;
/**
+ * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
+ * while in Lock Task Mode.
+ * @hide
+ */
+ public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 5;
+
+ /**
* Flag for IActivityManaqer.startActivity: do special start mode where
* a new activity is launched only if it is needed.
* @hide
@@ -2232,4 +2239,35 @@
e.printStackTrace(pw);
}
}
+
+ /**
+ * @hide
+ */
+ public void startLockTaskMode(int taskId) {
+ try {
+ ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void stopLockTaskMode() {
+ try {
+ ActivityManagerNative.getDefault().stopLockTaskMode();
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean isInLockTaskMode() {
+ try {
+ return ActivityManagerNative.getDefault().isInLockTaskMode();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c7c81dd..373a8a3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2097,6 +2097,37 @@
reply.writeStrongBinder(homeActivityToken);
return true;
}
+
+ case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ final int taskId = data.readInt();
+ startLockTaskMode(taskId);
+ reply.writeNoException();
+ return true;
+ }
+
+ case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ startLockTaskMode(token);
+ reply.writeNoException();
+ return true;
+ }
+
+ case STOP_LOCK_TASK_MODE_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ stopLockTaskMode();
+ reply.writeNoException();
+ return true;
+ }
+
+ case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ final boolean isInLockTaskMode = isInLockTaskMode();
+ reply.writeNoException();
+ reply.writeInt(isInLockTaskMode ? 1 : 0);
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -4820,5 +4851,53 @@
return res;
}
+ @Override
+ public void startLockTaskMode(int taskId) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ @Override
+ public void startLockTaskMode(IBinder token) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ @Override
+ public void stopLockTaskMode() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ @Override
+ public boolean isInLockTaskMode() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean isInLockTaskMode = reply.readInt() == 1;
+ data.recycle();
+ reply.recycle();
+ return isInLockTaskMode;
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e71d47d..079cf7a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -878,7 +878,7 @@
}
/**
- * Like {@link #checkOp but instead of throwing a {@link SecurityException} it
+ * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
* returns {@link #MODE_ERRORED}.
*/
public int checkOpNoThrow(String op, int uid, String packageName) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 061e5a5..8165fa1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -727,6 +727,39 @@
}
@Override
+ public Drawable getActivityBanner(ComponentName activityName)
+ throws NameNotFoundException {
+ return getActivityInfo(activityName, 0).loadBanner(this);
+ }
+
+ @Override
+ public Drawable getActivityBanner(Intent intent)
+ throws NameNotFoundException {
+ if (intent.getComponent() != null) {
+ return getActivityBanner(intent.getComponent());
+ }
+
+ ResolveInfo info = resolveActivity(
+ intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (info != null) {
+ return info.activityInfo.loadBanner(this);
+ }
+
+ throw new NameNotFoundException(intent.toUri(0));
+ }
+
+ @Override
+ public Drawable getApplicationBanner(ApplicationInfo info) {
+ return info.loadBanner(this);
+ }
+
+ @Override
+ public Drawable getApplicationBanner(String packageName)
+ throws NameNotFoundException {
+ return getApplicationBanner(getApplicationInfo(packageName, 0));
+ }
+
+ @Override
public Drawable getActivityLogo(ComponentName activityName)
throws NameNotFoundException {
return getActivityInfo(activityName, 0).loadLogo(this);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index f2cabf4..cb06a42 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -424,6 +424,18 @@
public IBinder getHomeActivityToken() throws RemoteException;
+ /** @hide */
+ public void startLockTaskMode(int taskId) throws RemoteException;
+
+ /** @hide */
+ public void startLockTaskMode(IBinder token) throws RemoteException;
+
+ /** @hide */
+ public void stopLockTaskMode() throws RemoteException;
+
+ /** @hide */
+ public boolean isInLockTaskMode() throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -719,4 +731,8 @@
int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
+ int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
+ int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
+ int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
+ int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 96479e2..0175d62 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3457,7 +3457,16 @@
*/
public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
/**
- * <strong>Do not use this flag unless you are implementing your own
+ * This flag is used to create a new task and launch an activity into it.
+ * This flag is always paired with either {@link #FLAG_ACTIVITY_NEW_DOCUMENT}
+ * or {@link #FLAG_ACTIVITY_NEW_TASK}. In both cases these flags alone would
+ * search through existing tasks for ones matching this Intent. Only if no such
+ * task is found would a new task be created. When paired with
+ * FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip
+ * the search for a matching task and unconditionally start a new task.
+ *
+ * <strong>When used with {@link #FLAG_ACTIVITY_NEW_TASK} do not use this
+ * flag unless you are implementing your own
* top-level application launcher.</strong> Used in conjunction with
* {@link #FLAG_ACTIVITY_NEW_TASK} to disable the
* behavior of bringing an existing task to the foreground. When set,
@@ -3469,12 +3478,18 @@
* you should not use this flag unless you provide some way for a user to
* return back to the tasks you have launched.</strong>
*
- * <p>This flag is ignored if
- * {@link #FLAG_ACTIVITY_NEW_TASK} is not set.
+ * See {@link #FLAG_ACTIVITY_NEW_DOCUMENT} for details of this flag's use for
+ * creating new document tasks.
+ *
+ * <p>This flag is ignored if one of {@link #FLAG_ACTIVITY_NEW_TASK} or
+ * {@link #FLAG_ACTIVITY_NEW_TASK} is not also set.
*
* <p>See
* <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
* Stack</a> for more information about tasks.
+ *
+ * @see #FLAG_ACTIVITY_NEW_DOCUMENT
+ * @see #FLAG_ACTIVITY_NEW_TASK
*/
public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
/**
@@ -3581,6 +3596,34 @@
*/
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
/**
+ * This flag is used to break out "documents" into separate tasks that can
+ * be reached via the Recents mechanism. Such a document is any kind of
+ * item for which an application may want to maintain multiple simultaneous
+ * instances. Examples might be text files, web pages, spreadsheets, or
+ * emails. Each such document will be in a separate task in the Recents list.
+ *
+ * <p>When set, the activity specified by this Intent will launch into a
+ * separate task rooted at that activity. The activity launched must be
+ * defined with {@link android.R.attr#launchMode} "standard" or "singleTop".
+ *
+ * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without
+ * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will
+ * search for an existing task with a matching target activity and Intent
+ * data URI and relaunch that task, first finishing all activities down to
+ * the root activity and then calling the root activity's
+ * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing
+ * task's root activity matches the Intent's data URI then a new task will
+ * be launched with the target activity as root.
+ *
+ * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will
+ * always create a new task. Thus the same document may be made to appear
+ * more than one time in Recents.
+ *
+ * @see #FLAG_ACTIVITY_MULTIPLE_TASK
+ */
+ public static final int FLAG_ACTIVITY_NEW_DOCUMENT =
+ FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK;
+ /**
* If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
* callback from occurring on the current frontmost activity before it is
* paused as the newly-started activity is brought to the front.
@@ -6246,6 +6289,7 @@
* @see #FLAG_ACTIVITY_FORWARD_RESULT
* @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
* @see #FLAG_ACTIVITY_MULTIPLE_TASK
+ * @see #FLAG_ACTIVITY_NEW_DOCUMENT
* @see #FLAG_ACTIVITY_NEW_TASK
* @see #FLAG_ACTIVITY_NO_ANIMATION
* @see #FLAG_ACTIVITY_NO_HISTORY
@@ -7342,4 +7386,9 @@
String htmlText = htmlTexts != null ? htmlTexts.get(which) : null;
return new ClipData.Item(text, htmlText, null, uri);
}
+
+ /** @hide */
+ public boolean isDocument() {
+ return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT;
+ }
}
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 4dbcf23..7e8f285 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -128,6 +128,17 @@
return logo != 0 ? logo : applicationInfo.logo;
}
+ /**
+ * Return the banner resource identifier to use for this component. If the
+ * component defines a banner, that is used; else, the application banner is
+ * used.
+ *
+ * @return The banner associated with this component.
+ */
+ public final int getBannerResource() {
+ return banner != 0 ? banner : applicationInfo.banner;
+ }
+
protected void dumpFront(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
pw.println(prefix + "enabled=" + enabled + " exported=" + exported
@@ -175,6 +186,13 @@
/**
* @hide
*/
+ @Override protected Drawable loadDefaultBanner(PackageManager pm) {
+ return applicationInfo.loadBanner(pm);
+ }
+
+ /**
+ * @hide
+ */
@Override
protected Drawable loadDefaultLogo(PackageManager pm) {
return applicationInfo.loadLogo(pm);
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index a67326e..58f1c84 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -68,6 +68,12 @@
/**
* A drawable resource identifier (in the package's resources) of this
+ * component's banner. From the "banner" attribute or, if not set, 0.
+ */
+ public int banner;
+
+ /**
+ * A drawable resource identifier (in the package's resources) of this
* component's logo. Logos may be larger/wider than icons and are
* displayed by certain UI elements in place of a name or name/icon
* combination. From the "logo" attribute or, if not set, 0.
@@ -92,6 +98,7 @@
nonLocalizedLabel = orig.nonLocalizedLabel;
if (nonLocalizedLabel != null) nonLocalizedLabel = nonLocalizedLabel.toString().trim();
icon = orig.icon;
+ banner = orig.banner;
logo = orig.logo;
metaData = orig.metaData;
}
@@ -146,6 +153,27 @@
}
/**
+ * Retrieve the current graphical banner associated with this item. This
+ * will call back on the given PackageManager to load the banner from
+ * the application.
+ *
+ * @param pm A PackageManager from which the banner can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's banner. If the item
+ * does not have a banner, this method will return null.
+ */
+ public Drawable loadBanner(PackageManager pm) {
+ if (banner != 0) {
+ Drawable dr = pm.getDrawable(packageName, banner, getApplicationInfo());
+ if (dr != null) {
+ return dr;
+ }
+ }
+ return loadDefaultBanner(pm);
+ }
+
+ /**
* Retrieve the default graphical icon associated with this item.
*
* @param pm A PackageManager from which the icon can be loaded; usually
@@ -159,7 +187,22 @@
protected Drawable loadDefaultIcon(PackageManager pm) {
return pm.getDefaultActivityIcon();
}
-
+
+ /**
+ * Retrieve the default graphical banner associated with this item.
+ *
+ * @param pm A PackageManager from which the banner can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's default banner
+ * or null if no default logo is available.
+ *
+ * @hide
+ */
+ protected Drawable loadDefaultBanner(PackageManager pm) {
+ return null;
+ }
+
/**
* Retrieve the current graphical logo associated with this item. This
* will call back on the given PackageManager to load the logo from
@@ -224,10 +267,11 @@
pw.println(prefix + "name=" + name);
}
pw.println(prefix + "packageName=" + packageName);
- if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) {
+ if (labelRes != 0 || nonLocalizedLabel != null || icon != 0 || banner != 0) {
pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
+ " nonLocalizedLabel=" + nonLocalizedLabel
- + " icon=0x" + Integer.toHexString(icon));
+ + " icon=0x" + Integer.toHexString(icon)
+ + " banner=0x" + Integer.toHexString(banner));
}
}
@@ -243,6 +287,7 @@
dest.writeInt(icon);
dest.writeInt(logo);
dest.writeBundle(metaData);
+ dest.writeInt(banner);
}
protected PackageItemInfo(Parcel source) {
@@ -254,6 +299,7 @@
icon = source.readInt();
logo = source.readInt();
metaData = source.readBundle();
+ banner = source.readInt();
}
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b648930..e86833b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1233,6 +1233,26 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports leanback UI. This is
+ * typically used in a living room television experience, but is a software
+ * feature unlike {@link #FEATURE_TELEVISION}. Devices running with this
+ * feature will use resources associated with the "television" UI mode.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_LEANBACK = "android.software.leanback";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports only leanback UI. Only
+ * applications designed for this experience should be run, though this is
+ * not enforced by the system.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports WiFi (802.11) networking.
*/
@SdkConstant(SdkConstantType.FEATURE)
@@ -1252,6 +1272,7 @@
* room television experience: displayed on a big screen, where the user
* is sitting far away from it, and the dominant form of input will be
* something like a DPAD, not through touch or mouse.
+ * @deprecated use {@link #FEATURE_LEANBACK} instead.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_TELEVISION = "android.hardware.type.television";
@@ -2400,9 +2421,43 @@
throws NameNotFoundException;
/**
+ * Retrieve the banner associated with an activity. Given the full name of
+ * an activity, retrieves the information about it and calls
+ * {@link ComponentInfo#loadIcon ComponentInfo.loadIcon()} to return its
+ * banner. If the activity cannot be found, NameNotFoundException is thrown.
+ *
+ * @param activityName Name of the activity whose banner is to be retrieved.
+ * @return Returns the image of the banner, or null if the activity has no
+ * banner specified.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * activity could not be loaded.
+ * @see #getActivityBanner(Intent)
+ */
+ public abstract Drawable getActivityBanner(ComponentName activityName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the banner associated with an Intent. If intent.getClassName()
+ * is set, this simply returns the result of
+ * getActivityBanner(intent.getClassName()). Otherwise it resolves the
+ * intent's component and returns the banner associated with the resolved
+ * component. If intent.getClassName() cannot be found or the Intent cannot
+ * be resolved to a component, NameNotFoundException is thrown.
+ *
+ * @param intent The intent for which you would like to retrieve a banner.
+ * @return Returns the image of the banner, or null if the activity has no
+ * banner specified.
+ * @throws NameNotFoundException Thrown if the resources for application
+ * matching the given intent could not be loaded.
+ * @see #getActivityBanner(ComponentName)
+ */
+ public abstract Drawable getActivityBanner(Intent intent)
+ throws NameNotFoundException;
+
+ /**
* Return the generic icon for an activity that is used when no specific
* icon is defined.
- *
+ *
* @return Drawable Image of the icon.
*/
public abstract Drawable getDefaultActivityIcon();
@@ -2440,19 +2495,43 @@
throws NameNotFoundException;
/**
- * Retrieve the logo associated with an activity. Given the full name of
- * an activity, retrieves the information about it and calls
- * {@link ComponentInfo#loadLogo ComponentInfo.loadLogo()} to return its logo.
- * If the activity cannot be found, NameNotFoundException is thrown.
+ * Retrieve the banner associated with an application.
+ *
+ * @param info Information about application being queried.
+ * @return Returns the image of the banner or null if the application has no
+ * banner specified.
+ * @see #getApplicationBanner(String)
+ */
+ public abstract Drawable getApplicationBanner(ApplicationInfo info);
+
+ /**
+ * Retrieve the banner associated with an application. Given the name of the
+ * application's package, retrieves the information about it and calls
+ * getApplicationIcon() to return its banner. If the application cannot be
+ * found, NameNotFoundException is thrown.
+ *
+ * @param packageName Name of the package whose application banner is to be
+ * retrieved.
+ * @return Returns the image of the banner or null if the application has no
+ * banner specified.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded.
+ * @see #getApplicationBanner(ApplicationInfo)
+ */
+ public abstract Drawable getApplicationBanner(String packageName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the logo associated with an activity. Given the full name of an
+ * activity, retrieves the information about it and calls
+ * {@link ComponentInfo#loadLogo ComponentInfo.loadLogo()} to return its
+ * logo. If the activity cannot be found, NameNotFoundException is thrown.
*
* @param activityName Name of the activity whose logo is to be retrieved.
- *
- * @return Returns the image of the logo or null if the activity has no
- * logo specified.
- *
+ * @return Returns the image of the logo or null if the activity has no logo
+ * specified.
* @throws NameNotFoundException Thrown if the resources for the given
- * activity could not be loaded.
- *
+ * activity could not be loaded.
* @see #getActivityLogo(Intent)
*/
public abstract Drawable getActivityLogo(ComponentName activityName)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c222003..f76aada 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -167,18 +167,20 @@
final int labelRes;
final int iconRes;
final int logoRes;
+ final int bannerRes;
String tag;
TypedArray sa;
ParsePackageItemArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes, int _logoRes) {
+ int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes) {
owner = _owner;
outError = _outError;
nameRes = _nameRes;
labelRes = _labelRes;
iconRes = _iconRes;
logoRes = _logoRes;
+ bannerRes = _bannerRes;
}
}
@@ -190,10 +192,10 @@
int flags;
ParseComponentArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes, int _logoRes,
+ int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes,
String[] _sepProcesses, int _processRes,
int _descriptionRes, int _enabledRes) {
- super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes);
+ super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes, _bannerRes);
sepProcesses = _sepProcesses;
processRes = _processRes;
descriptionRes = _descriptionRes;
@@ -1688,7 +1690,8 @@
com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo)) {
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_banner)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1731,7 +1734,8 @@
com.android.internal.R.styleable.AndroidManifestPermission_name,
com.android.internal.R.styleable.AndroidManifestPermission_label,
com.android.internal.R.styleable.AndroidManifestPermission_icon,
- com.android.internal.R.styleable.AndroidManifestPermission_logo)) {
+ com.android.internal.R.styleable.AndroidManifestPermission_logo,
+ com.android.internal.R.styleable.AndroidManifestPermission_banner)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1800,7 +1804,8 @@
com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
com.android.internal.R.styleable.AndroidManifestPermissionTree_icon,
- com.android.internal.R.styleable.AndroidManifestPermissionTree_logo)) {
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_logo,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_banner)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1845,7 +1850,8 @@
com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
com.android.internal.R.styleable.AndroidManifestInstrumentation_icon,
- com.android.internal.R.styleable.AndroidManifestInstrumentation_logo);
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_logo,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_banner);
mParseInstrumentationArgs.tag = "<instrumentation>";
}
@@ -1961,6 +1967,8 @@
com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
ai.logo = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
+ ai.banner = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestApplication_banner, 0);
ai.theme = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
ai.descriptionRes = sa.getResourceId(
@@ -2256,7 +2264,7 @@
private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
String[] outError, String tag, TypedArray sa,
- int nameRes, int labelRes, int iconRes, int logoRes) {
+ int nameRes, int labelRes, int iconRes, int logoRes, int bannerRes) {
String name = sa.getNonConfigurationString(nameRes, 0);
if (name == null) {
outError[0] = tag + " does not specify android:name";
@@ -2280,6 +2288,11 @@
outInfo.logo = logoVal;
}
+ int bannerVal = sa.getResourceId(bannerRes, 0);
+ if (bannerVal != 0) {
+ outInfo.banner = bannerVal;
+ }
+
TypedValue v = sa.peekValue(labelRes);
if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
outInfo.nonLocalizedLabel = v.coerceToString();
@@ -2303,6 +2316,7 @@
com.android.internal.R.styleable.AndroidManifestActivity_label,
com.android.internal.R.styleable.AndroidManifestActivity_icon,
com.android.internal.R.styleable.AndroidManifestActivity_logo,
+ com.android.internal.R.styleable.AndroidManifestActivity_banner,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestActivity_process,
com.android.internal.R.styleable.AndroidManifestActivity_description,
@@ -2588,6 +2602,7 @@
com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
com.android.internal.R.styleable.AndroidManifestActivityAlias_logo,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_banner,
mSeparateProcesses,
0,
com.android.internal.R.styleable.AndroidManifestActivityAlias_description,
@@ -2622,6 +2637,7 @@
info.flags = target.info.flags;
info.icon = target.info.icon;
info.logo = target.info.logo;
+ info.banner = target.info.banner;
info.labelRes = target.info.labelRes;
info.nonLocalizedLabel = target.info.nonLocalizedLabel;
info.launchMode = target.info.launchMode;
@@ -2735,6 +2751,7 @@
com.android.internal.R.styleable.AndroidManifestProvider_label,
com.android.internal.R.styleable.AndroidManifestProvider_icon,
com.android.internal.R.styleable.AndroidManifestProvider_logo,
+ com.android.internal.R.styleable.AndroidManifestProvider_banner,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestProvider_process,
com.android.internal.R.styleable.AndroidManifestProvider_description,
@@ -3041,6 +3058,7 @@
com.android.internal.R.styleable.AndroidManifestService_label,
com.android.internal.R.styleable.AndroidManifestService_icon,
com.android.internal.R.styleable.AndroidManifestService_logo,
+ com.android.internal.R.styleable.AndroidManifestService_banner,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestService_process,
com.android.internal.R.styleable.AndroidManifestService_description,
@@ -3338,6 +3356,9 @@
outInfo.logo = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);
+ outInfo.banner = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_banner, 0);
+
sa.recycle();
int outerDepth = parser.getDepth();
@@ -3707,6 +3728,11 @@
outInfo.logo = logoVal;
}
+ int bannerVal = args.sa.getResourceId(args.bannerRes, 0);
+ if (bannerVal != 0) {
+ outInfo.banner = bannerVal;
+ }
+
TypedValue v = args.sa.peekValue(args.labelRes);
if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
outInfo.nonLocalizedLabel = v.coerceToString();
@@ -4131,6 +4157,7 @@
public CharSequence nonLocalizedLabel;
public int icon;
public int logo;
+ public int banner;
public int preferred;
}
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 875e8de..4a743a5 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -140,12 +140,33 @@
mContext.registerReceiver(mExternalReceiver, sdFilter);
}
+ private final void handlePackageEvent(Intent intent, int userId) {
+ // Don't regenerate the services map when the package is removed or its
+ // ASEC container unmounted as a step in replacement. The subsequent
+ // _ADDED / _AVAILABLE call will regenerate the map in the final state.
+ final String action = intent.getAction();
+ // it's a new-component action if it isn't some sort of removal
+ final boolean isRemoval = Intent.ACTION_PACKAGE_REMOVED.equals(action)
+ || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action);
+ // if it's a removal, is it part of an update-in-place step?
+ final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+ if (isRemoval && replacing) {
+ // package is going away, but it's the middle of an upgrade: keep the current
+ // state and do nothing here. This clause is intentionally empty.
+ } else {
+ // either we're adding/changing, or it's a removal without replacement, so
+ // we need to recalculate the set of available services
+ generateServicesMap(userId);
+ }
+ }
+
private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
if (uid != -1) {
- generateServicesMap(UserHandle.getUserId(uid));
+ handlePackageEvent(intent, UserHandle.getUserId(uid));
}
}
};
@@ -154,7 +175,7 @@
@Override
public void onReceive(Context context, Intent intent) {
// External apps can't coexist with multi-user, so scan owner
- generateServicesMap(UserHandle.USER_OWNER);
+ handlePackageEvent(intent, UserHandle.USER_OWNER);
}
};
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 542af6a..4c50dda 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -61,4 +61,12 @@
int removeListener(ICameraServiceListener listener);
int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
+
+ /**
+ * The java stubs for this method are not intended to be used. Please use
+ * the native stub in frameworks/av/include/camera/ICameraService.h instead.
+ * The BinderHolder output is being used as a placeholder, and will not be
+ * well-formatted in the generated java method.
+ */
+ int getCameraVendorTagDescriptor(out BinderHolder desc);
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index d27485b..4c04caa 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -148,7 +148,7 @@
* <p>All camera devices support ON, and all camera devices with
* flash units support ON_AUTO_FLASH and
* ON_ALWAYS_FLASH.</p>
- * <p>Full-capability camera devices always support OFF mode,
+ * <p>FULL mode camera devices always support OFF mode,
* which enables application control of camera exposure time,
* sensitivity, and frame duration.</p>
*
@@ -244,7 +244,7 @@
* given camera device. This entry lists the valid modes for
* {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} for this camera device.</p>
* <p>All camera devices will support ON mode.</p>
- * <p>Full-capability camera devices will always support OFF mode,
+ * <p>FULL mode camera devices will always support OFF mode,
* which enables application control of white balance, by using
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}({@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} must be set to TRANSFORM_MATRIX).</p>
*
@@ -280,6 +280,17 @@
new Key<Boolean>("android.flash.info.available", boolean.class);
/**
+ * <p>The set of hot pixel correction modes that are supported by this
+ * camera device.</p>
+ * <p>This tag lists valid modes for {@link CaptureRequest#HOT_PIXEL_MODE android.hotPixel.mode}.</p>
+ * <p>FULL mode camera devices will always support FAST.</p>
+ *
+ * @see CaptureRequest#HOT_PIXEL_MODE
+ */
+ public static final Key<byte[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
+ new Key<byte[]>("android.hotPixel.availableHotPixelModes", byte[].class);
+
+ /**
* <p>Supported resolutions for the JPEG thumbnail</p>
* <p>Below condiditions will be satisfied for this size list:</p>
* <ul>
@@ -1088,6 +1099,18 @@
new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
/**
+ * <p>The set of hot pixel map output modes supported by this camera device.</p>
+ * <p>This tag lists valid output modes for {@link CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE android.statistics.hotPixelMapMode}.</p>
+ * <p>If no hotpixel map is available for this camera device, this will contain
+ * only OFF. If the hotpixel map is available, this should include both
+ * the ON and OFF options.</p>
+ *
+ * @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
+ */
+ public static final Key<boolean[]> STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =
+ new Key<boolean[]>("android.statistics.info.availableHotPixelMapModes", boolean[].class);
+
+ /**
* <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>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 2ac50e4..78e7037 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -48,6 +48,8 @@
*/
public final class CameraManager {
+ private static final String TAG = "CameraManager";
+
/**
* This should match the ICameraService definition
*/
@@ -79,6 +81,19 @@
mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw);
try {
+ int err = CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor();
+ if (err == CameraBinderDecorator.EOPNOTSUPP) {
+ Log.w(TAG, "HAL version doesn't vendor tags.");
+ } else {
+ CameraBinderDecorator.throwOnError(CameraMetadataNative.
+ nativeSetupGlobalVendorTagDescriptor());
+ }
+ } catch(CameraRuntimeException e) {
+ throw new IllegalStateException("Failed to setup camera vendor tags",
+ e.asChecked());
+ }
+
+ try {
mCameraService.addListener(new CameraServiceListener());
} catch(CameraRuntimeException e) {
throw new IllegalStateException("Failed to register a camera service listener",
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index a62df0f..a3fbfbe 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1199,7 +1199,10 @@
/**
* <p>The frame rate must not be reduced relative to sensor raw output
* for this option.</p>
- * <p>No hot pixel correction is applied.</p>
+ * <p>No hot pixel correction is applied.
+ * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ *
+ * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
*/
public static final int HOT_PIXEL_MODE_OFF = 0;
@@ -1207,7 +1210,10 @@
/**
* <p>The frame rate must not be reduced relative to sensor raw output
* for this option.</p>
- * <p>Hot pixel correction is applied.</p>
+ * <p>Hot pixel correction is applied.
+ * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ *
+ * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
*/
public static final int HOT_PIXEL_MODE_FAST = 1;
@@ -1215,7 +1221,10 @@
/**
* <p>The frame rate may be reduced relative to sensor raw output
* for this option.</p>
- * <p>A high-quality hot pixel correction is applied.</p>
+ * <p>A high-quality hot pixel correction is applied.
+ * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ *
+ * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
*/
public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a8caba0..fbac529 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -876,9 +876,13 @@
/**
* <p>Set operational mode for hot pixel correction.</p>
+ * <p>Valid modes for this camera device are listed in
+ * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
* <p>Hotpixel correction interpolates out, or otherwise removes, pixels
* that do not accurately encode the incoming light (i.e. pixels that
* are stuck at an arbitrary value).</p>
+ *
+ * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
* @see #HOT_PIXEL_MODE_OFF
* @see #HOT_PIXEL_MODE_FAST
* @see #HOT_PIXEL_MODE_HIGH_QUALITY
@@ -1286,6 +1290,18 @@
new Key<Integer>("android.statistics.faceDetectMode", int.class);
/**
+ * <p>Operating mode for hotpixel map generation.</p>
+ * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+ * If set to OFF, no hotpixel map should be returned.</p>
+ * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+ *
+ * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+ * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+ */
+ public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+ new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+ /**
* <p>Whether the camera device will output the lens
* shading map in output result metadata.</p>
* <p>When set to ON,
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 0f2c7f7..ab1525e 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1166,24 +1166,14 @@
new Key<Integer>("android.flash.state", int.class);
/**
- * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the
- * sensor, where <code>(x, y)</code> lies between <code>(0, 0)</code>, which is the top-left
- * of the pixel array, and the width,height of the pixel array given in
- * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}. This may include hot pixels
- * that lie outside of the active array bounds given by
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
- *
- * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
- * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
- */
- public static final Key<int[]> HOT_PIXEL_MAP =
- new Key<int[]>("android.hotPixel.map", int[].class);
-
- /**
* <p>Set operational mode for hot pixel correction.</p>
+ * <p>Valid modes for this camera device are listed in
+ * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
* <p>Hotpixel correction interpolates out, or otherwise removes, pixels
* that do not accurately encode the incoming light (i.e. pixels that
* are stuck at an arbitrary value).</p>
+ *
+ * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
* @see #HOT_PIXEL_MODE_OFF
* @see #HOT_PIXEL_MODE_FAST
* @see #HOT_PIXEL_MODE_HIGH_QUALITY
@@ -1971,6 +1961,33 @@
new Key<Integer>("android.statistics.sceneFlicker", int.class);
/**
+ * <p>Operating mode for hotpixel map generation.</p>
+ * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+ * If set to OFF, no hotpixel map should be returned.</p>
+ * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+ *
+ * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+ * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+ */
+ public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+ new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+ /**
+ * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the sensor.</p>
+ * <p>A coordinate <code>(x, y)</code> must lie between <code>(0, 0)</code>, and
+ * <code>(width - 1, height - 1)</code> (inclusive), which are the top-left and
+ * bottom-right of the pixel array, respectively. The width and
+ * height dimensions are given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.
+ * This may include hot pixels that lie outside of the active array
+ * bounds given by {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ *
+ * @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);
+
+ /**
* <p>Tonemapping / contrast / gamma curve for the blue
* channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* CONTRAST_CURVE.</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 2ddcb14..0d4a4cb 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -105,6 +105,18 @@
}
/**
+ * Set the global client-side vendor tag descriptor to allow use of vendor
+ * tags in camera applications.
+ *
+ * @return int A native status_t value corresponding to one of the
+ * {@link CameraBinderDecorator} integer constants.
+ * @see CameraBinderDecorator#throwOnError
+ *
+ * @hide
+ */
+ public static native int nativeSetupGlobalVendorTagDescriptor();
+
+ /**
* Set a camera metadata field to a value. The field definitions can be
* found in {@link CameraCharacteristics}, {@link CaptureResult}, and
* {@link CaptureRequest}.
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index e535e00..328ccbe 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -64,47 +64,7 @@
// int return type => status_t => convert to exception
if (m.getReturnType() == Integer.TYPE) {
int returnValue = (Integer) result;
-
- switch (returnValue) {
- case NO_ERROR:
- return;
- case PERMISSION_DENIED:
- throw new SecurityException("Lacking privileges to access camera service");
- case ALREADY_EXISTS:
- // This should be handled at the call site. Typically this isn't bad,
- // just means we tried to do an operation that already completed.
- return;
- case BAD_VALUE:
- throw new IllegalArgumentException("Bad argument passed to camera service");
- case DEAD_OBJECT:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- CAMERA_DISCONNECTED));
- case EACCES:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- CAMERA_DISABLED));
- case EBUSY:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- CAMERA_IN_USE));
- case EUSERS:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- MAX_CAMERAS_IN_USE));
- case ENODEV:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- CAMERA_DISCONNECTED));
- case EOPNOTSUPP:
- UncheckedThrow.throwAnyException(new CameraRuntimeException(
- CAMERA_DEPRECATED_HAL));
- }
-
- /**
- * Trap the rest of the negative return values. If we have known
- * error codes i.e. ALREADY_EXISTS that aren't really runtime
- * errors, then add them to the top switch statement
- */
- if (returnValue < 0) {
- throw new UnsupportedOperationException(String.format("Unknown error %d",
- returnValue));
- }
+ throwOnError(returnValue);
}
}
@@ -131,6 +91,54 @@
}
/**
+ * Throw error codes returned by the camera service as exceptions.
+ *
+ * @param errorFlag error to throw as an exception.
+ */
+ public static void throwOnError(int errorFlag) {
+ switch (errorFlag) {
+ case NO_ERROR:
+ return;
+ case PERMISSION_DENIED:
+ throw new SecurityException("Lacking privileges to access camera service");
+ case ALREADY_EXISTS:
+ // This should be handled at the call site. Typically this isn't bad,
+ // just means we tried to do an operation that already completed.
+ return;
+ case BAD_VALUE:
+ throw new IllegalArgumentException("Bad argument passed to camera service");
+ case DEAD_OBJECT:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ CAMERA_DISCONNECTED));
+ case EACCES:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ CAMERA_DISABLED));
+ case EBUSY:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ CAMERA_IN_USE));
+ case EUSERS:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ MAX_CAMERAS_IN_USE));
+ case ENODEV:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ CAMERA_DISCONNECTED));
+ case EOPNOTSUPP:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ CAMERA_DEPRECATED_HAL));
+ }
+
+ /**
+ * Trap the rest of the negative return values. If we have known
+ * error codes i.e. ALREADY_EXISTS that aren't really runtime
+ * errors, then add them to the top switch statement
+ */
+ if (errorFlag < 0) {
+ throw new UnsupportedOperationException(String.format("Unknown error %d",
+ errorFlag));
+ }
+ }
+
+ /**
* <p>
* Wraps the type T with a proxy that will check 'status_t' return codes
* from the native side of the camera service, and throw Java exceptions
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java
index b615600..806a89d8 100644
--- a/core/java/android/print/PrinterCapabilitiesInfo.java
+++ b/core/java/android/print/PrinterCapabilitiesInfo.java
@@ -475,6 +475,12 @@
* @param colorModes The color mode bit mask.
* @param defaultColorMode The default color mode.
* @return This builder.
+ * <p>
+ * <strong>Note:</strong> On platform version 19 (Kitkat) specifying
+ * only PrintAttributes#COLOR_MODE_MONOCHROME leads to a print spooler
+ * crash. Hence, you should declare either both color modes or
+ * PrintAttributes#COLOR_MODE_COLOR.
+ * </p>
*
* @throws IllegalArgumentException If color modes contains an invalid
* mode bit or if the default color mode is invalid.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d72f810..7a58d06 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13953,7 +13953,8 @@
* @return A new or reused DisplayList object.
*/
private DisplayList getDisplayList(DisplayList displayList, boolean isLayer) {
- if (!canHaveDisplayList()) {
+ final HardwareRenderer renderer = getHardwareRenderer();
+ if (renderer == null || !canHaveDisplayList()) {
return null;
}
@@ -14032,13 +14033,21 @@
}
}
} finally {
- displayList.end(getHardwareRenderer(), canvas);
+ displayList.end(renderer, canvas);
displayList.setCaching(caching);
if (isLayer) {
displayList.setLeftTopRightBottom(0, 0, width, height);
} else {
setDisplayListProperties(displayList);
}
+
+ if (renderer != getHardwareRenderer()) {
+ Log.w(VIEW_LOG_TAG, "View was detached during a draw() call!");
+ // TODO: Should this be elevated to a crash?
+ // For now have it behaves the same as it previously did, it
+ // will result in the DisplayListData being destroyed later
+ // than it could be but oh well...
+ }
}
} else if (!isLayer) {
mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 10fd2f0..26d7f5f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -270,7 +270,6 @@
boolean mWifiOn;
StopwatchTimer mWifiOnTimer;
- int mWifiOnUid = -1;
boolean mGlobalWifiRunning;
StopwatchTimer mGlobalWifiRunningTimer;
@@ -2912,10 +2911,6 @@
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtime);
}
- if (mWifiOnUid >= 0) {
- getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked(elapsedRealtime);
- mWifiOnUid = -1;
- }
}
public void noteAudioOnLocked(int uid) {
@@ -5973,7 +5968,7 @@
if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
- final Uid u = getUidStatsLocked(entry.uid);
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
@@ -6040,7 +6035,7 @@
if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
- final Uid u = getUidStatsLocked(entry.uid);
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
@@ -6240,6 +6235,7 @@
* if needed.
*/
public Uid.Proc getProcessStatsLocked(int uid, String name) {
+ uid = mapUid(uid);
Uid u = getUidStatsLocked(uid);
return u.getProcessStatsLocked(name);
}
@@ -6249,6 +6245,7 @@
* if needed.
*/
public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
+ uid = mapUid(uid);
Uid u = getUidStatsLocked(uid);
return u.getPackageStatsLocked(pkg);
}
@@ -6258,6 +6255,7 @@
* if needed.
*/
public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
+ uid = mapUid(uid);
Uid u = getUidStatsLocked(uid);
return u.getServiceStatsLocked(pkg, name);
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 94c3f44..d8cf18e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -435,6 +435,14 @@
* Various arguments, most determined by system properties, are passed in.
* The "mOptions" vector is updated.
*
+ * CAUTION: when adding options in here, be careful not to put the
+ * char buffer inside a nested scope. Adding the buffer to the
+ * options using mOptions.add() does not copy the buffer, so if the
+ * buffer goes out of scope the option may be overwritten. It's best
+ * to put the buffer at the top of the function so that it is more
+ * unlikely that someone will surround it in a scope at a later time
+ * and thus introduce a bug.
+ *
* Returns 0 on success.
*/
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
@@ -469,7 +477,15 @@
kEMIntFast,
kEMJitCompiler,
} executionMode = kEMDefault;
-
+ char profile_period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
+ char profile_duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
+ char profile_interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
+ char profile_backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
+ char langOption[sizeof("-Duser.language=") + 3];
+ char regionOption[sizeof("-Duser.region=") + 3];
+ char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
+ char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
+ char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
property_get("dalvik.vm.checkjni", propBuf, "");
if (strcmp(propBuf, "true") == 0) {
@@ -670,7 +686,6 @@
//mOptions.add(opt);
}
- char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
property_get("dalvik.vm.lockprof.threshold", propBuf, "");
if (strlen(propBuf) > 0) {
strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");
@@ -680,7 +695,6 @@
}
/* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */
- char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
property_get("dalvik.vm.jit.op", propBuf, "");
if (strlen(propBuf) > 0) {
strcpy(jitOpBuf, "-Xjitop:");
@@ -690,7 +704,6 @@
}
/* Force interpreter-only mode for selected methods */
- char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
property_get("dalvik.vm.jit.method", propBuf, "");
if (strlen(propBuf) > 0) {
strcpy(jitMethodBuf, "-Xjitmethod:");
@@ -770,8 +783,6 @@
/* Set the properties for locale */
{
- char langOption[sizeof("-Duser.language=") + 3];
- char regionOption[sizeof("-Duser.region=") + 3];
strcpy(langOption, "-Duser.language=");
strcpy(regionOption, "-Duser.region=");
readLocale(langOption, regionOption);
@@ -786,35 +797,30 @@
* Set profiler options
*/
if (libart) {
- char period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
- char duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
- char interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
- char backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
-
// Number of seconds during profile runs.
- strcpy(period, "-Xprofile-period:");
- property_get("dalvik.vm.profile.period_secs", period+17, "10");
- opt.optionString = period;
+ strcpy(profile_period, "-Xprofile-period:");
+ property_get("dalvik.vm.profile.period_secs", profile_period+17, "10");
+ opt.optionString = profile_period;
mOptions.add(opt);
// Length of each profile run (seconds).
- strcpy(duration, "-Xprofile-duration:");
- property_get("dalvik.vm.profile.duration_secs", duration+19, "30");
- opt.optionString = duration;
+ strcpy(profile_duration, "-Xprofile-duration:");
+ property_get("dalvik.vm.profile.duration_secs", profile_duration+19, "30");
+ opt.optionString = profile_duration;
mOptions.add(opt);
// Polling interval during profile run (microseconds).
- strcpy(interval, "-Xprofile-interval:");
- property_get("dalvik.vm.profile.interval_us", interval+19, "10000");
- opt.optionString = interval;
+ strcpy(profile_interval, "-Xprofile-interval:");
+ property_get("dalvik.vm.profile.interval_us", profile_interval+19, "10000");
+ opt.optionString = profile_interval;
mOptions.add(opt);
// Coefficient for period backoff. The the period is multiplied
// by this value after each profile run.
- strcpy(backoff, "-Xprofile-backoff:");
- property_get("dalvik.vm.profile.backoff_coeff", backoff+18, "2.0");
- opt.optionString = backoff;
+ strcpy(profile_backoff, "-Xprofile-backoff:");
+ property_get("dalvik.vm.profile.backoff_coeff", profile_backoff+18, "2.0");
+ opt.optionString = profile_backoff;
mOptions.add(opt);
}
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 3c7da1e..8c15ac25 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -19,13 +19,18 @@
// #define LOG_NNDEBUG 0
#define LOG_TAG "CameraMetadata-JNI"
#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <string.h>
#include "jni.h"
#include "JNIHelp.h"
#include "android_os_Parcel.h"
#include "android_runtime/AndroidRuntime.h"
+#include <binder/IServiceManager.h>
#include <camera/CameraMetadata.h>
+#include <camera/ICameraService.h>
+#include <camera/VendorTagDescriptor.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -112,6 +117,7 @@
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
@@ -372,6 +378,9 @@
{ "nativeGetTypeFromTag",
"(I)I",
(void *)CameraMetadata_getTypeFromTag },
+ { "nativeSetupGlobalVendorTagDescriptor",
+ "()I",
+ (void*)CameraMetadata_setupGlobalVendorTagDescriptor },
// instance methods
{ "nativeAllocate",
"()J",
@@ -556,4 +565,29 @@
return tagType;
}
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
+ const String16 NAME("media.camera");
+ sp<ICameraService> cameraService;
+ status_t err = getService(NAME, /*out*/&cameraService);
+
+ if (err != OK) {
+ ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
+ strerror(-err), err);
+ return err;
+ }
+
+ sp<VendorTagDescriptor> desc;
+ err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
+
+ if (err != OK) {
+ ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)", __FUNCTION__,
+ strerror(-err), err);
+ return err;
+ }
+
+ err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+
+ return err;
+}
+
} // extern "C"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0b9ac7f..5cb5709 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Laat die houer toe om die opstellingsprogram wat deur die diensverskaffer voorsien word, op te roep. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"luister vir waarnemings oor netwerktoestande"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Laat \'n program luister vir waarnemings oor netwerktoestande. Behoort nooit nodig te wees vir normale programme nie."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"verander invoertoestelkalibrasie"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Laat die program toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale programme nodig te wees nie."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5701852..5c9a212 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ያዢው በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን እንዲጠራው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን ያዳምጣል"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"አንድ መተግበሪያ በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን እንዲያዳምጥ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አስፈላጊ ሊሆን አይገባም።"</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"የግቤት መሣሪያ ማስተካከያ ቀይር"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"መተግበሪያው የማያ ንካ የማስተካከያ ልኬቶቹን እንዲቀይር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 798ea7a..dfac282 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"الاستماع إلى ملاحظات حول أحوال الشبكة"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f76ad7f..79ba8e6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Разрешава на притежателя да извиква предоставеното от оператора приложение за конфигуриране. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"слушане за наблюдения на мрежовите условия"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Разрешава на приложението да слуша за наблюдения на мрежовите условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index dc8128a..682e0ea 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet que el titular invoqui l\'aplicació de configuració proporcionada per l\'operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"conèixer les observacions sobre les condicions de la xarxa"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet que una aplicació conegui les observacions sobre les condicions de la xarxa. No s\'ha de necessitar mai per a aplicacions normals."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"canviar el calibratge del dispositiu d\'entrada"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet que l\'aplicació modifiqui els paràmetres de calibratge de la pantalla tàctil. S\'ha de procurar no fer servir mai aquesta opció per a les aplicacions normals."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Controlar intents de desbloqueig de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9745cdc..37e228c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje vyvolání konfigurační aplikace poskytnuté operátorem. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"naslouchat informacím o stavu sítě"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikaci naslouchat informacím o stavu sítě. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"měnit kalibraci vstupního zařízení"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikaci měnit parametry kalibrace dotykové obrazovky. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ca12213..dd7b352 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Tillader, at brugeren aktiverer konfigurationsappen, der er forsynet af mobilselskabet. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"observer netværksforhold"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 404d4cc..f87865d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ermöglicht dem Inhaber, die vom Mobilfunkanbieter bereitgestellte Konfigurations-App aufzurufen. Sollte für normale Apps nie benötigt werden."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Informationen zu den Netzwerkbedingungen erfassen"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ermöglicht der App, Informationen zu den Netzwerkbedingungen zu erfassen. Sollte für normale Apps nie benötigt werden."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"Kalibrierung für Eingabegerät ändern"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ermöglicht der App, die Kalibrierungsparameter des Touchscreens zu ändern. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1c3e185..ffe25013 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Επιτρέπει στον κάτοχο την κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας. Δεν απαιτείται για κανονικές εφαρμογές."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"λήψη παρατηρήσεων σχετικά με την κατάσταση δικτύου"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Επιτρέπει σε μια εφαρμογή να λαμβάνει παρατηρήσεις σχετικά με την κατάσταση δικτύου. Δεν θα πρέπει να απαιτείται ποτέ για κανονικές εφαρμογές."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"αλλαγή βαθμονόμησης της συσκευής εισόδου"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Επιτρέπει στην εφαρμογή να τροποποιεί τις παραμέτρους βαθμονόμησης της οθόνης αφής. Δεν απαιτείται για τις κανονικές εφαρμογές."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c4b3a2b..19ea67b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index c4b3a2b..19ea67b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1446aff..ec4ed33 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite al propietario ejecutar la aplicación de configuración proporcionada por el proveedor. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Detectar cambios en el estado de la red"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"Cambiar la calibración del dispositivo de entrada"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6d4ee8e..cb68b67 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite ejecutar la aplicación de configuración proporcionada por el operador. No debe ser necesario para aplicaciones normales."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar cambios en el estado de la red"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. No debe ser necesario para aplicaciones normales."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. No debe ser necesario para las aplicaciones normales."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 629852f..039fa9c 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lubab omanikul aktiveerida operaatoripoolse konfiguratsioonirakenduse. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"võrgutingimuste teabe kuulamine"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lubab rakendusel kuulata võrgutingimuste teavet. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"sisendseadme kalibreerimise muutmine"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lubab rakendusel muuta puuteekraani kalibreerimisparameetreid. Ei tohiks kunagi olla vajalik tavaliste rakenduste puhul."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index a73d136..655cd24 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -256,7 +256,7 @@
<string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"حذف نصب میانبرها"</string>
<string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"به برنامه اجازه میدهد میانبرهای صفحه اصلی را بدون دخالت کاربر حذف کند."</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ترسیم مجدد مسیر تماسهای خروجی"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"به برنامه اجازه میدهد عددی را که در طی یک تماس خروجی شمارهگیری شده ببیند و این اختیار را دارد که تماس را به شماره دیگری هدایت کند یا کلاً تماس را قطع کند."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"به برنامه اجازه میدهد عددی را که در طی یک تماس خروجی شمارهگیری شده، ببیند و این اختیار را دارد که تماس را به شماره دیگری هدایت کند یا کلاً تماس را قطع کند."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"دریافت پیامهای نوشتاری (پیامک)"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"به برنامه اجازه میدهد پیامکها را دریافت و پردازش کند. این یعنی برنامه میتواند پیامهای ارسالی به دستگاه شما را بدون نمایش آنها به شما حذف یا کنترل کند."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"دریافت پیامهای نوشتاری (MMS)"</string>
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"به دارنده اجازه میدهد که تنظیمات برنامه شرکت مخابراتی را لغو کند. هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"گوش دادن برای بررسی شرایط شبکه"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"به برنامه امکان میدهد برای بررسی شرایط شبکه گوش دهد. این امکان هرگز نباید برای برنامههای معمولی مورد نیاز باشد."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسههای مجاز در گذرواژههای بازکردن قفل صفحه را کنترل کنید."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاشهای قفل گشایی صفحه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4e9ddd1..aa85581 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Antaa luvanhaltijan käynnistää palveluntarjoajan määrityssovelluksen. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"verkon tilahavaintojen kuunteleminen"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Antaa sovellukselle luvan kuunnella verkon tilahavaintoja. Ei tavallisten sovellusten käyttöön."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 79a1ab1..23a20a1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f869af5..f9e7b15 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par l\'opérateur. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter des observations sur les conditions du réseau. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 00fdd7c..05e5941 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन ऐप्स प्रारंभ करने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्थितियों के अवलोकनों को सुनें"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ऐप्स को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट उपकरण कैलिब्रेशन बदलें"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ऐप्स को टच स्क्रीन के कैलिब्रेशन पैरामीटर को बदलने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 6224106..1d3d3a5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Dopušta nositelju pozivanje operaterove aplikacije za konfiguraciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"praćenje motrenja mrežnih uvjeta"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Omogućuje aplikaciji praćenje motrenja mrežnih uvjeta. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"promjena kalibracije uređaja za unos"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Omogućuje aplikaciji izmjenu parametara kalibracije dodirnog zaslona. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c0f9c27..1d6b16d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lehetővé teszi a használó számára a szolgáltató által biztosított konfigurációs alkalmazás hívását. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"hálózati körülményekkel kapcsolatos észrevételek figyelemmel kísérése"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lehetővé teszi egy alkalmazás számára, hogy figyelemmel kísérje a hálózati körülményekkel kapcsolatos észrevételeket. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"beviteli eszköz kalibrációjának módosítása"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lehetővé teszi, hogy alkalmazás módosítsa az érintőképernyő kalibrációs paramétereit. A normál alkalmazásoknál erre elvileg soha nincs szükség."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 8a0f901..e216c63 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Թույլ է տալիս սեփականատիրոջը գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"լսել դիտարկումներ ցանցային պայմանների վերաբերյալ"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 07e6cb2..b3b0d2b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Memungkinkan pemegang meminta aplikasi konfigurasi yang disediakan operator. Tidak pernah diperlukan aplikasi normal."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"mendengar untuk observasi kondisi jaringan"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Memungkinkan aplikasi mendengar untuk observasi kondisi jaringan. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"mengubah kalibrasi perangkat masukan"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Memungkinkan aplikasi mengubah parameter kalibrasi layar sentuh. Tidak diperlukan oleh aplikasi normal."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0f59bba..3faca1a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Consente al titolare di richiamare l\'app di configurazione dell\'operatore-provider. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascolto delle osservazioni sulle condizioni di rete"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Consente a un\'applicazione di ascoltare le osservazioni sulle condizioni di rete. Da non utilizzare mai con app normali."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifica calibrazione del dispositivo di immissione"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Consente all\'app di modificare i parametri di calibrazione del touch screen. Questa opzione non deve essere utilizzata per le app normali."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione regole password"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Controllo tentativi di sblocco dello schermo"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 128fbc7..c8f0dd5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ההרשאה הזו מאפשרת לבעלים להפעיל את אפליקציית התצורה שסופקה על ידי ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"קליטת מעקב אחר תנאי רשת"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"מאפשרת לאפליקציה לקלוט מעקב אחר תנאי רשת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"שינוי הכיול של מכשיר קלט"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"מאפשרת לאפליקציה לשנות את פרמטרי הכיול של מסך המגע. לעולם לא אמורה להיות נחוצה לאפליקציות רגילות."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 7892d69..c118d83 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"携帯通信会社が提供する設定アプリを呼び出すことを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ネットワーク状況監視のためのリッスン"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ネットワーク状況を監視するためリッスンすることをアプリに許可します。通常のアプリで必要になることはありません。"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index a48ac95..f360f70 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"საშუალებას აძლევს მფლობელს გამოიწვიოს ოპერატორის მიერ მოწოდებული კონფიგურაციის აპი. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"განხორციელდეს ქსელის მდგომარეობის მონიტორინგი"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 488a439..b9b777d 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"អនុញ្ញាតឲ្យម្ចាស់ដកហូតកម្មវិធីកំណត់រចនាសម្ព័ន្ធដែលបានផ្ដល់ដោយក្រុមហ៊ុនបញ្ជូន។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"សង្កេតមើលលើលក្ខខណ្ឌបណ្ដាញ"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យកម្មវិធីសង្កេតមើលលើលក្ខខណ្ឌបណ្ដាញ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់ក្បួនពាក្យសម្ងាត់"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យប្រវែង និងតួអក្សរដែលបានអនុញ្ញាតក្នុងពាក្យសម្ងាត់ចាក់សោអេក្រង់។"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យការព្យាយាមដោះសោអេក្រង់"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 681aabf..15661a6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"권한을 가진 프로그램이 이동통신사에서 제공한 구성 앱을 호출하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"네트워크 상태에 대한 관측 보고 수신"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"애플리케이션이 네트워크 상태에 대한 관측 보고를 수신하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 64dcbc6..d327bb6 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b379738..22fc1c4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Turėtojui leidžiama iškviesti operatoriaus pateiktą konfigūravimo programą. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"vykdyti tinklo sąlygų stebėjimą"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Leidžiama programai vykdyti tinklo sąlygų stebėjimą. To niekada neturėtų prireikti naudojant įprastas programas."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"keisti įvesties įrenginio kalibravimą"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Leidžiama programai keisti jutiklinio ekrano kalibravimo parametrus. Neturėti prireikti naudojant įprastas programas."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 278b0d7..4a207d9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ļauj īpašniekam izsaukt operatora nodrošināto konfigurācijas lietotni. Parastām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"iegūt informāciju par tīkla stāvokļa novērojumiem"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ļauj lietojumprogrammai iegūt informāciju par tīkla stāvokļa novērojumiem. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"mainīt ievadierīces kalibrēšanu"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ļauj lietotnei pārveidot skārienekrāna kalibrēšanas parametrus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 3d0b3cb..dd8568e 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Эзэмшигчид үүрэн компанийн нийлүүлсэн тохируулах апп-г өдөөх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Сүлжээний байдлын талаар ажиглалтуудыг хүлээн авах"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 37d0d0f..6ca6399 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Membenarkan pemegang menggunakan apl konfigurasi yang diberikan oleh pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"dengar pemerhatian mengenai keadaan rangkaian"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Membenarkan aplikasi mendengar pemerhatian tentang keadaan rangkaian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 78df5e8..85e51ed 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Gir innehaveren tillatelse til å kalle opp den konfigurasjonsappen som ble levert av operatøren. Dette skal ikke være nødvendig for vanlige apper."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lytte etter observasjoner om nettverksforhold"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Gir appen tillatelse til å lytte etter observasjoner om nettverksforhold. Dette skal ikke være nødvendig for vanlige apper."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8eaebf1..f8869f0 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Hiermee kan de houder de door de provider geleverde configuratie-app aanroepen. Nooit vereist voor normale apps."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"controleren op waarnemingen met betrekking tot netwerkomstandigheden"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Hiermee kan een app controleren op waarnemingen met betrekking tot netwerkomstandigheden. Nooit vereist voor normale apps."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 77d5441..e9d701a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Zezwala na wywoływanie aplikacji konfiguracyjnej udostępnionej przez operatora. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"śledź stan sieci"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Pozwala aplikacji śledzić stan sieci. Nieprzeznaczone dla zwykłych aplikacji."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"zmiana kalibracji urządzenia wejściwego"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Zezwala aplikacji na modyfikowanie parametrów kalibracji ekranu dotykowego. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e92961d..1f42876 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o titular invoque a aplicação de configuração fornecida pela operadora. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ouvir observações sobre as condições da rede"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que uma aplicação ouça observações sobre as condições da rede. Nunca deverá ser necessário para aplicações normais."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index b3481b8..12d3cd7 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o proprietário invoque o aplicativo de configuração fornecido pela operadora. Não deve ser necessário para aplicativos comuns."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar observações nas condições da rede"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que o aplicativo detecte observações nas condições da rede. Não deve ser necessário para aplicativos comuns."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9c2c793..8d007e4 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1170,6 +1170,10 @@
<skip />
<!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
<skip />
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<!-- no translation found for policylab_limitPassword (4497420728857585791) -->
<skip />
<!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 016cb16..86101eb 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite proprietarului să apeleze aplicația de configurare furnizată de operator. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascultă observații despre starea rețelei"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite unei aplicații să asculte observații despre starea rețelei. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5c9e697..ad6bdeb 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Владелец сможет запускать приложение настроек, предоставленное оператором. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Использование данных о состоянии сети"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Приложение сможет использовать данные о состоянии сети. Это разрешение обычно используется только специальными приложениями."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 039e1eb..7d73b5a 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje držiteľovi vyvolať aplikáciu pre konfiguráciu poskytnutú operátorom. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"zachytávať informácie o stave siete"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikácii zachytávať informácie o stave siete. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 6a909d6..ebde21f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lastniku omogoča sproženje operaterjeve aplikacije za konfiguracijo. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"spremljanje razmer v omrežju"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Aplikaciji omogoča spremljanje razmer v omrežju. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9a53a2a7..7895ded 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"праћење података о условима на мрежи"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"промени калибрацију улазног уређаја"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2e2d3f2..c29f0a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Innehavaren tillåts att anropa konfigurationsappen från operatören. Ska inte behövas för vanliga appar."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lyssna efter information om nätverksförhållanden"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillåter att appen lyssnar efter information om nätverksförhållanden. Vanliga appar bör aldrig behöva den här behörigheten."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ändra kalibreringen för inmatningsenheten"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillåter att appen ändrar kalibreringsparametrarna för pekskärmen. Detta behövs aldrig för vanliga appar."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5b15a7f..5b8fbd4 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -256,7 +256,7 @@
<string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ondoa njia za mikato"</string>
<string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Huruhusu programu kuondoa njia za mkato za Skrini ya kwanza bila mtumiaji kuingilia."</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"panga upya simu zinazotoka"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Huruhusu programu kuona nambari inayopigwa wakati simu inapigwa ikiwa na chaguo la kuelekeza simu kwa nambari tofauti au kukata simu kabisa."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Huruhusu programu kuona nambari inayopigwa wakati simu inapigwa ikiwa na chaguo la kuelekeza simu kwenye nambari tofauti au kukata simu kabisa."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"pokea ujumbe wa maandishi wa SMS"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"pokea ujumbe wa maandishi wa MMS"</string>
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Inaruhusu kishikiliaji kuomba programu ya usakinishaji inayotolewa na mto huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"sikiliza matukio katika hali za mtandao"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Huruhusu programu kusikiliza matukio katika hali za mtandao. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu idadi ya mara ambazo skrini inajaribu kufunguliwa"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a4c328e..2b2d0a1 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -256,7 +256,7 @@
<string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ถอนการติดตั้งทางลัด"</string>
<string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"อนุญาตให้แอปพลิเคชันลบทางลัดหน้าจอหลักโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"จัดเส้นทางการโทรออกใหม่"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"อนุญาตให้แอปดูหมายเลขที่โทรในระหว่างการโทรออกโดยสามารถเลือกเปลี่ยนเส้นทางการโทรไปยังหมายเลขอื่นหรือยกเลิกการโทรไปเลย"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"อนุญาตให้แอปดูหมายเลขที่โทรในระหว่างการโทรออกโดยสามารถเลือกเปลี่ยนเส้นทางการโทรไปยังหมายเลขอื่นหรือยกเลิกการโทรไปเลยได้"</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"รับข้อความ (SMS)"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ SMS ซึ่งหมายความว่าแอปพลิเคชันจะสามารถตรวจสอบหรือลบข้อความที่ส่งมายังอุปกรณ์ของคุณได้โดยไม่ต้องแสดงให้คุณเห็น"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"รับข้อความ (MMS)"</string>
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"อนุญาตให้ผู้ใช้สามารถเรียกใช้แอปการกำหนดค่าของผู้ให้บริการ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"อนุญาตให้แอปพลิเคชันฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย ไม่จำเป็นสำหรับแอปปกติ"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4c54352..999f8ca 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Nagbibigay-daan sa may-ari na paganahin ang app ng configuration na ibinigay ng carrier. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"makinig sa mga obserbasyon sa mga kundisyon ng network"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Nagbibigay-daan sa isang application na makinig sa mga obserbasyon sa mga kundisyon ng network. Dapat na hindi kailanman kakailanganin para sa normal na apps."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index bf01a4e..1fcb645 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"İzin sahibine, operatör tarafından sağlanan yapılandırma uygulamasını çalıştırma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ağ koşullarındaki gözlemleri dinle"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Bir uygulamaya, ağ koşullarındaki gözlemleri dinleme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index dc79da7..ee68648 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозволяє власнику викликати надану оператором програму конфігурації. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"прослуховувати дані спостережень за станом мережі"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозволяє програмі прослуховувати дані спостережень за станом мережі. Ніколи не застосовується для звичайних програм."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5dcf41d..d4c2f29 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -256,7 +256,7 @@
<string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"gỡ cài đặt lối tắt"</string>
<string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Cho phép ứng dụng xóa lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"định tuyến lại cuộc gọi đi"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Cho phép ứng dụng xem số được quay trong một cuộc gọi đi với tùy chọn chuyển hướng cuộc gọi đến một số khác hoặc hủy cuộc gọi đó hoàn toàn."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Cho phép ứng dụng xem số được gọi trong một cuộc gọi đi với tùy chọn chuyển hướng cuộc gọi đến một số khác hoặc hủy cuộc gọi đó hoàn toàn."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"nhận tin nhắn văn bản (SMS)"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"nhận tin nhắn văn bản (MMS)"</string>
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Cho phép chủ sở hữu gọi ra ứng dụng cấu hình do nhà cung cấp dịch vụ cung cấp. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"quan sát các điều kiện mạng"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Cho phép ứng dụng quan sát các điều kiện mạng. Không bao giờ cần cho ứng dụng thông thường."</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 5a9c285..76730b2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允许应用调用运营商提供的配置应用。普通应用绝不需要此权限。"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"监听网络状况的观测信息"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允许应用监听网络状况的观测信息。普通应用绝不需要此权限。"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index bfffe13..3bb37d5 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式調用流動網絡供應商提供的設定應用程式 (不建議一般應用程式使用)。"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽對網絡狀況的觀察"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽對網絡狀況的觀察 (不建議一般應用程式使用)。"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d6bcb61..a11392d 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -256,7 +256,7 @@
<string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"解除安裝捷徑"</string>
<string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"允許應用程式自動移除主螢幕捷徑。"</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"重設撥號路徑"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥打電話期間查看撥出的電話號碼,並選擇改撥其他號碼或完全中斷通話。"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥打電話期間查看撥出的電話號碼,並可選擇改撥其他號碼或中斷通話。"</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"接收簡訊 (SMS)"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理簡訊。這項設定可讓應用程式監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"接收簡訊 (MMS)"</string>
@@ -689,6 +689,10 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式叫用行動通訊業者提供的設定應用程式 (一般應用程式並不需要)。"</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽網路狀況觀察資訊"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽網路狀況觀察資訊 (一般應用程式並不需要)。"</string>
+ <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+ <skip />
+ <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a44c04c..c7faf48 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -689,6 +689,8 @@
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ivumela umnikazi ukuthi abuyisele uhlelo lokusebenza lokulungiselelwa. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Lalela okubonwayo kuzimo zenethiwekhi"</string>
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ivumela uhlelo lokusebenza ukuthi lulalele okubonwa kuzimo zenethiwekhi. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"guqula ukulinganisa kokufaka kwedivayisi"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ivumela uhlelo lokusebenza ukuthi lushintshe imingcele yokulinganisa yesikrini esithintwayo. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 2efbca2..0a27840 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -62,6 +62,21 @@
a reference to a Drawable resource containing the image definition. -->
<attr name="icon" format="reference" />
+ <!-- A Drawable resource providing an extended graphical banner for its
+ associated item. Use with the application tag (to supply a default
+ banner for all application activities), or with the activity, tag to
+ supply a banner for a specific activity.
+
+ <p>The given banner will be used to display to the user a graphical
+ representation of an activity in the Leanback application launcher.
+ Since banners are displayed only in the Leanback launcher, they should
+ only be used with activities (and applications) that support Leanback
+ mode. These are activities that handle Intents of category
+ {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER
+ Intent.CATEGORY_LEANBACK_LAUNCHER}.
+ <p>This must be a reference to a Drawable resource containing the image definition. -->
+ <attr name="banner" format="reference" />
+
<!-- A Drawable resource providing an extended graphical logo for its
associated item. Use with the application tag (to supply a default
logo for all application components), or with the activity, receiver,
@@ -899,6 +914,7 @@
<attr name="theme" />
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="description" />
<attr name="permission" />
@@ -982,6 +998,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="permissionGroup" />
<attr name="description" />
@@ -1008,6 +1025,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="description" />
<attr name="permissionGroupFlags" />
@@ -1040,6 +1058,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
</declare-styleable>
@@ -1306,6 +1325,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="process" />
<attr name="authorities" />
@@ -1387,6 +1407,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="permission" />
<attr name="process" />
@@ -1429,6 +1450,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="permission" />
<attr name="process" />
@@ -1463,6 +1485,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="launchMode" />
<attr name="screenOrientation" />
@@ -1526,6 +1549,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="permission" />
<!-- Specify whether the activity-alias is enabled or not (that is, can be instantiated by the system).
@@ -1597,6 +1621,7 @@
parent="AndroidManifestActivity AndroidManifestReceiver AndroidManifestService">
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="priority" />
</declare-styleable>
@@ -1725,6 +1750,7 @@
<attr name="targetPackage" />
<attr name="label" />
<attr name="icon" />
+ <attr name="banner" />
<attr name="logo" />
<attr name="handleProfiling" />
<attr name="functionalTest" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cfd4a63..4656f32 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1212,6 +1212,10 @@
<!-- Whether UI for multi user should be shown -->
<bool name="config_enableMultiUserUI">false</bool>
+ <!-- If true, then we do not ask user for permission for apps to connect to USB devices.
+ Do not set this to true for production devices. Doing so will cause you to fail CTS. -->
+ <bool name="config_disableUsbPermissionDialogs">false</bool>
+
<!-- Minimum span needed to begin a touch scaling gesture.
If the span is equal to or greater than this size, a scaling gesture
will begin, where supported. (See android.view.ScaleGestureDetector)
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d58e8ad..25c8baa 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2088,6 +2088,13 @@
<public type="style" name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" id="0x010301e4" />
<!-- ===============================================================
+ Resources added in version 20 of the platform
+ =============================================================== -->
+ <eat-comment />
+
+ <public type="attr" name="banner" id="0x10103f2" />
+
+<!-- ===============================================================
Resources added in version 21 of the platform
=============================================================== -->
<eat-comment />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6624da4..efa873d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -290,6 +290,7 @@
<java-symbol type="bool" name="config_forceDefaultOrientation" />
<java-symbol type="bool" name="config_wifi_batched_scan_supported" />
<java-symbol type="bool" name="config_enableMultiUserUI"/>
+ <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
<java-symbol type="integer" name="config_cursorWindowSize" />
<java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
index f493e9a..fc2897f 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
@@ -27,14 +27,14 @@
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.InstrumentationTestCase;
import android.util.Log;
-import java.io.File;
-import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeoutException;
@@ -47,7 +47,6 @@
protected DownloadManager mDownloadManager = null;
protected String mFileType = "text/plain";
protected Context mContext = null;
- protected MultipleDownloadsCompletedReceiver mReceiver = null;
protected static final int DEFAULT_FILE_SIZE = 10 * 1024; // 10kb
protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
@@ -65,70 +64,9 @@
protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
- public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
- private volatile int mNumDownloadsCompleted = 0;
- private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
+ private DownloadFinishedListener mListener;
+ private Thread mListenerThread;
- /**
- * {@inheritDoc}
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
- synchronized(this) {
- long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
- Log.i(LOG_TAG, "Received Notification for download: " + id);
- if (!downloadIds.contains(id)) {
- ++mNumDownloadsCompleted;
- Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
- intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
- downloadIds.add(id);
-
- DownloadManager dm = (DownloadManager)context.getSystemService(
- Context.DOWNLOAD_SERVICE);
-
- Cursor cursor = dm.query(new Query().setFilterById(id));
- try {
- if (cursor.moveToFirst()) {
- int status = cursor.getInt(cursor.getColumnIndex(
- DownloadManager.COLUMN_STATUS));
- Log.i(LOG_TAG, "Download status is: " + status);
- } else {
- fail("No status found for completed download!");
- }
- } finally {
- cursor.close();
- }
- } else {
- Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
- }
- }
- }
- }
-
- /**
- * Gets the number of times the {@link #onReceive} callback has been called for the
- * {@link DownloadManager#ACTION_DOWNLOAD_COMPLETE} action, indicating the number of
- * downloads completed thus far.
- *
- * @return the number of downloads completed so far.
- */
- public int numDownloadsCompleted() {
- return mNumDownloadsCompleted;
- }
-
- /**
- * Gets the list of download IDs.
- * @return A Set<Long> with the ids of the completed downloads.
- */
- public Set<Long> getDownloadIds() {
- synchronized(this) {
- Set<Long> returnIds = new HashSet<Long>(downloadIds);
- return returnIds;
- }
- }
-
- }
public static class WiFiChangedReceiver extends BroadcastReceiver {
private Context mContext = null;
@@ -172,13 +110,138 @@
}
/**
+ * Broadcast receiver to listen for broadcast from DownloadManager indicating that downloads
+ * are finished.
+ */
+ private class DownloadFinishedListener extends BroadcastReceiver implements Runnable {
+ private Handler mHandler = null;
+ private Looper mLooper;
+ private Set<Long> mFinishedDownloads = new HashSet<Long>();
+
+ /**
+ * Event loop for the thread that listens to broadcasts.
+ */
+ @Override
+ public void run() {
+ Looper.prepare();
+ synchronized (this) {
+ mLooper = Looper.myLooper();
+ mHandler = new Handler();
+ notifyAll();
+ }
+ Looper.loop();
+ }
+
+ /**
+ * Handles the incoming notifications from DownloadManager.
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
+ long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
+ Log.i(LOG_TAG, "Received Notification for download: " + id);
+ synchronized (this) {
+ if(!mFinishedDownloads.contains(id)) {
+ mFinishedDownloads.add(id);
+ notifyAll();
+ } else {
+ Log.i(LOG_TAG,
+ String.format("Notification for %d was already received", id));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the handler for this thread. Need this to make sure that the events are handled
+ * in it is own thread and don't interfere with the instrumentation thread.
+ * @return Handler for the receiver thread.
+ * @throws InterruptedException
+ */
+ private Handler getHandler() throws InterruptedException {
+ synchronized (this) {
+ if (mHandler != null) return mHandler;
+ while (mHandler == null) {
+ wait();
+ }
+ return mHandler;
+ }
+ }
+
+ /**
+ * Stops the thread that receives notification from DownloadManager.
+ */
+ public void cancel() {
+ synchronized(this) {
+ if (mLooper != null) {
+ mLooper.quit();
+ }
+ }
+ }
+
+ /**
+ * Waits for a given download to finish, or until the timeout expires.
+ * @param id id of the download to wait for.
+ * @param timeout maximum time to wait, in milliseconds
+ * @return true if the download finished, false otherwise.
+ * @throws InterruptedException
+ */
+ public boolean waitForDownloadToFinish(long id, long timeout) throws InterruptedException {
+ long startTime = SystemClock.uptimeMillis();
+ synchronized (this) {
+ while (!mFinishedDownloads.contains(id)) {
+ if (SystemClock.uptimeMillis() - startTime > timeout) {
+ Log.i(LOG_TAG, String.format("Timeout while waiting for %d to finish", id));
+ return false;
+ } else {
+ wait(timeout);
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Waits for multiple downloads to finish, or until timeout expires.
+ * @param ids ids of the downloads to wait for.
+ * @param timeout maximum time to wait, in milliseconds
+ * @return true of all the downloads finished, false otherwise.
+ * @throws InterruptedException
+ */
+ public boolean waitForMultipleDownloadsToFinish(Set<Long> ids, long timeout)
+ throws InterruptedException {
+ long startTime = SystemClock.uptimeMillis();
+ synchronized (this) {
+ while (!mFinishedDownloads.containsAll(ids)) {
+ if (SystemClock.uptimeMillis() - startTime > timeout) {
+ Log.i(LOG_TAG, "Timeout waiting for multiple downloads to finish");
+ return false;
+ } else {
+ wait(timeout);
+ }
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
public void setUp() throws Exception {
+ super.setUp();
mContext = getInstrumentation().getContext();
mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
- mReceiver = registerNewMultipleDownloadsReceiver();
+ mListener = registerDownloadsListener();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mContext.unregisterReceiver(mListener);
+ mListener.cancel();
+ mListenerThread.join();
+ super.tearDown();
}
/**
@@ -198,12 +261,15 @@
* that have completed.
*
* @return A new receiver that records and can be queried on how many downloads have completed.
+ * @throws InterruptedException
*/
- protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
- MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
- mContext.registerReceiver(receiver, new IntentFilter(
- DownloadManager.ACTION_DOWNLOAD_COMPLETE));
- return receiver;
+ protected DownloadFinishedListener registerDownloadsListener() throws InterruptedException {
+ DownloadFinishedListener listener = new DownloadFinishedListener();
+ mListenerThread = new Thread(listener);
+ mListenerThread.start();
+ mContext.registerReceiver(listener, new IntentFilter(
+ DownloadManager.ACTION_DOWNLOAD_COMPLETE), null, listener.getHandler());
+ return listener;
}
/**
@@ -283,76 +349,35 @@
}
/**
- * Helper to wait for a particular download to finish, or else a timeout to occur
- *
- * Does not wait for a receiver notification of the download.
- *
- * @param id The download id to query on (wait for)
- */
- protected void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
- InterruptedException {
- doWaitForDownloadsOrTimeout(new Query().setFilterById(id),
- WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
- }
-
- /**
- * Helper to wait for a particular download to finish, or else a timeout to occur
- *
- * Also guarantees a notification has been posted for the download.
- *
- * @param id The download id to query on (wait for)
- */
- protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
- InterruptedException {
- waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
- }
-
- /**
- * Helper to wait for a particular download to finish, or else a timeout to occur
- *
- * Also guarantees a notification has been posted for the download.
+ * Helper to wait for a particular download to finish, or else a timeout to occur.
*
* @param id The download id to query on (wait for)
* @param poll The amount of time to wait
* @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
*/
- protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
- throws TimeoutException, InterruptedException {
- doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
- waitForReceiverNotifications(1);
+ protected boolean waitForDownload(long id, long timeoutMillis)
+ throws InterruptedException {
+ return mListener.waitForDownloadToFinish(id, timeoutMillis);
+ }
+
+ protected boolean waitForMultipleDownloads(Set<Long> ids, long timeout)
+ throws InterruptedException {
+ return mListener.waitForMultipleDownloadsToFinish(ids, timeout);
}
/**
- * Helper to wait for all downloads to finish, or else a specified timeout to occur
- *
- * Makes no guaranee that notifications have been posted for all downloads.
- *
- * @param poll The amount of time to wait
- * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+ * Checks with the download manager if the give download is finished.
+ * @param id id of the download to check
+ * @return true if download is finished, false otherwise.
*/
- protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
- InterruptedException {
- doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
- }
-
- /**
- * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
- *
- * Also guarantees a notification has been posted for the download.
- *
- * @param id The id of the download to query against
- * @param poll The amount of time to wait
- * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
- * @return true if download completed successfully (didn't timeout), false otherwise
- */
- private boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
- try {
- doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
- waitForReceiverNotifications(1);
- } catch (TimeoutException e) {
- return false;
- }
- return true;
+ private boolean hasDownloadFinished(long id) {
+ Query q = new Query();
+ q.setFilterById(id);
+ q.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
+ Cursor cursor = mDownloadManager.query(q);
+ boolean finished = cursor.getCount() == 1;
+ cursor.close();
+ return finished;
}
/**
@@ -389,34 +414,6 @@
}
/**
- * Helper to wait for all downloads to finish, or else a timeout to occur
- *
- * @param query The query to pass to the download manager
- * @param poll The poll time to wait between checks
- * @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
- */
- private void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
- throws TimeoutException {
- int currentWaitTime = 0;
- while (true) {
- query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
- | DownloadManager.STATUS_RUNNING);
- Cursor cursor = mDownloadManager.query(query);
-
- try {
- if (cursor.getCount() == 0) {
- Log.i(LOG_TAG, "All downloads should be done...");
- break;
- }
- currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
- "Timed out waiting for all downloads to finish");
- } finally {
- cursor.close();
- }
- }
- }
-
- /**
* Synchronously waits for external store to be mounted (eg: SD Card).
*
* @throws InterruptedException if interrupted
@@ -465,53 +462,50 @@
}
/**
- * Synchronously waits for our receiver to receive notification for a given number of
- * downloads.
+ * Synchronously waits for the download manager to start incrementing the number of
+ * bytes downloaded so far.
*
- * @param targetNumber The number of notifications for unique downloads to wait for; pass in
- * -1 to not wait for notification.
- * @throws Exception if timed out while waiting
- */
- private void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
- int count = mReceiver.numDownloadsCompleted();
- int currentWaitTime = 0;
-
- while (count < targetNumber) {
- Log.i(LOG_TAG, "Waiting for notification of downloads...");
- currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
- MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
- + " Received " + count + "notifications.");
- count = mReceiver.numDownloadsCompleted();
- }
- }
-
- /**
- * Synchronously waits for a file to increase in size (such as to monitor that a download is
- * progressing).
- *
- * @param file The file whose size to track.
+ * @param id DownloadManager download id that needs to be checked.
* @throws Exception if timed out while waiting for the file to grow in size.
*/
- protected void waitForFileToGrow(File file) throws Exception {
+ protected void waitToReceiveData(long id) throws Exception {
int currentWaitTime = 0;
-
- // File may not even exist yet, so wait until it does (or we timeout)
- while (!file.exists()) {
- Log.i(LOG_TAG, "Waiting for file to exist...");
- currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
- MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
- }
-
- // Get original file size...
- long originalSize = file.length();
-
- while (file.length() <= originalSize) {
- Log.i(LOG_TAG, "Waiting for file to be written to...");
+ long originalSize = getBytesDownloaded(id);
+ long currentSize = 0;
+ while ((currentSize = getBytesDownloaded(id)) <= originalSize) {
+ Log.i(LOG_TAG, String.format("orig: %d, cur: %d. Waiting for file to be written to...",
+ originalSize, currentSize));
currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
}
}
+ private long getBytesDownloaded(long id) {
+ DownloadManager.Query q = new DownloadManager.Query();
+ q.setFilterById(id);
+ Cursor response = mDownloadManager.query(q);
+ if (response.getCount() < 1) {
+ Log.i(LOG_TAG, String.format("Query to download manager returned nothing for id %d",id));
+ response.close();
+ return -1;
+ }
+ while(response.moveToNext()) {
+ int index = response.getColumnIndex(DownloadManager.COLUMN_ID);
+ if (id == response.getLong(index)) {
+ break;
+ }
+ }
+ int index = response.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
+ if (index < 0) {
+ Log.i(LOG_TAG, String.format("No downloaded bytes for id %d", id));
+ response.close();
+ return -1;
+ }
+ long size = response.getLong(index);
+ response.close();
+ return size;
+ }
+
/**
* Helper to remove all downloads that are registered with the DL Manager.
*
@@ -536,19 +530,6 @@
}
/**
- * Helper to verify an int value in a Cursor
- *
- * @param cursor The cursor containing the query results
- * @param columnName The name of the column to query
- * @param expected The expected int value
- */
- private void verifyInt(Cursor cursor, String columnName, int expected) {
- int index = cursor.getColumnIndex(columnName);
- int actual = cursor.getInt(index);
- assertEquals(expected, actual);
- }
-
- /**
* Performs a query based on ID and returns a Cursor for the query.
*
* @param id The id of the download in DL Manager; pass -1 to query all downloads
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index 06c6c34..ef48a18 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -23,9 +23,6 @@
import android.os.ParcelFileDescriptor;
import android.util.Log;
-import com.android.frameworks.downloadmanagertests.DownloadManagerBaseTest;
-import com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner;
-
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -193,9 +190,7 @@
int status = cursor.getInt(columnIndex);
int currentWaitTime = 0;
- // Wait until the download finishes; don't wait for a notification b/c
- // the download may well have been completed before the last reboot.
- waitForDownloadOrTimeout_skipNotification(dlRequest);
+ assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
Log.i(LOG_TAG, "Verifying download information...");
// Verify specific info about the file (size, name, etc)...
@@ -235,7 +230,7 @@
dlRequest = mDownloadManager.enqueue(request);
// Rather large file, so wait up to 15 mins...
- waitForDownloadOrTimeout(dlRequest, WAIT_FOR_DOWNLOAD_POLL_TIME, 15 * 60 * 1000);
+ assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
Cursor cursor = getCursor(dlRequest);
ParcelFileDescriptor pfd = null;
@@ -289,7 +284,7 @@
dlRequest = mDownloadManager.enqueue(request);
waitForDownloadToStart(dlRequest);
// make sure we're starting to download some data...
- waitForFileToGrow(downloadedFile);
+ waitToReceiveData(dlRequest);
// download disable
setWiFiStateOn(false);
@@ -317,7 +312,7 @@
Log.i(LOG_TAG, "Turning on WiFi...");
setWiFiStateOn(true);
Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
- waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+ assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -363,7 +358,7 @@
dlRequest = mDownloadManager.enqueue(request);
waitForDownloadToStart(dlRequest);
// are we making any progress?
- waitForFileToGrow(downloadedFile);
+ waitToReceiveData(dlRequest);
// download disable
Log.i(LOG_TAG, "Turning off WiFi...");
@@ -373,7 +368,7 @@
// enable download...
Log.i(LOG_TAG, "Turning on WiFi again...");
setWiFiStateOn(true);
- waitForFileToGrow(downloadedFile);
+ waitToReceiveData(dlRequest);
// download disable
Log.i(LOG_TAG, "Turning off WiFi...");
@@ -385,7 +380,7 @@
setWiFiStateOn(true);
Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
- waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+ assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -433,7 +428,7 @@
dlRequest = mDownloadManager.enqueue(request);
waitForDownloadToStart(dlRequest);
// are we making any progress?
- waitForFileToGrow(downloadedFile);
+ waitToReceiveData(dlRequest);
// download disable
Log.i(LOG_TAG, "Turning on Airplane mode...");
@@ -444,7 +439,7 @@
Log.i(LOG_TAG, "Turning off Airplane mode...");
setAirplaneModeOn(false);
// make sure we're starting to download some data...
- waitForFileToGrow(downloadedFile);
+ waitToReceiveData(dlRequest);
// reenable the connection to start up the download again
Log.i(LOG_TAG, "Turning on Airplane mode again...");
@@ -456,7 +451,7 @@
setAirplaneModeOn(false);
Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete...");
- waitForDownloadsOrTimeout(dlRequest, 180 * 1000); // wait up to 3 mins before timeout
+ assertTrue(waitForDownload(dlRequest, 180 * 1000)); // wait up to 3 mins before timeout
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -476,7 +471,6 @@
public void runDownloadMultipleSimultaneously() throws Exception {
final int TOTAL_DOWNLOADS = 15;
HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
- MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
// Make sure there are no pending downloads currently going on
removeAllCurrentDownloads();
@@ -494,8 +488,7 @@
downloadIds.add(dlRequest);
}
- waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000); // wait 15 mins max
- assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
+ assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max
} finally {
removeAllCurrentDownloads();
}
diff --git a/docs/html/images/screens_support/avds-config.png b/docs/html/images/screens_support/avds-config.png
index 97bd5f6..e609447 100644
--- a/docs/html/images/screens_support/avds-config.png
+++ b/docs/html/images/screens_support/avds-config.png
Binary files differ
diff --git a/docs/html/images/tools/as-camera-icon.png b/docs/html/images/tools/as-camera-icon.png
new file mode 100644
index 0000000..419a88d
--- /dev/null
+++ b/docs/html/images/tools/as-camera-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-error.png b/docs/html/images/tools/as-error.png
new file mode 100644
index 0000000..8865f54
--- /dev/null
+++ b/docs/html/images/tools/as-error.png
Binary files differ
diff --git a/docs/html/images/tools/as-fr-device.png b/docs/html/images/tools/as-fr-device.png
new file mode 100644
index 0000000..aec3bce
--- /dev/null
+++ b/docs/html/images/tools/as-fr-device.png
Binary files differ
diff --git a/docs/html/images/tools/as-fr-icon.png b/docs/html/images/tools/as-fr-icon.png
new file mode 100644
index 0000000..9252ca1
--- /dev/null
+++ b/docs/html/images/tools/as-fr-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-frag-ex.png b/docs/html/images/tools/as-frag-ex.png
new file mode 100644
index 0000000..775fa5e
--- /dev/null
+++ b/docs/html/images/tools/as-frag-ex.png
Binary files differ
diff --git a/docs/html/images/tools/as-grid-layout.png b/docs/html/images/tools/as-grid-layout.png
new file mode 100644
index 0000000..41b933a
--- /dev/null
+++ b/docs/html/images/tools/as-grid-layout.png
Binary files differ
diff --git a/docs/html/images/tools/as-i18n-icon.png b/docs/html/images/tools/as-i18n-icon.png
new file mode 100644
index 0000000..d35568f
--- /dev/null
+++ b/docs/html/images/tools/as-i18n-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-chrome.png b/docs/html/images/tools/as-preview-chrome.png
new file mode 100644
index 0000000..716b8d7
--- /dev/null
+++ b/docs/html/images/tools/as-preview-chrome.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-icon.png b/docs/html/images/tools/as-preview-icon.png
new file mode 100644
index 0000000..59c7644
--- /dev/null
+++ b/docs/html/images/tools/as-preview-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-nochrome.png b/docs/html/images/tools/as-preview-nochrome.png
new file mode 100644
index 0000000..1011e08
--- /dev/null
+++ b/docs/html/images/tools/as-preview-nochrome.png
Binary files differ
diff --git a/docs/html/images/tools/as-theme-db.png b/docs/html/images/tools/as-theme-db.png
new file mode 100644
index 0000000..beade0d
--- /dev/null
+++ b/docs/html/images/tools/as-theme-db.png
Binary files differ
diff --git a/docs/html/images/tools/as-theme-icon.png b/docs/html/images/tools/as-theme-icon.png
new file mode 100644
index 0000000..0e5fdf0
--- /dev/null
+++ b/docs/html/images/tools/as-theme-icon.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/adt-firstapp-setup.png b/docs/html/images/training/firstapp/adt-firstapp-setup.png
index bf95285..05e147d 100644
--- a/docs/html/images/training/firstapp/adt-firstapp-setup.png
+++ b/docs/html/images/training/firstapp/adt-firstapp-setup.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/adt-new-activity.png b/docs/html/images/training/firstapp/adt-new-activity.png
index c396793..2c32dcc 100644
--- a/docs/html/images/training/firstapp/adt-new-activity.png
+++ b/docs/html/images/training/firstapp/adt-new-activity.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/edittext_gravity.png b/docs/html/images/training/firstapp/edittext_gravity.png
index f78e676..bc4f7ee 100644
--- a/docs/html/images/training/firstapp/edittext_gravity.png
+++ b/docs/html/images/training/firstapp/edittext_gravity.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/edittext_wrap.png b/docs/html/images/training/firstapp/edittext_wrap.png
index 156776d..fe56731 100644
--- a/docs/html/images/training/firstapp/edittext_wrap.png
+++ b/docs/html/images/training/firstapp/edittext_wrap.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/firstapp.png b/docs/html/images/training/firstapp/firstapp.png
index d69cd20..581e000 100644
--- a/docs/html/images/training/firstapp/firstapp.png
+++ b/docs/html/images/training/firstapp/firstapp.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 5d1788a..e901652 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -22,12 +22,13 @@
<script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<div style="box-shadow: 3px 10px 18px 1px #999;width:600px;height:336px">
<div id="ytapiplayer">
- <a href="http://www.youtube.com/watch?v=WWArLD6nqrk"><img width=600 src="{@docRoot}images/video-kiwi.jpg"></a><!--You need Flash player 8+ and JavaScript enabled to view this video. -->
+ <a href="http://www.youtube.com/watch?v=i2uvYI6blEE"><img width=600
+ src="https://i1.ytimg.com/vi/i2uvYI6blEE/maxresdefault.jpg"></a><!--You need Flash player 8+ and JavaScript enabled to view this video. -->
</div>
<script type="text/javascript">
var params = { allowScriptAccess: "always" };
var atts = { id: "ytapiplayer" };
- swfobject.embedSWF("//www.youtube.com/v/WWArLD6nqrk?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
+ swfobject.embedSWF("//www.youtube.com/v/i2uvYI6blEE?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
"ytapiplayer", "600", "336", "8", null, null, params, atts);
// Callback used to pause/resume carousel based on video state
@@ -56,9 +57,8 @@
</div>
</div>
<div class="content-right col-4">
- <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />Kiwi, Inc.</h1>
- <p>Game developer Kiwi has had five titles in the top 25 grossing on Google Play. Hear how Google Play
- has helped them double revenue every six months.</p>
+ <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />Box Inc.</h1>
+ <p>Box is a cloud-based platform and app for users to share business information. See how they got over 5 million downloads by leveraging the flexibility in the Android platform.</p>
<p><a href="{@docRoot}distribute/googleplay/spotlight/index.html" class="button">Watch more videos </a></p>
</div>
</li>
diff --git a/docs/html/sdk/installing/studio-layout.jd b/docs/html/sdk/installing/studio-layout.jd
new file mode 100644
index 0000000..f0e5d59
--- /dev/null
+++ b/docs/html/sdk/installing/studio-layout.jd
@@ -0,0 +1,148 @@
+page.title=Using the Layout Editor
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>See also</h2>
+<ul>
+<li><a href="{@docRoot}sdk/installing/studio.html">
+Getting Started with Android Studio</a></li>
+<li><a href="{@docRoot}sdk/installing/studio-tips.html">
+Android Studio Tips and Tricks</a></li>
+<li><a href="{@docRoot}sdk/installing/migrate.html">
+Migrating from Eclipse</a></li>
+</div>
+</div>
+
+<a class="notice-developers-video"
+href="https://developers.google.com/events/io/sessions/324603352">
+<div>
+ <h3>Video</h3>
+ <p>What's New in Android Developer Tools</p>
+</div>
+</a>
+
+<p>Android Studio offers an advanced layout editor that allows you to drag-and-drop widgets
+into your layout and preview your layout while editing the XML.</p>
+
+<p>Within the layout editor, you can switch between the <strong>Text</strong> view, where
+you edit the XML file as text, and the <strong>Design</strong> view. Just click the
+appropriate tab at the bottom of the window to display the desired editor.</p>
+
+<h2>Editing in the Text View</h2>
+
+<p>You can use the <strong>Text</strong> view to edit your layout file. This section describes
+some of the features that are available in the <strong>Text</strong> view.</p>
+
+<h3>Preview</h3>
+
+<p>While editing in the <strong>Text</strong> view, you can preview the layout on devices
+by opening the <strong>Preview</strong> pane available on the right side of the window.
+Within the <strong>Preview</strong> pane, you can modify the preview by changing various
+options at the top of the pane, including the preview device, layout theme, platform
+version and more. To see a preview of how your app would look with a particular device
+skin, click the preview icon
+<img src="{@docRoot}images/tools/as-preview-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+and choose the desired device, such as Nexus 4:</p>
+
+<img src="{@docRoot}images/tools/as-preview-chrome.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Previewing your app.</p>
+
+<p>To preview the layout on multiple devices simultaneously, select <strong>Preview All
+Screen Sizes</strong> from the device drop-down. </p>
+
+<p>When you click in the preview image, the layout editor highlights the corresponding
+section in the XML, and vice-versa.</p>
+
+<h3>Interactive error detection and recovery</h3>
+
+<p>As you edit the <strong>Text</strong> view of your layout XML file, Android Studio flags
+typos and offers assistance.</p>
+
+<p>For example, suppose you are adding a button, and you misspell it as "Buttonn".
+Android Studio helps you to correct it by displaying an error such as the following,
+where you can click on "Change to Button" to fix the error in the XML file:</p>
+
+<img src="{@docRoot}images/tools/as-error.png" alt="" />
+
+<p class="img-caption"><strong>Figure 2.</strong> Flagging errors.</p>
+
+<p>Android Studio also prompts you to supply missing information. For example, suppose you
+start adding a fragment to your layout XML file. First of all, Android Studio displays
+auto-complete suggestions as you type. Once it becomes clear that you are adding a fragment,
+Android Studio displays an error panel with links that you can click to supply the missing
+attributes. Clicking "Automatically add all missing attributes" in this case
+does just that—it completes the fragment definition in your layout XML file:</p>
+
+<img src="{@docRoot}images/tools/as-frag-ex.png" alt="" />
+
+<p class="img-caption"><strong>Figure 3.</strong> Supplying missing information</p>
+
+<h3>Picking a theme</h3>
+
+<p>To pick a theme for your app, click the Theme icon
+<img src="{@docRoot}images/tools/as-theme-icon.png" style="vertical-align:bottom;margin:0;height:19px" />.
+</p>
+
+<p>This displays the <strong>Select Theme</strong> dialog, where you can search for a
+particular theme and/or select one from the list on the right hand side. The theme you
+choose will be reflected in the previewed image.</p>
+
+<img src="{@docRoot}images/tools/as-theme-db.png" alt="" />
+
+<p class="img-caption"><strong>Figure 4.</strong> Specifying a theme.</p>
+
+<h3>Localization</h3>
+
+<p>Android Studio provides built-in localization support. When you click the
+localization icon
+<img src="{@docRoot}images/tools/as-i18n-icon.png" style="vertical-align:bottom;margin:0;height:19px" />,
+you can select a particular locale, add and edit translations, preview the locales your
+app supports (all locales or just a single locale), and preview right-to-left layout for
+languages that are RTL.</p>
+
+<p>See <a href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting
+Different Languages</a> for a description of how to support different locales in your app.</p>
+<p>For example, here is a preview of a "Hello World" app for the
+<img src="{@docRoot}images/tools/as-fr-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+locale:</p>
+
+<img src="{@docRoot}images/tools/as-fr-device.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> Previewing locales.</p>
+
+<h2>Editing in the Design View</h2>
+
+<p>You can switch to the graphical editor by clicking <strong>Design</strong> at the
+bottom of the window. While editing in the <strong>Design</strong> view, you can show and
+hide the widgets available to drag-and-drop by clicking <strong>Palette</strong> on the
+left side of the window. Clicking <strong>Designer</strong> on the right side of the
+window reveals a panel with a layout hierarchy and a list of properties for each view in
+the layout.</p>
+
+<p>When you drag a widget into the graphical layout for your app, the display changes to
+help you place the widget. What you see depends on the type of layout. For example, if
+you're dragging a widget into a {@link android.widget.FrameLayout}, it displays a grid to
+help you place the widget, as shown in figure 6:</p>
+
+<img src="{@docRoot}images/tools/as-grid-layout.png" alt="" />
+
+<p class="img-caption"><strong>Figure 6.</strong> Using the grid layout to place a widget.</p>
+
+<p>Within the graphical editor, you can rearrange your app's UI by dragging widgets to
+the desired location.</p>
+
+<h3>Taking a snapshot</h3>
+
+<p>When you run your app on a connected device, you can take a snapshot of it by clicking
+the camera icon
+<img src="{@docRoot}images/tools/as-camera-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+to the left of the logging
+panel (at the bottom of the window by default). This takes a snapshot of your running app
+(or whatever is currently displayed on your device) and displays it in a window. Check
+<strong>Frame Screenshot</strong> to show your screenshot within the device skin of your
+choice. You can also specify whether you want the image to have screen glare and/or a drop
+shadow. Once you have the desired effect, you can save the image.</p>
+
+<p>You can use the same process to create a snapshot of your app's preview. Just click the
+camera icon in the preview area and follow the steps for adding a device skin.</p>
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index 5a7e270..feb7a6e 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -318,6 +318,12 @@
<h2 id="Installing">Installing Android Studio</h2>
+<p>Android Studio requires JDK 6 or greater (JRE alone is not sufficient). To check if you
+have JDK installed (and which version), open a terminal and type <code>javac -version</code>.
+If JDK is not available or the version is lower than 6,
+<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">download
+JDK from here</a>.</p>
+<p>To install Android Studio:</p>
<ol>
<li>Download the <strong>Android Studio</strong> package from above.</li>
<li>Install Android Studio and the SDK tools:
diff --git a/docs/html/tools/help/logcat.jd b/docs/html/tools/help/logcat.jd
index ede1905..b30971e 100644
--- a/docs/html/tools/help/logcat.jd
+++ b/docs/html/tools/help/logcat.jd
@@ -45,7 +45,7 @@
<tr>
<td><code>-b <buffer></code></td>
- <td>Loads an alternate log buffer for viewing, such as <code>event</code> or
+ <td>Loads an alternate log buffer for viewing, such as <code>events</code> or
<code>radio</code>. The <code>main</code> buffer is used by default. See <a href=
"{@docRoot}tools/debugging/debugging-log.html#alternativeBuffers">Viewing Alternative Log Buffers</a>.</td>
</tr>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a8424e6..382165c 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -34,7 +34,9 @@
Migrating from Eclipse</a></li>
<li><a href="<?cs var:toroot ?>sdk/installing/studio-tips.html">
Tips and Tricks</a></li>
- </ul>
+ <li><a href="<?cs var:toroot ?>sdk/installing/studio-layout.html">
+ Using the Layout Editor</a></li>
+ </ul>
</li>
<li><a href="<?cs var:toroot ?>sdk/exploring.html">
<span class="en">Exploring the SDK</span></a></li>
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index 2615bee..179b3ac 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -75,16 +75,16 @@
<h2 id="LinearLayout">Create a Linear Layout</h2>
-<p>Open the <code>activity_main.xml</code> file from the <code>res/layout/</code>
+<p>Open the <code>fragment_main.xml</code> file from the <code>res/layout/</code>
directory.</p>
<p class="note"><strong>Note:</strong> In Eclipse, when you open a layout file, you’re first shown
the Graphical Layout editor. This is an editor that helps you build layouts using WYSIWYG tools. For this
-lesson, you’re going to work directly with the XML, so click the <em>activity_main.xml</em> tab at
+lesson, you’re going to work directly with the XML, so click the <em>fragment_main.xml</em> tab at
the bottom of the screen to open the XML editor.</p>
<p>The BlankActivity template you chose when you created this project includes the
-<code>activity_main.xml</code> file with a {@link
+<code>fragment_main.xml</code> file with a {@link
android.widget.RelativeLayout} root view and a {@link android.widget.TextView} child view.</p>
<p>First, delete the {@link android.widget.TextView <TextView>} element and change the {@link
@@ -95,7 +95,6 @@
The result looks like this:</p>
<pre>
-<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index 9516e37..50485db 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -120,8 +120,8 @@
<strong>Finish</strong>.</li>
</ol>
-<p>Your Android project is now set up with some default files and you’re ready to begin
-building the app. Continue to the <a href="running-app.html">next lesson</a>.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files.
+To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
@@ -155,8 +155,8 @@
projects.</p></li>
</ol>
-<p>Your Android project is now set up with several default configurations and you’re ready to begin
-building the app. Continue to the <a href="running-app.html">next lesson</a>.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files.
+To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
<p class="note"><strong>Tip:</strong> Add the <code>platform-tools/</code> as well as the
<code>tools/</code> directory to your <code>PATH</code> environment variable.</p>
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 999d399..23cedba 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -62,7 +62,7 @@
attributes. For your first app, it should look like this:</p>
<pre>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
- <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
...
</manifest>
</pre>
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index 712eabc..9aa25a3 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -45,7 +45,7 @@
<h2 id="RespondToButton">Respond to the Send Button</h2>
-<p>To respond to the button's on-click event, open the <code>activity_main.xml</code>
+<p>To respond to the button's on-click event, open the <code>fragment_main.xml</code>
layout file and add the <a
href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>
attribute to the {@link android.widget.Button <Button>} element:</p>
@@ -73,14 +73,6 @@
}
</pre>
-<p>This requires that you import the {@link android.view.View} class:</p>
-<pre>
-import android.view.View;
-</pre>
-
-<p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes
-(Cmd + Shift + O on Mac).</p>
-
<p>In order for the system to match this method to the method name given to <a
href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>,
the signature must be exactly as shown. Specifically, the method must:</p>
@@ -111,6 +103,14 @@
Intent intent = new Intent(this, DisplayMessageActivity.class);
</pre>
+<p>This requires that you import the {@link android.content.Intent} class:</p>
+<pre>
+import android.content.Intent;
+</pre>
+
+<p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes
+(Cmd + Shift + O on Mac).</p>
+
<p>The constructor used here takes two parameters:</p>
<ul>
<li>A {@link
@@ -151,9 +151,8 @@
</pre>
<p class="note"><strong>Note:</strong>
-You now need import statements for <code>android.content.Intent</code>
-and <code>android.widget.EditText</code>. You'll define the <code>EXTRA_MESSAGE</code>
-constant in a moment.</p>
+You now need an import statement for <code>android.widget.EditText</code>.
+You'll define the <code>EXTRA_MESSAGE</code> constant in a moment.</p>
<p>An {@link android.content.Intent} can carry a collection of various data types as key-value
pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the
@@ -165,7 +164,7 @@
MainActivity} class:</p>
<pre>
-public class MainActivity extends Activity {
+public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
...
}
@@ -223,6 +222,7 @@
<li><strong>Project</strong>: MyFirstApp</li>
<li><strong>Activity Name</strong>: DisplayMessageActivity</li>
<li><strong>Layout Name</strong>: activity_display_message</li>
+ <li><strong>Fragment Layout Name</strong>: fragment_display_message</li>
<li><strong>Title</strong>: My Message</li>
<li><strong>Hierarchial Parent</strong>: com.example.myfirstapp.MainActivity</li>
<li><strong>Navigation Type</strong>: None</li>
@@ -240,49 +240,65 @@
<ul>
<li>The class
already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()}
-method.</li>
+method. You will update the implementation of this method later.</li>
<li>There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu
onCreateOptionsMenu()} method, but
you won't need it for this app so you can remove it.</li>
<li>There's also an implementation of {@link android.app.Activity#onOptionsItemSelected
onOptionsItemSelected()} which handles the behavior for the action bar's <em>Up</em> behavior.
Keep this one the way it is.</li>
+ <li>There's also a <code>PlaceholderFragment</code> class that extends
+{@link android.app.Fragment}. You will not need this class in the final version of this
+activity.</li>
</ul>
-<p>Because the {@link android.app.ActionBar} APIs are available only on {@link
-android.os.Build.VERSION_CODES#HONEYCOMB} (API level 11) and higher, you must add a condition
-around the {@link android.app.Activity#getActionBar()} method to check the current platform version.
-Additionally, you must add the {@code @SuppressLint("NewApi")} tag to the
-{@link android.app.Activity#onCreate onCreate()} method to avoid <a
-href="{@docRoot}tools/help/lint.html">lint</a> errors.</p>
+<p>Fragments decompose application functionality and UI into reusable modules. For more
+information on fragments, see the <a href="{@docRoot}guide/components/fragments.html">Fragments
+API Guide</a>. The final version of this activity does not use fragments.</p>
<p>The {@code DisplayMessageActivity} class should now look like this:</p>
<pre>
-public class DisplayMessageActivity extends Activity {
+public class DisplayMessageActivity extends ActionBarActivity {
- @SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
- // Make sure we're running on Honeycomb or higher to use ActionBar APIs
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- // Show the Up button in the action bar.
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ if (savedInstanceState == null) {
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.container, new PlaceholderFragment()).commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- NavUtils.navigateUpFromSameTask(this);
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+ if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
+
+ /**
+ * A placeholder fragment containing a simple view.
+ */
+ public static class PlaceholderFragment extends Fragment {
+
+ public PlaceholderFragment() { }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_display_message,
+ container, false);
+ return rootView;
+ }
+ }
}
</pre>
@@ -422,7 +438,7 @@
<img src="{@docRoot}images/training/firstapp/firstapp.png" />
<p class="img-caption"><strong>Figure 2.</strong> Both activities in the final app, running
-on Android 4.0.
+on Android 4.4.
<p>That's it, you've built your first Android app!</p>
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 2ddbb7d..15ae238 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -596,6 +596,11 @@
MtpConstants.PROPERTY_DURATION,
MtpConstants.PROPERTY_GENRE,
MtpConstants.PROPERTY_COMPOSER,
+ MtpConstants.PROPERTY_AUDIO_WAVE_CODEC,
+ MtpConstants.PROPERTY_BITRATE_TYPE,
+ MtpConstants.PROPERTY_AUDIO_BITRATE,
+ MtpConstants.PROPERTY_NUMBER_OF_CHANNELS,
+ MtpConstants.PROPERTY_SAMPLE_RATE,
};
static final int[] VIDEO_PROPERTIES = {
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index ea75a18..82c6a80 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -1000,6 +1000,22 @@
MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
MtpObjectFormat format) {
+ static const int channelEnum[] = {
+ 1, // mono
+ 2, // stereo
+ 3, // 2.1
+ 4, // 3
+ 5, // 3.1
+ 6, // 4
+ 7, // 4.1
+ 8, // 5
+ 9, // 5.1
+ };
+ static const int bitrateEnum[] = {
+ 1, // fixed rate
+ 2, // variable rate
+ };
+
MtpProperty* result = NULL;
switch (property) {
case MTP_PROPERTY_OBJECT_FORMAT:
@@ -1013,6 +1029,7 @@
case MTP_PROPERTY_STORAGE_ID:
case MTP_PROPERTY_PARENT_OBJECT:
case MTP_PROPERTY_DURATION:
+ case MTP_PROPERTY_AUDIO_WAVE_CODEC:
result = new MtpProperty(property, MTP_TYPE_UINT32);
break;
case MTP_PROPERTY_OBJECT_SIZE:
@@ -1041,6 +1058,22 @@
// We allow renaming files and folders
result = new MtpProperty(property, MTP_TYPE_STR, true);
break;
+ case MTP_PROPERTY_BITRATE_TYPE:
+ result = new MtpProperty(property, MTP_TYPE_UINT16);
+ result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
+ break;
+ case MTP_PROPERTY_AUDIO_BITRATE:
+ result = new MtpProperty(property, MTP_TYPE_UINT32);
+ result->setFormRange(1, 1536000, 1);
+ break;
+ case MTP_PROPERTY_NUMBER_OF_CHANNELS:
+ result = new MtpProperty(property, MTP_TYPE_UINT16);
+ result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
+ break;
+ case MTP_PROPERTY_SAMPLE_RATE:
+ result = new MtpProperty(property, MTP_TYPE_UINT32);
+ result->setFormRange(8000, 48000, 1);
+ break;
}
return result;
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 31428b4..98d132a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Kleur-omkeringmodus"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Verbeterde kontrasmodus"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Kleurregstellingmodus"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"ONLANGS"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk word\ndalk gemonitor"</string>
<string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e393c90..d7457f0 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"የተቃራኒ ቀለም ሁነታ"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"የተሻሻለ ንፅፅር ሁነታ"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"የቀለም እርማት ሁነታ"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"የቅርብ ጊዜዎች"</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>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 0060004..d693e91 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"وضع انعكاس اللون"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"وضع التباين المحسن"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"وضع تصحيح الألوان"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1488864..dc53861 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим на инвертиране на цветовете"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим на подобрен контраст"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим на коригиране на цветовете"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 329e91f..e79e094 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversió de color"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode de contrast millorat"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correcció de color"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"És possible que la xarxa\nestigui controlada"</string>
<string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index b326220..60bbe3b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim převrácení barev"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekce barev"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"POSLEDNÍ"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Síť může být\nmonitorována"</string>
<string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index f0db449..5b9f633 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farveinverteringstilstand"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tilstand for forbedret kontrast"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Farvekorrigeringstilstand"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netværket kan\nvære overvåget"</string>
<string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index fd41752..c8cb0a4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farbinversionsmodus"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastverbesserungsmodus"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Farbkorrekturmodus"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"Letzte"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netzwerk wird\neventuell überwacht."</string>
<string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 96e2aaa..79025b6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Λειτουργία αναστροφής χρώματος"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Λειτουργία βελτίωσης αντίθεσης"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Λειτουργία διόρθωσης χρώματος"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"ΠΡΟΣΦΑΤΑ"</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>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 342061e..338c8ac 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
<string name="description_target_search" msgid="3091587249776033139">"Search"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 342061e..338c8ac 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
<string name="description_target_search" msgid="3091587249776033139">"Search"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index a82e2d7..89fe58b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Es posible que la red\nesté supervisada."</string>
<string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2a977ee..4999f71 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La red se\npuede supervisar"</string>
<string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 821c1dd..b734fa8 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Värvide ümberpööramise režiim"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Täiustatud kontrasti režiim"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Värviparandusrežiim"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"HILJUTISED"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Võrku võidakse\njälgida"</string>
<string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 2cb40a0..46caf79 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"حالت وارونگی رنگ"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"حالت کنتراست بهبودیافته"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 41a0bd4..6567318 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Käänteinen väritila"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastinparannustila"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Värinkorjaustila"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Verkkoa saatetaan\nvalvoa"</string>
<string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 60823b5..273fd9f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
<string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 5d6368e..0b0da12 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
<string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3167fe7..9be9550 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"रंग व्युत्क्रम मोड"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"उन्नत कंट्रास्ट मोड"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"हाल ही का"</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>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 529f891..21d6ef5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije boje"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način pojačanog kontrasta"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Način korekcije boje"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNO"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža se\nmožda prati"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 7e064dd..8e6ee4f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Színinvertálás mód"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrasztjavítás mód"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Színjavítás mód"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"LEGUTÓBBIAK"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Lehet, hogy a\nhálózat felügyelt"</string>
<string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
<string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 1124163..af14c76 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Գունաշրջման ռեժիմ"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Ընդլայնված ցայտունության ռեժիմ"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Գույների կարգավորման ռեժիմ"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 167b101..13fc534 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode inversi warna"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode kontras yang disempurnakan"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode koreksi warna"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"TERBARU"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Jaringan bisa\ndiawasi"</string>
<string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6321870..71a644d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modalità inversione colori"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modalità di contrasto avanzata"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modalità di correzione del colore"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"ELEMENTI RECENTI"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La rete potrebbe\nessere monitorata"</string>
<string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 24114f7..798e8c3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"מצב היפוך צבעים"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"מצב ניגודיות מוגברת"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"מצב תיקון צבע"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"אחרונים"</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>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0bee9f0..b0d15cf 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"色反転モード"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"拡張コントラストモード"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色補正モード"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index fe0a047..a4d459f 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"ფერთა ინვერსიის რეჟიმი"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"გაუმჯობესებული კონტრასტის რეჟიმი"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"ფერთა კორექციის რეჟიმი"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 470309a..d0d1c120 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"របៀបបញ្ច្រាសពណ៌"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"របៀបកម្រិតពណ៌ប្រសើរឡើង"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"របៀបកែពណ៌"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f72549d..bda4a95 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"색상 반전 모드"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"향상된 대비 모드"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"색상 보정 모드"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 59cf520..4503c4f 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"ໂໝດສະລັບສີ"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"ໂໝດຄວາມຕ່າງແສງ"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"ໂໝດການແກ້ໄຂສີ"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 29ca84a9..1d8b051 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Spalvų inversijos režimas"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Patobulinto kontrasto režimas"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Spalvų taisymo režimas"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"PASTARIEJI"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tinklas gali\nbūti stebimas"</string>
<string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4230b2e..603fa1a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Krāsu inversijas režīms"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Uzlabota kontrasta režīms"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Krāsu korekcijas režīms"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"JAUNĀKIE"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tīkls var\ntikt uzraudzīts"</string>
<string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index d6c68bc..6deb896 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Өнгө урвуулах горим"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Сайжруулсан ялгаралтай горим"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Өнгө залруулах горим"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 114d03e..2150bea 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod penyongsangan warna"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod kontras dipertingkat"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod pembetulan warna"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rangkaian mungkin\nboleh dipantau"</string>
<string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 12deaef..433aa7c 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus for fargeinvertering"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Forbedret kontrastmodus"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus for fargekorrigering"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nettverket kan\nvære overvåket"</string>
<string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 59c64b5..617aeb0 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus voor kleurinversie"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modus voor verbeterd contrast"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus voor kleurcorrectie"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk kan\nworden gecontroleerd"</string>
<string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b2628e1..c21230c 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Tryb odwrócenia kolorów"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tryb zwiększonego kontrastu"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Tryb korekcji kolorów"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"OSTATNIE"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieć może być\nmonitorowana"</string>
<string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index fc25ea8..d5c2e4c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cor"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste melhorado"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode ser\nmonitorizada"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e077fc6..21119e0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cores"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste aprimorado"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index adf54bc..33cb355 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -378,6 +378,8 @@
<skip />
<!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
<skip />
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
<skip />
<!-- no translation found for description_target_search (3091587249776033139) -->
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9cfb329..a8a7546 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod de inversare a culorilor"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod contrast îmbunătățit"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod de corectare a culorilor"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</string>
<string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 7a89d27..4aa67e7 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -208,6 +208,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Инверсия цвета"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Контрастность"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Коррекция цвета"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 13c60946..bc6a2f2 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim prevrátenia farieb"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieť môže byť\nmonitorovaná"</string>
<string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index a5b3244..7018188 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije barv"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način izboljšanega kontrasta"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Način popravljanja barv"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Omrežje je\nlahko spremljano"</string>
<string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 0bdccee..89bc3c5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим инверзије боје"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим унапређеног контраста"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим корекције боје"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"НАЈНОВИЈЕ"</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>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index efe7fcb..1b47be5 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Färginverteringsläge"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastförbättringsläge"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Färgkorrigeringsläge"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"NYA"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nätverket kan\nvara övervakat"</string>
<string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9336ade..08f8012 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -202,6 +202,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Hali ya ugeuzaji kinyume wa rangi"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Hali ya utofautishaji ulioboreshwa"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Hali ya kusahihisha rangi"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</string>
<string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 033e56d..98102dc 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"โหมดการกลับสี"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"โหมดคอนทราสต์ที่ปรับปรุงแล้ว"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"โหมดการแก้ไขสี"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 3704c48..403fc5f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode ng pag-invert ng kulay"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode na dinagdagan ang contrast"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode ng pagtatama ng kulay"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Maaaring\nsinusubaybayan ang network"</string>
<string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 56e5c88..c2f0d82 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Renk ters çevirme modu"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Geliştirilmiş kontrast modu"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Renk düzeltme modu"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ağ izleniyor\nolabilir"</string>
<string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3a474a4..9f7b961 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим інверсії кольорів"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим посиленого контрасту"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим коригування кольору"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 700c20d..96bc730 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -204,6 +204,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Chế độ đảo ngược màu sắc"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Chế độ tương phản tăng cường"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Chế độ hiệu chỉnh màu sắc"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mạng có thể\nđược giám sát"</string>
<string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 5909fbf..163c424 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"颜色反转模式"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"增强对比度模式"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"颜色校正模式"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index d229347..88a39ac 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"色彩反轉模式"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index bf2d7ce..9a59c78 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"彩色反轉模式"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
+ <!-- no translation found for recents_empty_message (2269156590813544104) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d676b5c..92e3382 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_inversion_label" msgid="1666358784283020762">"Imodi yokuguqulwa kombala"</string>
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Imodi ethuthukisiwe yokugqama"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Imodi yokulungisa umbala"</string>
+ <string name="recents_empty_message" msgid="2269156590813544104">"OKWAKAMUVA"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Kungenzeka inethiwekhi\niqashiwe"</string>
<string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Console.java b/packages/SystemUI/src/com/android/systemui/recents/Console.java
index b3d9ccf..db95193 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Console.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Console.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
@@ -36,20 +37,20 @@
/** Logs a key */
public static void log(String key) {
- Console.log(true, key, "", AnsiReset);
+ log(true, key, "", AnsiReset);
}
/** Logs a conditioned key */
public static void log(boolean condition, String key) {
if (condition) {
- Console.log(condition, key, "", AnsiReset);
+ log(condition, key, "", AnsiReset);
}
}
/** Logs a key in a specific color */
public static void log(boolean condition, String key, Object data) {
if (condition) {
- Console.log(condition, key, data, AnsiReset);
+ log(condition, key, data, AnsiReset);
}
}
@@ -74,6 +75,50 @@
}
}
+ /** Logs a stack trace */
+ public static void logStackTrace() {
+ logStackTrace("", 99);
+ }
+
+ /** Logs a stack trace to a certain depth */
+ public static void logStackTrace(int depth) {
+ logStackTrace("", depth);
+ }
+
+ /** Logs a stack trace to a certain depth with a key */
+ public static void logStackTrace(String key, int depth) {
+ int offset = 0;
+ StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+ String tinyStackTrace = "";
+ // Skip over the known stack trace classes
+ for (int i = 0; i < callStack.length; i++) {
+ StackTraceElement el = callStack[i];
+ String className = el.getClassName();
+ if (className.indexOf("dalvik.system.VMStack") == -1 &&
+ className.indexOf("java.lang.Thread") == -1 &&
+ className.indexOf("recents.Console") == -1) {
+ break;
+ } else {
+ offset++;
+ }
+ }
+ // Build the pretty stack trace
+ int start = Math.min(offset + depth, callStack.length);
+ int end = offset;
+ String indent = "";
+ for (int i = start - 1; i >= end; i--) {
+ StackTraceElement el = callStack[i];
+ tinyStackTrace += indent + " -> " + el.getClassName() +
+ "[" + el.getLineNumber() + "]." + el.getMethodName();
+ if (i > end) {
+ tinyStackTrace += "\n";
+ indent += " ";
+ }
+ }
+ log(true, key, tinyStackTrace, AnsiRed);
+ }
+
+
/** Returns the stringified MotionEvent action */
public static String motionEventActionToString(int action) {
switch (action) {
@@ -93,4 +138,25 @@
return "" + action;
}
}
+
+ public static String trimMemoryLevelToString(int level) {
+ switch (level) {
+ case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+ return "UI Hidden";
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+ return "Running Moderate";
+ case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+ return "Background";
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+ return "Running Low";
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ return "Moderate";
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+ return "Critical";
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ return "Complete";
+ default:
+ return "" + level;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index aeae4ab..57ebbc2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -30,9 +30,11 @@
public static final boolean EnableTaskStackClipping = false;
public static final boolean EnableBackgroundTaskLoading = true;
public static final boolean ForceDisableBackgroundCache = false;
+
public static final boolean TaskDataLoader = false;
public static final boolean SystemUIHandshake = false;
public static final boolean TimeSystemCalls = false;
+ public static final boolean Memory = false;
}
public static class UI {
@@ -41,7 +43,7 @@
public static final boolean TouchEvents = false;
public static final boolean MeasureAndLayout = false;
public static final boolean Clipping = false;
- public static final boolean HwLayers = true;
+ public static final boolean HwLayers = false;
}
public static class TaskStack {
@@ -55,13 +57,16 @@
public static class Values {
public static class Window {
+ // The dark background dim is set behind the empty recents view
public static final float DarkBackgroundDim = 0.5f;
+ // The background dim is set behind the card stack
public static final float BackgroundDim = 0.35f;
}
public static class RecentsTaskLoader {
// XXX: This should be calculated on the first load
public static final int PreloadFirstTasksCount = 5;
+ // For debugging, this allows us to multiply the number of cards for each task
public static final int TaskEntryMultiplier = 1;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index d050847..fc4d819 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
+import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.RecentsView;
@@ -168,6 +169,14 @@
}
@Override
+ public void onTrimMemory(int level) {
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ if (loader != null) {
+ loader.onTrimMemory(level);
+ }
+ }
+
+ @Override
public void onBackPressed() {
if (!mRecentsView.unfilterFilteredStacks()) {
super.onBackPressed();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index f3881ae..ed981ed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -30,7 +30,6 @@
DisplayMetrics mDisplayMetrics;
- public boolean layoutVerticalStack;
public Rect systemInsets = new Rect();
/** Private constructor */
@@ -56,7 +55,6 @@
boolean isPortrait = context.getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT;
- layoutVerticalStack = isPortrait || Constants.LANDSCAPE_LAYOUT_VERTICAL_STACK;
}
public void updateSystemInsets(Rect insets) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 522ab0f..13a3424 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -57,8 +57,9 @@
tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top);
tsv.boundScroll();
TaskViewTransform transform = tsv.getStackTransform(0);
+ Rect taskRect = new Rect(transform.rect);
- data.putParcelable("taskRect", transform.rect);
+ data.putParcelable("taskRect", taskRect);
Message reply = Message.obtain(null, MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
reply.setData(data);
msg.replyTo.send(reply);
@@ -100,4 +101,12 @@
Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onDestroy]");
super.onDestroy();
}
+
+ @Override
+ public void onTrimMemory(int level) {
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ if (loader != null) {
+ loader.onTrimMemory(level);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index c303ca7..96efed4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents;
import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
@@ -35,6 +36,7 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -233,7 +235,7 @@
@Override
protected int sizeOf(Task t, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than number of items
- return bitmap.getByteCount() / 1024;
+ return bitmap.getAllocationByteCount() / 1024;
}
}
@@ -247,17 +249,28 @@
TaskResourceLoadQueue mLoadQueue;
TaskResourceLoader mLoader;
+ int mMaxThumbnailCacheSize;
+ int mMaxIconCacheSize;
+
BitmapDrawable mDefaultIcon;
Bitmap mDefaultThumbnail;
/** Private Constructor */
private RecentsTaskLoader(Context context) {
+ // Calculate the cache sizes
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
- int iconCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 : maxMemory / 16;
- int thumbnailCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 : maxMemory / 8;
- Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ mMaxThumbnailCacheSize = maxMemory / 8;
+ mMaxIconCacheSize = mMaxThumbnailCacheSize / 4;
+ int iconCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 :
+ mMaxIconCacheSize;
+ int thumbnailCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 :
+ mMaxThumbnailCacheSize;
+
+ Console.log(Constants.DebugFlags.App.EnableBackgroundTaskLoading,
"[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
" iconCache: " + iconCacheSize);
+
+ // Initialize the cache and loaders
mLoadQueue = new TaskResourceLoadQueue();
mIconCache = new DrawableLruCache(iconCacheSize);
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
@@ -293,7 +306,7 @@
/** Reload the set of recent tasks */
SpaceNode reload(Context context, int preloadCount) {
- Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsTaskLoader|reload]");
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
TaskStack stack = new TaskStack(context);
SpaceNode root = new SpaceNode(context);
root.setStack(stack);
@@ -310,7 +323,7 @@
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
"[RecentsTaskLoader|getRecentTasks]",
"" + (System.currentTimeMillis() - t1) + "ms");
- Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[RecentsTaskLoader|tasks]", "" + tasks.size());
// Remove home/recents tasks
@@ -335,35 +348,51 @@
int taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = tasks.get(i);
-
- // Load the label, icon and thumbnail
ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(),
PackageManager.GET_META_DATA);
String title = info.loadLabel(pm).toString();
- Drawable icon = null;
- Bitmap thumbnail = null;
Task task;
- if (i >= (taskCount - preloadCount) || !Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ // Preload the specified number of apps
+ if (i >= (taskCount - preloadCount) ||
+ !Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[RecentsTaskLoader|preloadTask]",
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
- icon = info.loadIcon(pm);
- thumbnail = am.getTaskTopThumbnail(t.id);
- for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
- Console.log(Constants.DebugFlags.App.SystemUIHandshake,
- " [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
- task = new Task(t.persistentId, t.baseIntent, title, icon, thumbnail);
+
+ task = new Task(t.persistentId, t.baseIntent, title, null, null);
+
+ // Load the icon (if possible from the cache)
+ if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ task.icon = mIconCache.get(task);
+ }
+ if (task.icon == null) {
+ task.icon = info.loadIcon(pm);
if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- if (thumbnail != null) mThumbnailCache.put(task, thumbnail);
- if (icon != null) {
- mIconCache.put(task, icon);
- }
+ mIconCache.put(task, task.icon);
}
+ }
+
+ // Load the thumbnail (if possible from the cache)
+ if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ task.thumbnail = mThumbnailCache.get(task);
+ }
+ if (task.thumbnail == null) {
+ task.thumbnail = am.getTaskTopThumbnail(t.id);
+ if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ mThumbnailCache.put(task, task.thumbnail);
+ }
+ }
+
+ // Create as many tasks a we want to multiply by
+ for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
+ " [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
stack.addTask(task);
}
} else {
+ // Create as many tasks a we want to multiply by
for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
- Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
task = new Task(t.persistentId, t.baseIntent, title, null, null);
stack.addTask(task);
@@ -388,9 +417,9 @@
t1 = System.currentTimeMillis();
List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos();
Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms");
- Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsTaskLoader|stacks]", "" + tasks.size());
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size());
for (ActivityManager.StackInfo s : stackInfos) {
- Console.log(Constants.DebugFlags.App.SystemUIHandshake, " [RecentsTaskLoader|stack]", s.toString());
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, " [RecentsTaskLoader|stack]", s.toString());
if (stacks.containsKey(s.stackId)) {
stacks.get(s.stackId).setRect(s.bounds);
}
@@ -403,45 +432,46 @@
return root;
}
- /** Acquires the task resource data from the pool.
- * XXX: Move this into Task? */
+ /** Acquires the task resource data from the pool. */
public void loadTaskData(Task t) {
if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- t.icon = mIconCache.get(t);
- t.thumbnail = mThumbnailCache.get(t);
+ Drawable icon = mIconCache.get(t);
+ Bitmap thumbnail = mThumbnailCache.get(t);
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
- t + " icon: " + t.icon + " thumbnail: " + t.thumbnail);
+ t + " icon: " + icon + " thumbnail: " + thumbnail +
+ " thumbnailCacheSize: " + mThumbnailCache.size());
boolean requiresLoad = false;
- if (t.icon == null) {
- t.icon = mDefaultIcon;
+ if (icon == null) {
+ icon = mDefaultIcon;
requiresLoad = true;
}
- if (t.thumbnail == null) {
- t.thumbnail = mDefaultThumbnail;
+ if (thumbnail == null) {
+ thumbnail = mDefaultThumbnail;
requiresLoad = true;
}
if (requiresLoad) {
mLoadQueue.addTask(t);
}
+ t.notifyTaskLoaded(thumbnail, icon);
}
}
- /** Releases the task resource data back into the pool.
- * XXX: Move this into Task? */
+ /** Releases the task resource data back into the pool. */
public void unloadTaskData(Task t) {
if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
- "[RecentsTaskLoader|unloadTask]", t);
+ "[RecentsTaskLoader|unloadTask]", t +
+ " thumbnailCacheSize: " + mThumbnailCache.size());
mLoadQueue.removeTask(t);
- t.icon = mDefaultIcon;
- t.thumbnail = mDefaultThumbnail;
+ t.notifyTaskUnloaded(mDefaultThumbnail, mDefaultIcon);
+ } else {
+ t.notifyTaskUnloaded(null, null);
}
}
- /** Completely removes the resource data from the pool.
- * XXX: Move this into Task? */
+ /** Completely removes the resource data from the pool. */
public void deleteTaskData(Task t) {
if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
@@ -449,9 +479,10 @@
mLoadQueue.removeTask(t);
mThumbnailCache.remove(t);
mIconCache.remove(t);
+ t.notifyTaskUnloaded(mDefaultThumbnail, mDefaultIcon);
+ } else {
+ t.notifyTaskUnloaded(null, null);
}
- t.icon = mDefaultIcon;
- t.thumbnail = mDefaultThumbnail;
}
/** Stops the task loader */
@@ -460,4 +491,51 @@
mLoader.stop();
mLoadQueue.clearTasks();
}
+
+ void onTrimMemory(int level) {
+ Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|onTrimMemory]",
+ Console.trimMemoryLevelToString(level));
+
+ if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ // If we are hidden, then we should unload each of the task keys
+ if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|unloadTasks]"
+ );
+ // Unload each of the keys in the thumbnail cache
+ Map<Task, Bitmap> thumbnailCache = mThumbnailCache.snapshot();
+ for (Task t : thumbnailCache.keySet()) {
+ unloadTaskData(t);
+ }
+ // As well as the keys in the icon cache
+ Map<Task, Drawable> iconCache = mIconCache.snapshot();
+ for (Task t : iconCache.keySet()) {
+ unloadTaskData(t);
+ }
+ }
+
+ switch (level) {
+ case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+ case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+ // We are leaving recents, so trim the data a bit
+ mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
+ mIconCache.trimToSize(mMaxIconCacheSize / 2);
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ // We are going to be low on memory
+ mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
+ mIconCache.trimToSize(mMaxIconCacheSize / 4);
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ // We are low on memory, so release everything
+ mThumbnailCache.evictAll();
+ mIconCache.evictAll();
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 9b03c5d..378984c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -54,6 +54,24 @@
}
}
+ /** Notifies the callback listeners that this task has been loaded */
+ public void notifyTaskLoaded(Bitmap thumbnail, Drawable icon) {
+ this.icon = icon;
+ this.thumbnail = thumbnail;
+ if (mCb != null) {
+ mCb.onTaskBound();
+ }
+ }
+
+ /** Notifies the callback listeners that this task has been unloaded */
+ public void notifyTaskUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
+ icon = defaultIcon;
+ thumbnail = defaultThumbnail;
+ if (mCb != null) {
+ mCb.onTaskUnbound();
+ }
+ }
+
@Override
public boolean equals(Object o) {
// If we have multiple task entries for the same task, then we do the simple object
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
index 169f56c..712580d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
@@ -20,4 +20,8 @@
public interface TaskCallbacks {
/* Notifies when a task's data has been updated */
public void onTaskDataChanged(Task task);
+ /* Notifies when a task has been bound */
+ public void onTaskBound();
+ /* Notifies when a task has been unbound */
+ public void onTaskUnbound();
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index fe661bc..21ef9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -28,6 +28,8 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.animation.LinearInterpolator;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
/**
* This class facilitates swipe to dismiss. It defines an interface to be implemented by the
@@ -176,6 +178,9 @@
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ Console.log(Constants.DebugFlags.UI.TouchEvents,
+ "[SwipeHelper|interceptTouchEvent]",
+ Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
final int action = ev.getAction();
switch (action) {
@@ -200,7 +205,7 @@
if (Math.abs(delta) > mPagingTouchSlop) {
mCallback.onBeginDrag(mCurrView);
mDragging = true;
- mInitialTouchPos = getPos(ev) - getTranslation(mCurrView);
+ mInitialTouchPos = pos - getTranslation(mCurrView);
}
}
break;
@@ -286,6 +291,10 @@
}
public boolean onTouchEvent(MotionEvent ev) {
+ Console.log(Constants.DebugFlags.UI.TouchEvents,
+ "[SwipeHelper|touchEvent]",
+ Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+
if (!mDragging) {
if (!onInterceptTouchEvent(ev)) {
return mCanCurrViewBeDimissed;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 9dd6c0b..7753d69 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -435,19 +435,12 @@
mStackRectSansPeek.top += Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
// Compute the task rect
- if (RecentsConfiguration.getInstance().layoutVerticalStack) {
- int minHeight = (int) (mStackRect.height() -
- (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
- int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
- int centerX = mStackRect.centerX();
- mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
- centerX + size / 2, mStackRectSansPeek.top + size);
- } else {
- int size = Math.min(mStackRect.width(), mStackRect.height());
- int centerY = mStackRect.centerY();
- mTaskRect.set(mStackRectSansPeek.top, centerY - size / 2,
- mStackRectSansPeek.top + size, centerY + size / 2);
- }
+ int minHeight = (int) (mStackRect.height() -
+ (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
+ int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
+ int centerX = mStackRect.centerX();
+ mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
+ centerX + size / 2, mStackRectSansPeek.top + size);
// Update the scroll bounds
updateMinMaxScroll(false);
@@ -589,7 +582,6 @@
// Report that this tasks's data is no longer being used
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
loader.unloadTaskData(task);
- tv.unbindFromTask();
// Detach the view from the hierarchy
detachViewFromParent(tv);
@@ -610,7 +602,6 @@
// Request that this tasks's data be filled
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
loader.loadTaskData(task);
- tv.syncToTask();
// Find the index where this task should be placed in the children
int insertIndex = -1;
@@ -678,14 +669,13 @@
}
/* Handles touch events */
-class TaskStackViewTouchHandler {
+class TaskStackViewTouchHandler implements SwipeHelper.Callback {
static int INACTIVE_POINTER_ID = -1;
TaskStackView mSv;
VelocityTracker mVelocityTracker;
boolean mIsScrolling;
- boolean mIsSwiping;
int mInitialMotionX, mInitialMotionY;
int mLastMotionX, mLastMotionY;
@@ -697,21 +687,24 @@
int mMaximumVelocity;
// The scroll touch slop is used to calculate when we start scrolling
int mScrollTouchSlop;
- // The swipe touch slop is used to calculate when we start swiping left/right, this takes
- // precendence over the scroll touch slop in case the user makes a gesture that starts scrolling
- // but is intended to be a swipe
- int mSwipeTouchSlop;
- // After a certain amount of scrolling, we should start ignoring checks for swiping
- int mMaxScrollMotionToRejectSwipe;
+ // The page touch slop is used to calculate when we start swiping
+ float mPagingTouchSlop;
+
+ SwipeHelper mSwipeHelper;
+ boolean mInterceptedBySwipeHelper;
public TaskStackViewTouchHandler(Context context, TaskStackView sv) {
ViewConfiguration configuration = ViewConfiguration.get(context);
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mScrollTouchSlop = configuration.getScaledTouchSlop();
- mSwipeTouchSlop = 2 * mScrollTouchSlop;
- mMaxScrollMotionToRejectSwipe = 4 * mScrollTouchSlop;
+ mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
mSv = sv;
+
+
+ float densityScale = context.getResources().getDisplayMetrics().density;
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, mPagingTouchSlop);
+ mSwipeHelper.setMinAlpha(1f);
}
/** Velocity tracker helpers */
@@ -754,11 +747,18 @@
"[TaskStackViewTouchHandler|interceptTouchEvent]",
Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+ // Return early if we have no children
boolean hasChildren = (mSv.getChildCount() > 0);
if (!hasChildren) {
return false;
}
+ // Pass through to swipe helper if we are swiping
+ mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
+ if (mInterceptedBySwipeHelper) {
+ return true;
+ }
+
boolean wasScrolling = !mSv.mScroller.isFinished() ||
(mSv.mScrollAnimator != null && mSv.mScrollAnimator.isRunning());
int action = ev.getAction();
@@ -777,7 +777,8 @@
mVelocityTracker.addMovement(ev);
// Check if the scroller is finished yet
mIsScrolling = !mSv.mScroller.isFinished();
- mIsSwiping = false;
+ // Enable HW layers
+ mSv.addHwLayersRefCount();
break;
}
case MotionEvent.ACTION_MOVE: {
@@ -786,25 +787,7 @@
int activePointerIndex = ev.findPointerIndex(mActivePointerId);
int y = (int) ev.getY(activePointerIndex);
int x = (int) ev.getX(activePointerIndex);
- if (mActiveTaskView != null &&
- mTotalScrollMotion < mMaxScrollMotionToRejectSwipe &&
- Math.abs(x - mInitialMotionX) > Math.abs(y - mInitialMotionY) &&
- Math.abs(x - mInitialMotionX) > mSwipeTouchSlop) {
- // Start swiping and stop scrolling
- mIsScrolling = false;
- mIsSwiping = true;
- System.out.println("SWIPING: " + mActiveTaskView);
- // Initialize the velocity tracker if necessary
- initOrResetVelocityTracker();
- mVelocityTracker.addMovement(ev);
- // Disallow parents from intercepting touch events
- final ViewParent parent = mSv.getParent();
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- // Enable HW layers
- mSv.addHwLayersRefCount();
- } else if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
+ if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
// Save the touch move info
mIsScrolling = true;
// Initialize the velocity tracker if necessary
@@ -815,8 +798,6 @@
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
- // Enable HW layers
- mSv.addHwLayersRefCount();
}
mLastMotionX = x;
@@ -829,16 +810,17 @@
mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
// Reset the drag state and the velocity tracker
mIsScrolling = false;
- mIsSwiping = false;
mActivePointerId = INACTIVE_POINTER_ID;
mActiveTaskView = null;
mTotalScrollMotion = 0;
recycleVelocityTracker();
+ // Disable HW layers
+ mSv.decHwLayersRefCount();
break;
}
}
- return wasScrolling || mIsScrolling || mIsSwiping;
+ return wasScrolling || mIsScrolling;
}
/** Handles touch events once we have intercepted them */
@@ -853,6 +835,11 @@
return false;
}
+ // Pass through to swipe helper if we are swiping
+ if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
+ return true;
+ }
+
// Update the velocity tracker
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
@@ -871,7 +858,6 @@
// Initialize the velocity tracker
initOrResetVelocityTracker();
mVelocityTracker.addMovement(ev);
- // XXX: Set mIsScrolling or mIsSwiping?
// Disallow parents from intercepting touch events
final ViewParent parent = mSv.getParent();
if (parent != null) {
@@ -886,28 +872,7 @@
int x = (int) ev.getX(activePointerIndex);
int y = (int) ev.getY(activePointerIndex);
int deltaY = mLastMotionY - y;
- int deltaX = x - mLastMotionX;
- if (!mIsSwiping) {
- if (mActiveTaskView != null &&
- mTotalScrollMotion < mMaxScrollMotionToRejectSwipe &&
- Math.abs(x - mInitialMotionX) > Math.abs(y - mInitialMotionY) &&
- Math.abs(x - mInitialMotionX) > mSwipeTouchSlop) {
- mIsScrolling = false;
- mIsSwiping = true;
- System.out.println("SWIPING: " + mActiveTaskView);
- // Initialize the velocity tracker if necessary
- initOrResetVelocityTracker();
- mVelocityTracker.addMovement(ev);
- // Disallow parents from intercepting touch events
- final ViewParent parent = mSv.getParent();
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- // Enable HW layers
- mSv.addHwLayersRefCount();
- }
- }
- if (!mIsSwiping && !mIsScrolling) {
+ if (!mIsScrolling) {
if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
mIsScrolling = true;
// Initialize the velocity tracker
@@ -927,8 +892,6 @@
if (mSv.isScrollOutOfBounds()) {
mVelocityTracker.clear();
}
- } else if (mIsSwiping) {
- mActiveTaskView.setTranslationX(mActiveTaskView.getTranslationX() + deltaX);
}
mLastMotionX = x;
mLastMotionY = y;
@@ -936,107 +899,33 @@
break;
}
case MotionEvent.ACTION_UP: {
- if (mIsScrolling || mIsSwiping) {
- final TaskView activeTv = mActiveTaskView;
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
- if (mIsSwiping) {
- int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
- if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
- // Fling to dismiss
- int newScrollX = (int) (Math.signum(initialVelocity) *
- activeTv.getMeasuredWidth());
- int duration = Math.min(Constants.Values.TaskStackView.Animation.SwipeDismissDuration,
- (int) (Math.abs(newScrollX - activeTv.getScrollX()) *
- 1000f / Math.abs(initialVelocity)));
- activeTv.animate()
- .translationX(newScrollX)
- .alpha(0f)
- .setDuration(duration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- Task task = activeTv.getTask();
- Activity activity = (Activity) mSv.getContext();
-
- // We have to disable the listener to ensure that we
- // don't hit this again
- activeTv.animate().setListener(null);
-
- // Remove the task from the view
- mSv.mStack.removeTask(task);
-
- // Remove any stored data from the loader
- RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- loader.deleteTaskData(task);
-
- // Remove the task from activity manager
- final ActivityManager am = (ActivityManager)
- activity.getSystemService(Context.ACTIVITY_SERVICE);
- if (am != null) {
- am.removeTask(activeTv.getTask().id,
- ActivityManager.REMOVE_TASK_KILL_PROCESS);
- }
-
- // If there are no remaining tasks, then just close the activity
- if (mSv.mStack.getTaskCount() == 0) {
- activity.finish();
- }
-
- // Disable HW layers
- mSv.decHwLayersRefCount();
- }
- })
- .start();
- // Enable HW layers
- mSv.addHwLayersRefCount();
- } else {
- // Animate it back into place
- // XXX: Make this animation a function of the velocity OR distance
- int duration = Constants.Values.TaskStackView.Animation.SwipeSnapBackDuration;
- activeTv.animate()
- .translationX(0)
- .setDuration(duration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Disable HW layers
- mSv.decHwLayersRefCount();
- }
- })
- .start();
- // Enable HW layers
- mSv.addHwLayersRefCount();
- }
- } else {
- int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
- if ((Math.abs(velocity) > mMinimumVelocity)) {
- Console.log(Constants.DebugFlags.UI.TouchEvents,
- "[TaskStackViewTouchHandler|fling]",
- "scroll: " + mSv.getStackScroll() + " velocity: " + velocity,
- Console.AnsiGreen);
- // Enable HW layers on the stack
- mSv.addHwLayersRefCount();
- // Fling scroll
- mSv.mScroller.fling(0, mSv.getStackScroll(),
- 0, -velocity,
- 0, 0,
- mSv.mMinScroll, mSv.mMaxScroll,
- 0, 0);
- // Invalidate to kick off computeScroll
- mSv.invalidate();
- } else if (mSv.isScrollOutOfBounds()) {
- // Animate the scroll back into bounds
- // XXX: Make this animation a function of the velocity OR distance
- mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
- }
- }
+ if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
+ Console.log(Constants.DebugFlags.UI.TouchEvents,
+ "[TaskStackViewTouchHandler|fling]",
+ "scroll: " + mSv.getStackScroll() + " velocity: " + velocity,
+ Console.AnsiGreen);
+ // Enable HW layers on the stack
+ mSv.addHwLayersRefCount();
+ // Fling scroll
+ mSv.mScroller.fling(0, mSv.getStackScroll(),
+ 0, -velocity,
+ 0, 0,
+ mSv.mMinScroll, mSv.mMaxScroll,
+ 0, 0);
+ // Invalidate to kick off computeScroll
+ mSv.invalidate();
+ } else if (mSv.isScrollOutOfBounds()) {
+ // Animate the scroll back into bounds
+ // XXX: Make this animation a function of the velocity OR distance
+ mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
}
mActivePointerId = INACTIVE_POINTER_ID;
mIsScrolling = false;
- mIsSwiping = false;
mTotalScrollMotion = 0;
recycleVelocityTracker();
// Disable HW layers
@@ -1044,25 +933,14 @@
break;
}
case MotionEvent.ACTION_CANCEL: {
- if (mIsScrolling || mIsSwiping) {
- if (mIsSwiping) {
- // Animate it back into place
- // XXX: Make this animation a function of the velocity OR distance
- int duration = Constants.Values.TaskStackView.Animation.SwipeSnapBackDuration;
- mActiveTaskView.animate()
- .translationX(0)
- .setDuration(duration)
- .start();
- } else {
- // Animate the scroll back into bounds
- // XXX: Make this animation a function of the velocity OR distance
- mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
- }
+ if (mSv.isScrollOutOfBounds()) {
+ // Animate the scroll back into bounds
+ // XXX: Make this animation a function of the velocity OR distance
+ mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
}
mActivePointerId = INACTIVE_POINTER_ID;
mIsScrolling = false;
- mIsSwiping = false;
mTotalScrollMotion = 0;
recycleVelocityTracker();
// Disable HW layers
@@ -1072,4 +950,72 @@
}
return true;
}
+
+ /**** SwipeHelper Implementation ****/
+
+ @Override
+ public View getChildAtPosition(MotionEvent ev) {
+ return findViewAtPoint((int) ev.getX(), (int) ev.getY());
+ }
+
+ @Override
+ public boolean canChildBeDismissed(View v) {
+ return true;
+ }
+
+ @Override
+ public void onBeginDrag(View v) {
+ // Enable HW layers
+ mSv.addHwLayersRefCount();
+ // Disallow parents from intercepting touch events
+ final ViewParent parent = mSv.getParent();
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ }
+
+ @Override
+ public void onChildDismissed(View v) {
+ TaskView tv = (TaskView) v;
+ Task task = tv.getTask();
+ Activity activity = (Activity) mSv.getContext();
+
+ // We have to disable the listener to ensure that we
+ // don't hit this again
+ tv.animate().setListener(null);
+
+ // Remove the task from the view
+ mSv.mStack.removeTask(task);
+
+ // Remove any stored data from the loader
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ loader.deleteTaskData(task);
+
+ // Remove the task from activity manager
+ final ActivityManager am = (ActivityManager)
+ activity.getSystemService(Context.ACTIVITY_SERVICE);
+ if (am != null) {
+ am.removeTask(tv.getTask().id,
+ ActivityManager.REMOVE_TASK_KILL_PROCESS);
+ }
+
+ // If there are no remaining tasks, then just close the activity
+ if (mSv.mStack.getTaskCount() == 0) {
+ activity.finish();
+ }
+
+ // Disable HW layers
+ mSv.decHwLayersRefCount();
+ }
+
+ @Override
+ public void onSnapBackCompleted(View v) {
+ // Do Nothing
+ }
+
+ @Override
+ public void onDragCancelled(View v) {
+ // Disable HW layers
+ mSv.decHwLayersRefCount();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index b1d0d13..9ef74ca 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -255,13 +255,13 @@
}
/** Actually synchronizes the model data into the views */
- void syncToTask() {
+ private void syncToTask() {
mThumbnailView.rebindToTask(mTask, false);
mIconView.rebindToTask(mTask, false);
}
/** Unset the task and callback */
- void unbindFromTask() {
+ private void unbindFromTask() {
mTask.setCallbacks(null);
mThumbnailView.unbindFromTask();
mIconView.unbindFromTask();
@@ -357,16 +357,16 @@
/** Enable the hw layers on this task view */
void enableHwLayers() {
- Console.log(Constants.DebugFlags.UI.HwLayers, "[TaskView|enableHwLayers]");
mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
/** Disable the hw layers on this task view */
void disableHwLayers() {
- Console.log(Constants.DebugFlags.UI.HwLayers, "[TaskView|disableHwLayers]");
mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null);
}
+ /**** TaskCallbacks Implementation ****/
+
@Override
public void onTaskDataChanged(Task task) {
Console.log(Constants.DebugFlags.App.EnableBackgroundTaskLoading,
@@ -380,6 +380,16 @@
}
@Override
+ public void onTaskBound() {
+ syncToTask();
+ }
+
+ @Override
+ public void onTaskUnbound() {
+ unbindFromTask();
+ }
+
+ @Override
public void onClick(View v) {
mCb.onTaskIconClicked(this);
}
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index b9b87b1..e45b98c 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -340,6 +340,13 @@
getWindowManager());
// Get the crop
RectF cropRect = mCropView.getCrop();
+
+ // Due to rounding errors in the cropview renderer the edges can be slightly offset
+ // therefore we ensure that the boundaries are sanely defined
+ cropRect.left = Math.max(0, cropRect.left);
+ cropRect.right = Math.min(mCropView.getWidth(), cropRect.right);
+ cropRect.top = Math.max(0, cropRect.top);
+ cropRect.bottom = Math.min(mCropView.getHeight(), cropRect.bottom);
int cropRotation = mCropView.getImageRotation();
float cropScale = mCropView.getWidth() / (float) cropRect.width();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 15a68ef..1cca164 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3417,18 +3417,22 @@
&& attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
mTopFullscreenOpaqueWindowState = win;
- if (showWhenLocked && !mHideWindowBehindKeyguard) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
- if ((fl & FLAG_DISMISS_KEYGUARD) != 0
- && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
- mDismissKeyguard = mWinDismissingKeyguard == win ?
- DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
- mWinDismissingKeyguard = win;
- mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+ if (!mHideWindowBehindKeyguard) {
+ if (showWhenLocked) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Setting mHideLockScreen to true by win " + win);
+ mHideLockScreen = true;
+ mForceStatusBarFromKeyguard = false;
+ }
+ if ((fl & FLAG_DISMISS_KEYGUARD) != 0
+ && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Setting mDismissKeyguard true by win " + win);
+ mDismissKeyguard = mWinDismissingKeyguard == win ?
+ DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+ mWinDismissingKeyguard = win;
+ mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+ }
}
if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
mAllowLockscreenWhenOn = true;
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 399e7d1..0f78c9b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -52,12 +52,12 @@
# NotificationManagerService.java
# ---------------------------
# when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
+2750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
# when someone tries to cancel a notification, the notification manager sometimes
# calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2751 notification_cancel (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
# when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2752 notification_cancel_all (uid|1|5),(pid|1|5),(pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
# ---------------------------
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 3dcb488..e6163bd 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -457,6 +457,9 @@
* @param userId the new active user's UserId
*/
private void switchUser(int userId) {
+ if (mCurrentUserId == userId) {
+ return;
+ }
mBlacklist.switchUser(userId);
mLocationHandler.removeMessages(MSG_LOCATION_CHANGED);
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index c9f9a25..1ed943c 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -142,25 +142,40 @@
class DefaultState extends State {
@Override
public boolean processMessage(Message msg) {
+ ClientInfo cInfo = null;
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
AsyncChannel c = (AsyncChannel) msg.obj;
if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
- ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
+ cInfo = new ClientInfo(c, msg.replyTo);
mClients.put(msg.replyTo, cInfo);
} else {
Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
}
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
- Slog.e(TAG, "Send failed, client connection lost");
- } else {
- if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+ switch (msg.arg1) {
+ case AsyncChannel.STATUS_SEND_UNSUCCESSFUL:
+ Slog.e(TAG, "Send failed, client connection lost");
+ break;
+ case AsyncChannel.STATUS_REMOTE_DISCONNECTION:
+ if (DBG) Slog.d(TAG, "Client disconnected");
+ break;
+ default:
+ if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+ break;
}
- mClients.remove(msg.replyTo);
+ cInfo = mClients.get(msg.replyTo);
+ if (cInfo != null) {
+ cInfo.expungeAllRequests();
+ mClients.remove(msg.replyTo);
+ }
+ //Last client
+ if (mClients.size() == 0) {
+ stopMDnsDaemon();
+ }
break;
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
AsyncChannel ac = new AsyncChannel();
@@ -238,13 +253,15 @@
return false;
}
- private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+ private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo, int what) {
clientInfo.mClientIds.put(clientId, globalId);
+ clientInfo.mClientRequests.put(clientId, what);
mIdToClientInfoMap.put(globalId, clientInfo);
}
private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
clientInfo.mClientIds.remove(clientId);
+ clientInfo.mClientRequests.remove(clientId);
mIdToClientInfoMap.remove(globalId);
}
@@ -264,10 +281,6 @@
result = NOT_HANDLED;
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- //Last client
- if (mClients.size() == 1) {
- stopMDnsDaemon();
- }
result = NOT_HANDLED;
break;
case NsdManager.DISABLE:
@@ -291,7 +304,7 @@
Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
servInfo.getServiceType());
}
- storeRequestMap(msg.arg2, id, clientInfo);
+ storeRequestMap(msg.arg2, id, clientInfo, msg.what);
replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
} else {
stopServiceDiscovery(id);
@@ -330,7 +343,7 @@
id = getUniqueId();
if (registerService(id, (NsdServiceInfo) msg.obj)) {
if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
- storeRequestMap(msg.arg2, id, clientInfo);
+ storeRequestMap(msg.arg2, id, clientInfo, msg.what);
// Return success after mDns reports success
} else {
unregisterService(id);
@@ -371,7 +384,7 @@
id = getUniqueId();
if (resolveService(id, servInfo)) {
clientInfo.mResolvedService = new NsdServiceInfo();
- storeRequestMap(msg.arg2, id, clientInfo);
+ storeRequestMap(msg.arg2, id, clientInfo, msg.what);
} else {
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR);
@@ -477,7 +490,7 @@
int id2 = getUniqueId();
if (getAddrInfo(id2, cooked[3])) {
- storeRequestMap(clientId, id2, clientInfo);
+ storeRequestMap(clientId, id2, clientInfo, NsdManager.RESOLVE_SERVICE);
} else {
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
@@ -821,6 +834,9 @@
/* A map from client id to unique id sent to mDns */
private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
+ /* A map from client id to the type of the request we had received */
+ private SparseArray<Integer> mClientRequests = new SparseArray<Integer>();
+
private ClientInfo(AsyncChannel c, Messenger m) {
mChannel = c;
mMessenger = m;
@@ -834,10 +850,41 @@
sb.append("mMessenger ").append(mMessenger).append("\n");
sb.append("mResolvedService ").append(mResolvedService).append("\n");
for(int i = 0; i< mClientIds.size(); i++) {
- sb.append("clientId ").append(mClientIds.keyAt(i));
- sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
+ int clientID = mClientIds.keyAt(i);
+ sb.append("clientId ").append(clientID).
+ append(" mDnsId ").append(mClientIds.valueAt(i)).
+ append(" type ").append(mClientRequests.get(clientID)).append("\n");
}
return sb.toString();
}
+
+ // Remove any pending requests from the global map when we get rid of a client,
+ // and send cancellations to the daemon.
+ private void expungeAllRequests() {
+ int globalId, clientId, i;
+ for (i = 0; i < mClientIds.size(); i++) {
+ clientId = mClientIds.keyAt(i);
+ globalId = mClientIds.valueAt(i);
+ mIdToClientInfoMap.remove(globalId);
+ if (DBG) Slog.d(TAG, "Terminating client-ID " + clientId +
+ " global-ID " + globalId + " type " + mClientRequests.get(clientId));
+ switch (mClientRequests.get(clientId)) {
+ case NsdManager.DISCOVER_SERVICES:
+ stopServiceDiscovery(globalId);
+ break;
+ case NsdManager.RESOLVE_SERVICE:
+ stopResolveService(globalId);
+ break;
+ case NsdManager.REGISTER_SERVICE:
+ unregisterService(globalId);
+ break;
+ default:
+ break;
+ }
+ }
+ mClientIds.clear();
+ mClientRequests.clear();
+ }
+
}
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index ad693d0..94f699f 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -173,7 +173,9 @@
mDeskModeKeepsScreenOn = (context.getResources().getInteger(
com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
mTelevision = context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TELEVISION);
+ PackageManager.FEATURE_TELEVISION) ||
+ context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK);
mNightMode = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 128f636..ab7d60a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3319,20 +3319,35 @@
return;
}
// Remove any existing entries that are the same kind of task.
+ final Intent intent = task.intent;
+ final boolean document = intent != null && intent.isDocument();
for (int i=0; i<N; i++) {
TaskRecord tr = mRecentTasks.get(i);
- if (task.userId == tr.userId
- && ((task.affinity != null && task.affinity.equals(tr.affinity))
- || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
- tr.disposeThumbnail();
- mRecentTasks.remove(i);
- i--;
- N--;
- if (task.intent == null) {
- // If the new recent task we are adding is not fully
- // specified, then replace it with the existing recent task.
- task = tr;
+ if (task != tr) {
+ if (task.userId != tr.userId) {
+ continue;
}
+ final Intent trIntent = tr.intent;
+ if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
+ (intent == null || !intent.filterEquals(trIntent))) {
+ continue;
+ }
+ if (document || trIntent != null && trIntent.isDocument()) {
+ // Document tasks do not match other tasks.
+ continue;
+ }
+ }
+
+ // Either task and tr are the same or, their affinities match or their intents match
+ // and neither of them is a document.
+ tr.disposeThumbnail();
+ mRecentTasks.remove(i);
+ i--;
+ N--;
+ if (task.intent == null) {
+ // If the new recent task we are adding is not fully
+ // specified, then replace it with the existing recent task.
+ task = tr;
}
}
if (N >= MAX_RECENT_TASKS) {
@@ -7047,11 +7062,11 @@
* TODO: Add mController hook
*/
@Override
- public void moveTaskToFront(int task, int flags, Bundle options) {
+ public void moveTaskToFront(int taskId, int flags, Bundle options) {
enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
"moveTaskToFront()");
- if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
+ if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
synchronized(this) {
if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Binder.getCallingUid(), "Task to front")) {
@@ -7060,6 +7075,14 @@
}
final long origId = Binder.clearCallingIdentity();
try {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ return;
+ }
+ if (mStackSupervisor.isLockTaskModeViolation(task)) {
+ Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+ return;
+ }
mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
} finally {
Binder.restoreCallingIdentity(origId);
@@ -7269,6 +7292,85 @@
}
}
+ private boolean isLockTaskAuthorized(ComponentName name) {
+// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+// "startLockTaskMode()");
+// DevicePolicyManager dpm = (DevicePolicyManager)
+// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+// return dpm != null && dpm.isLockTaskPermitted(name);
+ return true;
+ }
+
+ private void startLockTaskMode(TaskRecord task) {
+ if (!isLockTaskAuthorized(task.intent.getComponent())) {
+ return;
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ // Since we lost lock on task, make sure it is still there.
+ task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
+ if (task != null) {
+ mStackSupervisor.setLockTaskModeLocked(task);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void startLockTaskMode(int taskId) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ final TaskRecord task;
+ synchronized (this) {
+ task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ }
+ if (task != null) {
+ startLockTaskMode(task);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void startLockTaskMode(IBinder token) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ final TaskRecord task;
+ synchronized (this) {
+ final ActivityRecord r = ActivityRecord.forToken(token);
+ if (r == null) {
+ return;
+ }
+ task = r.task;
+ }
+ if (task != null) {
+ startLockTaskMode(task);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void stopLockTaskMode() {
+// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+// "stopLockTaskMode()");
+ synchronized (this) {
+ mStackSupervisor.setLockTaskModeLocked(null);
+ }
+ }
+
+ @Override
+ public boolean isInLockTaskMode() {
+ synchronized (this) {
+ return mStackSupervisor.isInLockTaskMode();
+ }
+ }
+
// =========================================================
// THUMBNAILS
// =========================================================
@@ -16186,6 +16288,8 @@
return true;
}
+ mStackSupervisor.setLockTaskModeLocked(null);
+
final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
if (userInfo == null) {
Slog.w(TAG, "No user info for user #" + userId);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 087ad83c..25292a0 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -36,8 +36,6 @@
import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
-import android.os.Trace;
-import android.util.Log;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService.ItemMatcher;
@@ -494,6 +492,9 @@
cls = new ComponentName(info.packageName, info.targetActivity);
}
final int userId = UserHandle.getUserId(info.applicationInfo.uid);
+ boolean isDocument = intent != null & intent.isDocument();
+ // If documentData is non-null then it must match the existing task data.
+ Uri documentData = isDocument ? intent.getData() : null;
if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this);
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -510,23 +511,39 @@
continue;
}
+ final Intent taskIntent = task.intent;
+ final Intent affinityIntent = task.affinityIntent;
+ final boolean taskIsDocument;
+ final Uri taskDocumentData;
+ if (taskIntent != null && taskIntent.isDocument()) {
+ taskIsDocument = true;
+ taskDocumentData = taskIntent.getData();
+ } else if (affinityIntent != null && affinityIntent.isDocument()) {
+ taskIsDocument = true;
+ taskDocumentData = affinityIntent.getData();
+ } else {
+ taskIsDocument = false;
+ taskDocumentData = null;
+ }
+
if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
- + r.task.intent.getComponent().flattenToShortString()
+ + taskIntent.getComponent().flattenToShortString()
+ "/aff=" + r.task.affinity + " to new cls="
+ intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
- if (task.affinity != null) {
- if (task.affinity.equals(info.taskAffinity)) {
+ if (!isDocument && !taskIsDocument && task.affinity != null) {
+ if (task.affinity.equals(target.taskAffinity)) {
if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
return r;
}
- } else if (task.intent != null && task.intent.getComponent().equals(cls)) {
+ } else if (taskIntent != null && taskIntent.getComponent().equals(cls) &&
+ Objects.equals(documentData, taskDocumentData)) {
if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
//dump();
if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
+ r.intent);
return r;
- } else if (task.affinityIntent != null
- && task.affinityIntent.getComponent().equals(cls)) {
+ } else if (affinityIntent != null && affinityIntent.getComponent().equals(cls) &&
+ Objects.equals(documentData, taskDocumentData)) {
if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
//dump();
if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
@@ -1859,7 +1876,7 @@
// If the caller has requested that the target task be
// reset, then do so.
if ((r.intent.getFlags()
- &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
+ & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
resetTaskIfNeededLocked(r, r);
doShow = topRunningNonDelayedActivityLocked(null) == r;
}
@@ -2008,14 +2025,7 @@
+ " out to new task " + target.task);
}
- if (clearWhenTaskReset) {
- // This is the start of a new sub-task.
- if (target.thumbHolder == null) {
- target.thumbHolder = new ThumbnailHolder();
- }
- } else {
- target.thumbHolder = newThumbHolder;
- }
+ target.thumbHolder = newThumbHolder;
final int targetTaskId = targetTask.taskId;
mWindowManager.setAppGroupId(target.appToken, targetTaskId);
@@ -2478,14 +2488,15 @@
}
r.makeFinishing();
+ final TaskRecord task = r.task;
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
r.userId, System.identityHashCode(r),
- r.task.taskId, r.shortComponentName, reason);
- final ArrayList<ActivityRecord> activities = r.task.mActivities;
+ task.taskId, r.shortComponentName, reason);
+ final ArrayList<ActivityRecord> activities = task.mActivities;
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) {
- r.task.setFrontOfTask();
- if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+ task.setFrontOfTask();
+ if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked that this activity (and all above it)
// be cleared when the task is reset, don't lose that information,
// but propagate it up to the next activity.
@@ -2524,6 +2535,9 @@
startPausingLocked(false, false);
}
+ if (endTask) {
+ mStackSupervisor.endLockTaskModeIfTaskEnding(task);
+ }
} else if (r.state != ActivityState.PAUSING) {
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
@@ -3088,23 +3102,6 @@
}
}
- final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
- final TaskRecord task = taskForIdLocked(taskId);
- if (task != null) {
- if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
- mStackSupervisor.mUserLeaving = true;
- }
- 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.mOnTopOfHome = true;
- }
- moveTaskToFrontLocked(task, null, options);
- return true;
- }
- return false;
- }
-
final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
@@ -3162,7 +3159,15 @@
* @return Returns true if the move completed, false if not.
*/
final boolean moveTaskToBackLocked(int taskId, ActivityRecord reason) {
- Slog.i(TAG, "moveTaskToBack: " + taskId);
+ final TaskRecord tr = taskForIdLocked(taskId);
+ if (tr == null) {
+ Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
+ return false;
+ }
+
+ Slog.i(TAG, "moveTaskToBack: " + tr);
+
+ mStackSupervisor.endLockTaskModeIfTaskEnding(tr);
// If we have a watcher, preflight the move before committing to it. First check
// for *other* available tasks, but if none are available, then try again allowing the
@@ -3190,11 +3195,6 @@
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare to back transition: task=" + taskId);
- final TaskRecord tr = taskForIdLocked(taskId);
- if (tr == null) {
- return false;
- }
-
mTaskHistory.remove(tr);
mTaskHistory.add(0, tr);
@@ -3678,6 +3678,7 @@
}
void removeTask(TaskRecord task) {
+ mStackSupervisor.endLockTaskModeIfTaskEnding(task);
mWindowManager.removeTask(task.taskId);
final ActivityRecord r = mResumedActivity;
if (r != null && r.task == task) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b2cf846..3555993 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -231,6 +232,10 @@
InputManagerInternal mInputManagerInternal;
+ /** If non-null then the task specified remains in front and no other tasks may be started
+ * until the task exits or #stopLockTaskMode() is called. */
+ private TaskRecord mLockTaskModeTask;
+
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
@@ -1198,6 +1203,19 @@
resultRecord.removeResultsLocked(
sourceRecord, resultWho, requestCode);
}
+ if (sourceRecord.launchedFromUid == callingUid) {
+ // The new activity is being launched from the same uid as the previous
+ // activity in the flow, and asking to forward its result back to the
+ // previous. In this case the activity is serving as a trampoline between
+ // the two, so we also want to update its launchedFromPackage to be the
+ // same as the previous activity. Note that this is safe, since we know
+ // these two packages come from the same uid; the caller could just as
+ // well have supplied that same package name itself. This specifially
+ // deals with the case of an intent picker/chooser being launched in the app
+ // flow to redirect to an activity picked by the user, where we want the final
+ // activity to consider it to have been launched by the previous app activity.
+ callingPackage = sourceRecord.launchedFromPackage;
+ }
}
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
@@ -1426,14 +1444,20 @@
}
}
+ final boolean newDocument = intent.isDocument();
if (sourceRecord == null) {
// This activity is not being started from another... in this
// case we -always- start a new task.
- if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+ if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
"Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
+ } else if (newDocument) {
+ if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
+ Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
+ r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ }
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// The original activity who is starting us is running as a single
// instance... this new activity it is starting must go on its
@@ -1456,7 +1480,7 @@
// so we don't want to blindly throw it in to that task. Instead we will take
// the NEW_TASK flow and try to find a task for it. But save the task information
// so it can be used when creating the new task.
- if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+ if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Slog.w(TAG, "startActivity called from finishing " + sourceRecord
+ "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -1472,7 +1496,7 @@
sourceStack = null;
}
- if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+ if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
// For whatever reason this activity is being launched into a new
// task... yet the caller has requested a result back. Well, that
// is pretty messed up, so instead immediately send back a cancel
@@ -1489,8 +1513,8 @@
boolean movedHome = false;
TaskRecord reuseTask = null;
ActivityStack targetStack;
- if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
- (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
+ if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
+ (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// If bring to front is requested, and no result is requested, and
@@ -1505,6 +1529,10 @@
? findTaskLocked(r)
: findActivityLocked(intent, r.info);
if (intentActivity != null) {
+ if (isLockTaskModeViolation(intentActivity.task)) {
+ Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+ return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+ }
if (r.task == null) {
r.task = intentActivity.task;
}
@@ -1675,7 +1703,7 @@
if (top != null && r.resultTo == null) {
if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
if (top.app != null && top.app.thread != null) {
- if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+ if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
@@ -1715,6 +1743,10 @@
// Should this be considered a new task?
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+ if (isLockTaskModeViolation(reuseTask)) {
+ Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+ return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+ }
targetStack = adjustStackFocus(r);
targetStack.moveToFront();
if (reuseTask == null) {
@@ -1739,6 +1771,10 @@
}
} else if (sourceRecord != null) {
TaskRecord sourceTask = sourceRecord.task;
+ if (isLockTaskModeViolation(sourceTask)) {
+ Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+ return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+ }
targetStack = sourceTask.stack;
targetStack.moveToFront();
if (!addingToTask &&
@@ -1782,6 +1818,10 @@
// An existing activity is starting this new activity, so we want
// to keep the new one in the same task as the one that is starting
// it.
+ if (isLockTaskModeViolation(sourceTask)) {
+ Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+ return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+ }
r.setTask(sourceTask, sourceRecord.thumbHolder, false);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+ " in existing task " + r.task + " from source " + sourceRecord);
@@ -2098,17 +2138,18 @@
}
}
- void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
- if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
- + stacks.get(stackNdx));
- return;
- }
- }
+ void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
+ if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+ mUserLeaving = true;
}
+ 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.mOnTopOfHome = true;
+ }
+ task.stack.moveTaskToFrontLocked(task, null, options);
+ if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
+ + task.stack);
}
ActivityStack getStack(int stackId) {
@@ -2288,6 +2329,7 @@
}
}
checkReadyForSleepLocked();
+ setLockTaskModeLocked(null);
}
boolean shutdownLocked(int timeout) {
@@ -2872,6 +2914,35 @@
return list;
}
+ void setLockTaskModeLocked(TaskRecord task) {
+ if (task == null) {
+ // Take out of lock task mode.
+ mLockTaskModeTask = null;
+ return;
+ }
+ if (isLockTaskModeViolation(task)) {
+ Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
+ return;
+ }
+ mLockTaskModeTask = task;
+ findTaskToMoveToFrontLocked(task, 0, null);
+ resumeTopActivitiesLocked();
+ }
+
+ boolean isLockTaskModeViolation(TaskRecord task) {
+ return mLockTaskModeTask != null && mLockTaskModeTask != task;
+ }
+
+ void endLockTaskModeIfTaskEnding(TaskRecord task) {
+ if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
+ mLockTaskModeTask = null;
+ }
+ }
+
+ boolean isInLockTaskMode() {
+ return mLockTaskModeTask != null;
+ }
+
private final class ActivityStackSupervisorHandler extends Handler {
public ActivityStackSupervisorHandler(Looper looper) {
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 7bd88b2..4c8dcc3 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -20,10 +20,13 @@
public interface NotificationDelegate {
void onSetDisabled(int status);
- void onClearAll(int userId);
- void onNotificationClick(String pkg, String tag, int id, int userId);
- void onNotificationClear(String pkg, String tag, int id, int userId);
- void onNotificationError(String pkg, String tag, int id,
+ void onClearAll(int callingUid, int callingPid, int userId);
+ void onNotificationClick(int callingUid, int callingPid,
+ String pkg, String tag, int id, int userId);
+ void onNotificationClear(int callingUid, int callingPid,
+ String pkg, String tag, int id, int userId);
+ void onNotificationError(int callingUid, int callingPid,
+ String pkg, String tag, int id,
int uid, int initialPid, String message, int userId);
void onPanelRevealed();
boolean allowDisable(int what, IBinder token, String pkg);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f52092e..e2226aa 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -223,6 +223,20 @@
// Users related to the current user.
final protected SparseArray<UserInfo> mRelatedUsers = new SparseArray<UserInfo>();
+ private static final int MY_UID = Process.myUid();
+ private static final int MY_PID = Process.myPid();
+ private static final int REASON_DELEGATE_CLICK = 1;
+ private static final int REASON_DELEGATE_CANCEL = 2;
+ private static final int REASON_DELEGATE_CANCEL_ALL = 3;
+ private static final int REASON_DELEGATE_ERROR = 4;
+ private static final int REASON_PACKAGE_CHANGED = 5;
+ private static final int REASON_USER_STOPPED = 6;
+ private static final int REASON_PACKAGE_BANNED = 7;
+ private static final int REASON_NOMAN_CANCEL = 8;
+ private static final int REASON_NOMAN_CANCEL_ALL = 9;
+ private static final int REASON_LISTENER_CANCEL = 10;
+ private static final int REASON_LISTENER_CANCEL_ALL = 11;
+
private class NotificationListenerInfo implements IBinder.DeathRecipient {
INotificationListener listener;
ComponentName component;
@@ -916,21 +930,23 @@
}
@Override
- public void onClearAll(int userId) {
- cancelAll(userId);
+ public void onClearAll(int callingUid, int callingPid, int userId) {
+ cancelAll(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null);
}
@Override
- public void onNotificationClick(String pkg, String tag, int id, int userId) {
- cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
- Notification.FLAG_FOREGROUND_SERVICE, false, userId);
+ public void onNotificationClick(int callingUid, int callingPid,
+ String pkg, String tag, int id, int userId) {
+ cancelNotification(callingUid, callingPid, pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
+ Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_DELEGATE_CLICK, null);
}
@Override
- public void onNotificationClear(String pkg, String tag, int id, int userId) {
- cancelNotification(pkg, tag, id, 0,
+ public void onNotificationClear(int callingUid, int callingPid,
+ String pkg, String tag, int id, int userId) {
+ cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
- true, userId);
+ true, userId, REASON_DELEGATE_CANCEL, null);
}
@Override
@@ -967,11 +983,12 @@
}
@Override
- public void onNotificationError(String pkg, String tag, int id,
+ public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
int uid, int initialPid, String message, int userId) {
Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
+ "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
- cancelNotification(pkg, tag, id, 0, 0, false, userId);
+ cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
+ REASON_DELEGATE_ERROR, null);
long ident = Binder.clearCallingIdentity();
try {
ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -1048,8 +1065,8 @@
if (pkgList != null && (pkgList.length > 0)) {
for (String pkgName : pkgList) {
if (cancelNotifications) {
- cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart,
- UserHandle.USER_ALL);
+ cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
+ UserHandle.USER_ALL, REASON_PACKAGE_CHANGED, null);
}
if (mEnabledListenerPackageNames.contains(pkgName)) {
anyListenersInvolved = true;
@@ -1079,7 +1096,8 @@
} else if (action.equals(Intent.ACTION_USER_STOPPED)) {
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0) {
- cancelAllNotificationsInt(null, 0, 0, true, userHandle);
+ cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
+ REASON_USER_STOPPED, null);
}
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
// turn off LED when user passes through lock screen
@@ -1305,7 +1323,8 @@
// Now, cancel any outstanding notifications that are part of a just-disabled app
if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
- cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid));
+ cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true, UserHandle.getUserId(uid),
+ REASON_PACKAGE_BANNED, null);
}
}
@@ -1421,9 +1440,10 @@
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
// Don't allow client applications to cancel foreground service notis.
- cancelNotification(pkg, tag, id, 0,
+ cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
Binder.getCallingUid() == Process.SYSTEM_UID
- ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId);
+ ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_NOMAN_CANCEL,
+ null);
}
@Override
@@ -1435,7 +1455,9 @@
// Calling from user space, don't allow the canceling of actively
// running foreground services.
- cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
+ cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
+ pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
+ REASON_NOMAN_CANCEL_ALL, null);
}
@Override
@@ -1544,9 +1566,12 @@
@Override
public void cancelAllNotificationsFromListener(INotificationListener token) {
NotificationListenerInfo info = checkListenerToken(token);
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- cancelAll(info.userid);
+ cancelAll(callingUid, callingPid, info.userid,
+ REASON_LISTENER_CANCEL_ALL, info);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1563,12 +1588,14 @@
public void cancelNotificationFromListener(INotificationListener token, String pkg,
String tag, int id) {
NotificationListenerInfo info = checkListenerToken(token);
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- cancelNotification(pkg, tag, id, 0,
+ cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
true,
- info.userid);
+ info.userid, REASON_LISTENER_CANCEL, info);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1736,8 +1763,8 @@
// behalf of the download manager without affecting other apps.
if (!pkg.equals("com.android.providers.downloads")
|| Log.isLoggable("DownloadManager", Log.VERBOSE)) {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId,
- notification.toString());
+ EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
+ pkg, id, tag, userId, notification.toString());
}
if (pkg == null || notification == null) {
@@ -2288,9 +2315,10 @@
* Cancels a notification ONLY if it has all of the {@code mustHaveFlags}
* and none of the {@code mustNotHaveFlags}.
*/
- void cancelNotification(final String pkg, final String tag, final int id,
+ void cancelNotification(final int callingUid, final int callingPid,
+ final String pkg, final String tag, final int id,
final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
- final int userId) {
+ final int userId, final int reason, final NotificationListenerInfo listener) {
// In enqueueNotificationInternal notifications are added by scheduling the
// work on the worker handler. Hence, we also schedule the cancel on this
// handler to avoid a scenario where an add notification call followed by a
@@ -2298,8 +2326,9 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
- mustHaveFlags, mustNotHaveFlags);
+ EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, id, tag, userId,
+ mustHaveFlags, mustNotHaveFlags, reason,
+ listener == null ? null : listener.component.toShortString());
synchronized (mNotificationList) {
int index = indexOfNotificationLocked(pkg, tag, id, userId);
@@ -2353,10 +2382,12 @@
* Cancels all notifications from a given package that have all of the
* {@code mustHaveFlags}.
*/
- boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
- int mustNotHaveFlags, boolean doit, int userId) {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId,
- mustHaveFlags, mustNotHaveFlags);
+ boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
+ int mustNotHaveFlags, boolean doit, int userId, int reason,
+ NotificationListenerInfo listener) {
+ EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+ pkg, userId, mustHaveFlags, mustNotHaveFlags, reason,
+ listener == null ? null : listener.component.toShortString());
synchronized (mNotificationList) {
final int N = mNotificationList.size();
@@ -2431,7 +2462,11 @@
}
}
- void cancelAll(int userId) {
+ void cancelAll(int callingUid, int callingPid, int userId, int reason,
+ NotificationListenerInfo listener) {
+ EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+ null, userId, 0, 0, reason,
+ listener == null ? null : listener.component.toShortString());
synchronized (mNotificationList) {
final int N = mNotificationList.size();
for (int i=N-1; i>=0; i--) {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index df06bae..81af636 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -165,11 +165,11 @@
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
- boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
- && ownerUid == Process.SYSTEM_UID;
if (workSource != null && newWorkSource != null) {
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+ boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+ && newOwnerUid == Process.SYSTEM_UID;
if (DEBUG) {
Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ "\", packageName=" + newPackageName
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 1568d6f..4ce02c1 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -537,9 +537,11 @@
@Override
public void onNotificationClick(String pkg, String tag, int id, int userId) {
enforceStatusBarService();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- mNotificationDelegate.onNotificationClick(pkg, tag, id, userId);
+ mNotificationDelegate.onNotificationClick(callingUid, callingPid, pkg, tag, id, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -549,11 +551,13 @@
public void onNotificationError(String pkg, String tag, int id,
int uid, int initialPid, String message, int userId) {
enforceStatusBarService();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
// WARNING: this will call back into us to do the remove. Don't hold any locks.
- mNotificationDelegate.onNotificationError(pkg, tag, id, uid, initialPid, message,
- userId);
+ mNotificationDelegate.onNotificationError(callingUid, callingPid,
+ pkg, tag, id, uid, initialPid, message, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -562,9 +566,11 @@
@Override
public void onNotificationClear(String pkg, String tag, int id, int userId) {
enforceStatusBarService();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- mNotificationDelegate.onNotificationClear(pkg, tag, id, userId);
+ mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -573,9 +579,11 @@
@Override
public void onClearAllNotifications(int userId) {
enforceStatusBarService();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- mNotificationDelegate.onClearAll(userId);
+ mNotificationDelegate.onClearAll(callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b925856..efbfb33 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -90,6 +90,7 @@
private static final int MSG_SYSTEM_READY = 3;
private static final int MSG_BOOT_COMPLETED = 4;
private static final int MSG_USER_SWITCHED = 5;
+ private static final int MSG_START_ACCESSORY_MODE = 6;
private static final int AUDIO_MODE_NONE = 0;
private static final int AUDIO_MODE_SOURCE = 1;
@@ -152,7 +153,7 @@
mHandler.updateState(state);
} else if ("START".equals(accessory)) {
if (DEBUG) Slog.d(TAG, "got accessory start");
- startAccessoryMode();
+ mHandler.sendEmptyMessage(MSG_START_ACCESSORY_MODE);
}
}
};
@@ -170,7 +171,7 @@
if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
- startAccessoryMode();
+ mHandler.sendEmptyMessage(MSG_START_ACCESSORY_MODE);
}
boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
@@ -232,6 +233,8 @@
functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE;
}
+ if (DEBUG) Slog.d(TAG, "startAccessoryMode: " + functions);
+
if (functions != null) {
mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
setCurrentFunctions(functions, false);
@@ -306,6 +309,7 @@
// current USB state
private boolean mConnected;
private boolean mConfigured;
+ private boolean mAccessoryStartPending;
private String mCurrentFunctions;
private String mDefaultFunctions;
private UsbAccessory mCurrentAccessory;
@@ -612,6 +616,11 @@
case MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
+
+ if (!mConnected) {
+ mAccessoryStartPending = false;
+ }
+
updateUsbNotification();
updateAdbNotification();
if (containsFunction(mCurrentFunctions,
@@ -625,6 +634,10 @@
updateUsbState();
updateAudioSourceFunction();
}
+ if (mConnected && mConfigured && mAccessoryStartPending) {
+ startAccessoryMode();
+ mAccessoryStartPending = false;
+ }
break;
case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1);
@@ -661,6 +674,16 @@
mCurrentUser = msg.arg1;
break;
}
+ case MSG_START_ACCESSORY_MODE:
+ if (mConnected && mConfigured) {
+ startAccessoryMode();
+ } else {
+ // we sometimes receive the kernel "accessory start" uevent
+ // before the "configured" uevent. In this case we need to defer
+ // handling this event until after we received the configured event
+ mAccessoryStartPending = true;
+ }
+ break;
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index ff4857b..37b5c51 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -27,6 +27,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
@@ -73,6 +74,7 @@
private final UserHandle mUser;
private final AtomicFile mSettingsFile;
+ private final boolean mDisablePermissionDialogs;
private final Context mContext;
private final Context mUserContext;
@@ -510,6 +512,9 @@
Environment.getUserSystemDirectory(user.getIdentifier()),
"usb_device_manager.xml"));
+ mDisablePermissionDialogs = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_disableUsbPermissionDialogs);
+
synchronized (mLock) {
if (UserHandle.OWNER.equals(user)) {
upgradeSingleUserLocked();
@@ -815,6 +820,14 @@
(rInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
defaultRI = rInfo;
}
+
+ if (mDisablePermissionDialogs) {
+ // bypass dialog and launch the only matching activity
+ rInfo = matches.get(0);
+ if (rInfo.activityInfo != null) {
+ defaultPackage = rInfo.activityInfo.packageName;
+ }
+ }
}
if (defaultRI == null && defaultPackage != null) {
@@ -970,7 +983,7 @@
public boolean hasPermission(UsbDevice device) {
synchronized (mLock) {
int uid = Binder.getCallingUid();
- if (uid == Process.SYSTEM_UID) {
+ if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
return true;
}
SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
@@ -984,7 +997,7 @@
public boolean hasPermission(UsbAccessory accessory) {
synchronized (mLock) {
int uid = Binder.getCallingUid();
- if (uid == Process.SYSTEM_UID) {
+ if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
return true;
}
SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index ff5c935..118cba4 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -335,6 +335,27 @@
}
@Override
+ public Drawable getActivityBanner(ComponentName activityName)
+ throws NameNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Drawable getApplicationBanner(ApplicationInfo info) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public Drawable getApplicationIcon(ApplicationInfo info) {
throw new UnsupportedOperationException();
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 6666385..b235408 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -142,6 +142,13 @@
}
@LayoutlibDelegate
+ /*package*/ static boolean native_isConvex(long nPath) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Path.isConvex is not supported.", null, null);
+ return true;
+ }
+
+ @LayoutlibDelegate
/*package*/ static int native_getFillType(long nPath) {
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index d40352f..b16b4aa 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -18,6 +18,7 @@
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.ibm.icu.text.DateTimePatternGenerator;
+import com.ibm.icu.util.Currency;
import com.ibm.icu.util.ULocale;
import java.util.Locale;
@@ -117,6 +118,11 @@
}
@LayoutlibDelegate
+ /*package*/ static int getCurrencyNumericCode(String currencyCode) {
+ return Currency.getInstance(currencyCode).getNumericCode();
+ }
+
+ @LayoutlibDelegate
/*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
return "";
}
@@ -231,7 +237,7 @@
result.percent = '%';
result.perMill = '\u2030';
result.monetarySeparator = ' ';
- result.minusSign = '-';
+ result.minusSign = "-";
result.exponentSeparator = "e";
result.infinity = "\u221E";
result.NaN = "NaN";