Merge "Allow changing mouse cursor for the edges of resizable window."
diff --git a/api/current.txt b/api/current.txt
index 9fe6857..3637f14 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -241,10 +241,8 @@
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
- field public static final int activityHeight = 16844021; // 0x10104f5
field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
- field public static final int activityWidth = 16844020; // 0x10104f4
field public static final int addPrintersActivity = 16843750; // 0x10103e6
field public static final int addStatesFromChildren = 16842992; // 0x10100f0
field public static final int adjustViewBounds = 16843038; // 0x101011e
@@ -323,7 +321,7 @@
field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
field public static final int buttonBarStyle = 16843566; // 0x101032e
- field public static final int buttonGravity = 16844029; // 0x10104fd
+ field public static final int buttonGravity = 16844030; // 0x10104fe
field public static final int buttonStyle = 16842824; // 0x1010048
field public static final int buttonStyleInset = 16842826; // 0x101004a
field public static final int buttonStyleSmall = 16842825; // 0x1010049
@@ -373,7 +371,7 @@
field public static final int codes = 16843330; // 0x1010242
field public static final int collapseColumns = 16843083; // 0x101014b
field public static final int collapseContentDescription = 16843984; // 0x10104d0
- field public static final int collapseIcon = 16844030; // 0x10104fe
+ field public static final int collapseIcon = 16844031; // 0x10104ff
field public static final int color = 16843173; // 0x10101a5
field public static final int colorAccent = 16843829; // 0x1010435
field public static final int colorActivatedHighlight = 16843664; // 0x1010390
@@ -414,7 +412,7 @@
field public static final int contentInsetRight = 16843862; // 0x1010456
field public static final int contentInsetStart = 16843859; // 0x1010453
field public static final int contextClickable = 16844007; // 0x10104e7
- field public static final int contextPopupMenuStyle = 16844032; // 0x1010500
+ field public static final int contextPopupMenuStyle = 16844033; // 0x1010501
field public static final int controlX1 = 16843772; // 0x10103fc
field public static final int controlX2 = 16843774; // 0x10103fe
field public static final int controlY1 = 16843773; // 0x10103fd
@@ -673,8 +671,10 @@
field public static final int indicatorStart = 16843729; // 0x10103d1
field public static final int inflatedId = 16842995; // 0x10100f3
field public static final int initOrder = 16842778; // 0x101001a
+ field public static final int initialHeight = 16844021; // 0x10104f5
field public static final int initialKeyguardLayout = 16843714; // 0x10103c2
field public static final int initialLayout = 16843345; // 0x1010251
+ field public static final int initialWidth = 16844020; // 0x10104f4
field public static final int innerRadius = 16843359; // 0x101025f
field public static final int innerRadiusRatio = 16843163; // 0x101019b
field public static final deprecated int inputMethod = 16843112; // 0x1010168
@@ -780,7 +780,7 @@
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
field public static final int letterSpacing = 16843958; // 0x10104b6
- field public static final int level = 16844031; // 0x10104ff
+ field public static final int level = 16844032; // 0x1010500
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -813,7 +813,7 @@
field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
field public static final int matchOrder = 16843855; // 0x101044f
field public static final int max = 16843062; // 0x1010136
- field public static final int maxButtonHeight = 16844028; // 0x10104fc
+ field public static final int maxButtonHeight = 16844029; // 0x10104fd
field public static final int maxDate = 16843584; // 0x1010340
field public static final int maxEms = 16843095; // 0x1010157
field public static final int maxHeight = 16843040; // 0x1010120
@@ -841,6 +841,7 @@
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
+ field public static final int minimalSize = 16844022; // 0x10104f6
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
field public static final int mipMap = 16843725; // 0x10103cd
@@ -997,7 +998,7 @@
field public static final int resizeClip = 16843983; // 0x10104cf
field public static final int resizeMode = 16843619; // 0x1010363
field public static final int resizeable = 16843405; // 0x101028d
- field public static final int resizeableActivity = 16844022; // 0x10104f6
+ field public static final int resizeableActivity = 16844023; // 0x10104f7
field public static final int resource = 16842789; // 0x1010025
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1221,7 +1222,7 @@
field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
field public static final int textAppearanceMedium = 16842817; // 0x1010041
field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
- field public static final int textAppearancePopupMenuHeader = 16844033; // 0x1010501
+ field public static final int textAppearancePopupMenuHeader = 16844034; // 0x1010502
field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
field public static final int textAppearanceSearchResultTitle = 16843425; // 0x10102a1
field public static final int textAppearanceSmall = 16842818; // 0x1010042
@@ -1290,11 +1291,11 @@
field public static final int tintMode = 16843771; // 0x10103fb
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
- field public static final int titleMargin = 16844023; // 0x10104f7
- field public static final int titleMarginBottom = 16844027; // 0x10104fb
- field public static final int titleMarginEnd = 16844025; // 0x10104f9
- field public static final int titleMarginStart = 16844024; // 0x10104f8
- field public static final int titleMarginTop = 16844026; // 0x10104fa
+ field public static final int titleMargin = 16844024; // 0x10104f8
+ field public static final int titleMarginBottom = 16844028; // 0x10104fc
+ field public static final int titleMarginEnd = 16844026; // 0x10104fa
+ field public static final int titleMarginStart = 16844025; // 0x10104f9
+ field public static final int titleMarginTop = 16844027; // 0x10104fb
field public static final int titleTextAppearance = 16843822; // 0x101042e
field public static final int titleTextColor = 16844003; // 0x10104e3
field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -8924,8 +8925,8 @@
field public int configChanges;
field public int documentLaunchMode;
field public int flags;
- field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
field public int launchMode;
+ field public android.content.pm.ActivityInfo.Layout layout;
field public int maxRecents;
field public java.lang.String parentActivityName;
field public java.lang.String permission;
@@ -8938,11 +8939,12 @@
field public int uiOptions;
}
- public static final class ActivityInfo.InitialLayout {
- ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+ public static final class ActivityInfo.Layout {
+ ctor public ActivityInfo.Layout(int, float, int, float, int, int);
field public final int gravity;
field public final int height;
field public final float heightFraction;
+ field public final int minimalSize;
field public final int width;
field public final float widthFraction;
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 5e1aa41..076815e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -333,10 +333,8 @@
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
- field public static final int activityHeight = 16844021; // 0x10104f5
field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
- field public static final int activityWidth = 16844020; // 0x10104f4
field public static final int addPrintersActivity = 16843750; // 0x10103e6
field public static final int addStatesFromChildren = 16842992; // 0x10100f0
field public static final int adjustViewBounds = 16843038; // 0x101011e
@@ -415,7 +413,7 @@
field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
field public static final int buttonBarStyle = 16843566; // 0x101032e
- field public static final int buttonGravity = 16844029; // 0x10104fd
+ field public static final int buttonGravity = 16844030; // 0x10104fe
field public static final int buttonStyle = 16842824; // 0x1010048
field public static final int buttonStyleInset = 16842826; // 0x101004a
field public static final int buttonStyleSmall = 16842825; // 0x1010049
@@ -465,7 +463,7 @@
field public static final int codes = 16843330; // 0x1010242
field public static final int collapseColumns = 16843083; // 0x101014b
field public static final int collapseContentDescription = 16843984; // 0x10104d0
- field public static final int collapseIcon = 16844030; // 0x10104fe
+ field public static final int collapseIcon = 16844031; // 0x10104ff
field public static final int color = 16843173; // 0x10101a5
field public static final int colorAccent = 16843829; // 0x1010435
field public static final int colorActivatedHighlight = 16843664; // 0x1010390
@@ -506,7 +504,7 @@
field public static final int contentInsetRight = 16843862; // 0x1010456
field public static final int contentInsetStart = 16843859; // 0x1010453
field public static final int contextClickable = 16844007; // 0x10104e7
- field public static final int contextPopupMenuStyle = 16844032; // 0x1010500
+ field public static final int contextPopupMenuStyle = 16844033; // 0x1010501
field public static final int controlX1 = 16843772; // 0x10103fc
field public static final int controlX2 = 16843774; // 0x10103fe
field public static final int controlY1 = 16843773; // 0x10103fd
@@ -765,8 +763,10 @@
field public static final int indicatorStart = 16843729; // 0x10103d1
field public static final int inflatedId = 16842995; // 0x10100f3
field public static final int initOrder = 16842778; // 0x101001a
+ field public static final int initialHeight = 16844021; // 0x10104f5
field public static final int initialKeyguardLayout = 16843714; // 0x10103c2
field public static final int initialLayout = 16843345; // 0x1010251
+ field public static final int initialWidth = 16844020; // 0x10104f4
field public static final int innerRadius = 16843359; // 0x101025f
field public static final int innerRadiusRatio = 16843163; // 0x101019b
field public static final deprecated int inputMethod = 16843112; // 0x1010168
@@ -872,7 +872,7 @@
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
field public static final int letterSpacing = 16843958; // 0x10104b6
- field public static final int level = 16844031; // 0x10104ff
+ field public static final int level = 16844032; // 0x1010500
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -905,7 +905,7 @@
field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
field public static final int matchOrder = 16843855; // 0x101044f
field public static final int max = 16843062; // 0x1010136
- field public static final int maxButtonHeight = 16844028; // 0x10104fc
+ field public static final int maxButtonHeight = 16844029; // 0x10104fd
field public static final int maxDate = 16843584; // 0x1010340
field public static final int maxEms = 16843095; // 0x1010157
field public static final int maxHeight = 16843040; // 0x1010120
@@ -933,6 +933,7 @@
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
+ field public static final int minimalSize = 16844022; // 0x10104f6
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
field public static final int mipMap = 16843725; // 0x10103cd
@@ -1089,7 +1090,7 @@
field public static final int resizeClip = 16843983; // 0x10104cf
field public static final int resizeMode = 16843619; // 0x1010363
field public static final int resizeable = 16843405; // 0x101028d
- field public static final int resizeableActivity = 16844022; // 0x10104f6
+ field public static final int resizeableActivity = 16844023; // 0x10104f7
field public static final int resource = 16842789; // 0x1010025
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1317,7 +1318,7 @@
field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
field public static final int textAppearanceMedium = 16842817; // 0x1010041
field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
- field public static final int textAppearancePopupMenuHeader = 16844033; // 0x1010501
+ field public static final int textAppearancePopupMenuHeader = 16844034; // 0x1010502
field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
field public static final int textAppearanceSearchResultTitle = 16843425; // 0x10102a1
field public static final int textAppearanceSmall = 16842818; // 0x1010042
@@ -1386,11 +1387,11 @@
field public static final int tintMode = 16843771; // 0x10103fb
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
- field public static final int titleMargin = 16844023; // 0x10104f7
- field public static final int titleMarginBottom = 16844027; // 0x10104fb
- field public static final int titleMarginEnd = 16844025; // 0x10104f9
- field public static final int titleMarginStart = 16844024; // 0x10104f8
- field public static final int titleMarginTop = 16844026; // 0x10104fa
+ field public static final int titleMargin = 16844024; // 0x10104f8
+ field public static final int titleMarginBottom = 16844028; // 0x10104fc
+ field public static final int titleMarginEnd = 16844026; // 0x10104fa
+ field public static final int titleMarginStart = 16844025; // 0x10104f9
+ field public static final int titleMarginTop = 16844027; // 0x10104fb
field public static final int titleTextAppearance = 16843822; // 0x101042e
field public static final int titleTextColor = 16844003; // 0x10104e3
field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -9181,8 +9182,8 @@
field public int configChanges;
field public int documentLaunchMode;
field public int flags;
- field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
field public int launchMode;
+ field public android.content.pm.ActivityInfo.Layout layout;
field public int maxRecents;
field public java.lang.String parentActivityName;
field public java.lang.String permission;
@@ -9195,11 +9196,12 @@
field public int uiOptions;
}
- public static final class ActivityInfo.InitialLayout {
- ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+ public static final class ActivityInfo.Layout {
+ ctor public ActivityInfo.Layout(int, float, int, float, int, int);
field public final int gravity;
field public final int height;
field public final float heightFraction;
+ field public final int minimalSize;
field public final int width;
field public final float widthFraction;
}
@@ -25741,7 +25743,8 @@
ctor public UserHandle(android.os.Parcel);
method public int describeContents();
method public int getIdentifier();
- method public boolean isOwner();
+ method public deprecated boolean isOwner();
+ method public boolean isSystem();
method public static int myUserId();
method public static android.os.UserHandle readFromParcel(android.os.Parcel);
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e5cfbf3..3f02f17 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -647,20 +647,18 @@
/**
* Open a private file associated with this Context's application package
- * for writing. Creates the file if it doesn't already exist.
- *
- * <p>No permissions are required to invoke this method, since it uses internal
- * storage.
+ * for writing. Creates the file if it doesn't already exist.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write the returned file.
*
* @param name The name of the file to open; can not contain path
- * separators.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_APPEND} to append to an existing file,
- * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
- * permissions.
- *
+ * separators.
+ * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
+ * default operation, {@link #MODE_APPEND} to append to an
+ * existing file, {@link #MODE_WORLD_READABLE} and
+ * {@link #MODE_WORLD_WRITEABLE} to control permissions.
* @return The resulting {@link FileOutputStream}.
- *
* @see #MODE_APPEND
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
@@ -693,6 +691,9 @@
/**
* Returns the absolute path on the filesystem where a file created with
* {@link #openFileOutput} is stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
*
* @param name The name of the file for which you would like to get
* its path.
@@ -706,14 +707,16 @@
public abstract File getFileStreamPath(String name);
/**
- * Returns the absolute path to the directory on the filesystem where
- * files created with {@link #openFileOutput} are stored.
- *
- * <p>No permissions are required to read or write to the returned path, since this
- * path is internal storage.
+ * Returns the absolute path to the directory on the filesystem where files
+ * created with {@link #openFileOutput} are stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path.
*
* @return The path of the directory holding application files.
- *
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -722,17 +725,19 @@
/**
* Returns the absolute path to the directory on the filesystem similar to
- * {@link #getFilesDir()}. The difference is that files placed under this
- * directory will be excluded from automatic backup to remote storage. See
+ * {@link #getFilesDir()}. The difference is that files placed under this
+ * directory will be excluded from automatic backup to remote storage. See
* {@link android.app.backup.BackupAgent BackupAgent} for a full discussion
* of the automatic backup mechanism in Android.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path.
*
- * <p>No permissions are required to read or write to the returned path, since this
- * path is internal storage.
- *
- * @return The path of the directory holding application files that will not be
- * automatically backed up to remote storage.
- *
+ * @return The path of the directory holding application files that will not
+ * be automatically backed up to remote storage.
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -741,200 +746,256 @@
public abstract File getNoBackupFilesDir();
/**
- * Returns the absolute path to the directory on the primary external filesystem
- * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
- * Environment.getExternalStorageDirectory()}) where the application can
- * place persistent files it owns. These files are internal to the
- * applications, and not typically visible to the user as media.
- *
- * <p>This is like {@link #getFilesDir()} in that these
- * files will be deleted when the application is uninstalled, however there
- * are some important differences:
- *
+ * Returns the absolute path to the directory on the primary shared/external
+ * storage device where the application can place persistent files it owns.
+ * These files are internal to the applications, and not typically visible
+ * to the user as media.
+ * <p>
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it. See the
- * APIs on {@link android.os.Environment} for information in the storage state.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
- *
- * <p>Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * <p>
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directories returned
+ * by {@link #getFilesDir()}, etc.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
- *
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * <p>Here is an example of typical code to manipulate a file in
- * an application's private storage:</p>
- *
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * <p>
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
+ * <p>
+ * Here is an example of typical code to manipulate a file in an
+ * application's shared storage:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_file}
- *
- * <p>If you supply a non-null <var>type</var> to this function, the returned
- * file will be a path to a sub-directory of the given type. Though these files
- * are not automatically scanned by the media scanner, you can explicitly
- * add them to the media database with
- * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[],
- * android.media.MediaScannerConnection.OnScanCompletedListener)
- * MediaScannerConnection.scanFile}.
- * Note that this is not the same as
+ * <p>
+ * If you supply a non-null <var>type</var> to this function, the returned
+ * file will be a path to a sub-directory of the given type. Though these
+ * files are not automatically scanned by the media scanner, you can
+ * explicitly add them to the media database with
+ * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], android.media.MediaScannerConnection.OnScanCompletedListener)
+ * MediaScannerConnection.scanFile}. Note that this is not the same as
* {@link android.os.Environment#getExternalStoragePublicDirectory
* Environment.getExternalStoragePublicDirectory()}, which provides
- * directories of media shared by all applications. The
- * directories returned here are
- * owned by the application, and their contents will be removed when the
- * application is uninstalled. Unlike
+ * directories of media shared by all applications. The directories returned
+ * here are owned by the application, and their contents will be removed
+ * when the application is uninstalled. Unlike
* {@link android.os.Environment#getExternalStoragePublicDirectory
- * Environment.getExternalStoragePublicDirectory()}, the directory
- * returned here will be automatically created for you.
- *
- * <p>Here is an example of typical code to manipulate a picture in
- * an application's private storage and add it to the media database:</p>
- *
+ * Environment.getExternalStoragePublicDirectory()}, the directory returned
+ * here will be automatically created for you.
+ * <p>
+ * Here is an example of typical code to manipulate a picture in an
+ * application's shared storage and add it to the media database:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_picture}
*
- * @param type The type of files directory to return. May be null for
- * the root of the files directory or one of
- * the following Environment constants for a subdirectory:
- * {@link android.os.Environment#DIRECTORY_MUSIC},
- * {@link android.os.Environment#DIRECTORY_PODCASTS},
- * {@link android.os.Environment#DIRECTORY_RINGTONES},
- * {@link android.os.Environment#DIRECTORY_ALARMS},
- * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
- * {@link android.os.Environment#DIRECTORY_PICTURES}, or
- * {@link android.os.Environment#DIRECTORY_MOVIES}.
- *
- * @return The path of the directory holding application files
- * on external storage. Returns null if external storage is not currently
- * mounted so it could not ensure the path exists; you will need to call
- * this method again when it is available.
- *
+ * @param type The type of files directory to return. May be {@code null}
+ * for the root of the files directory or one of the following
+ * constants for a subdirectory:
+ * {@link android.os.Environment#DIRECTORY_MUSIC},
+ * {@link android.os.Environment#DIRECTORY_PODCASTS},
+ * {@link android.os.Environment#DIRECTORY_RINGTONES},
+ * {@link android.os.Environment#DIRECTORY_ALARMS},
+ * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
+ * {@link android.os.Environment#DIRECTORY_PICTURES}, or
+ * {@link android.os.Environment#DIRECTORY_MOVIES}.
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
* @see #getFilesDir
- * @see android.os.Environment#getExternalStoragePublicDirectory
+ * @see #getExternalFilesDirs(String)
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place persistent files
- * it owns. These files are internal to the application, and not typically
- * visible to the user as media.
+ * shared/external storage devices where the application can place
+ * persistent files it owns. These files are internal to the application,
+ * and not typically visible to the user as media.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directories returned
+ * by {@link #getFilesDir()}, etc.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
+ * <p>
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * The first path returned is the same as {@link #getExternalFilesDir(String)}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @param type The type of files directory to return. May be {@code null}
+ * for the root of the files directory or one of the following
+ * constants for a subdirectory:
+ * {@link android.os.Environment#DIRECTORY_MUSIC},
+ * {@link android.os.Environment#DIRECTORY_PODCASTS},
+ * {@link android.os.Environment#DIRECTORY_RINGTONES},
+ * {@link android.os.Environment#DIRECTORY_ALARMS},
+ * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
+ * {@link android.os.Environment#DIRECTORY_PICTURES}, or
+ * {@link android.os.Environment#DIRECTORY_MOVIES}.
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getExternalFilesDir(String)}.
* @see #getExternalFilesDir(String)
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalFilesDirs(String type);
/**
- * Return the primary external storage directory where this application's OBB
- * files (if there are any) can be found. Note if the application does not have
- * any OBB files, this directory may not exist.
+ * Return the primary shared/external storage directory where this
+ * application's OBB files (if there are any) can be found. Note if the
+ * application does not have any OBB files, this directory may not exist.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
* <p>
* On devices with multiple users (as described by {@link UserManager}),
* multiple users may share the same OBB storage location. Applications
* should ensure that multiple instances running under different users don't
* interfere with each other.
+ *
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
+ * @see #getObbDirs()
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File getObbDir();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application's OBB files (if there are
- * any) can be found. Note if the application does not have any OBB files,
- * these directories may not exist.
+ * shared/external storage devices where the application's OBB files (if
+ * there are any) can be found. Note if the application does not have any
+ * OBB files, these directories may not exist.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
- * <p>
- * The first path returned is the same as {@link #getObbDir()}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getObbDir()}
* @see #getObbDir()
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getObbDirs();
/**
- * Returns the absolute path to the application specific cache directory
- * on the filesystem. These files will be ones that get deleted first when the
- * device runs low on storage.
- * There is no guarantee when these files will be deleted.
- *
+ * Returns the absolute path to the application specific cache directory on
+ * the filesystem. These files will be ones that get deleted first when the
+ * device runs low on storage. There is no guarantee when these files will
+ * be deleted.
+ * <p>
* <strong>Note: you should not <em>rely</em> on the system deleting these
* files for you; you should always have a reasonable maximum, such as 1 MB,
* for the amount of space you consume with cache files, and prune those
* files when exceeding that space.</strong>
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * Apps require no extra permissions to read or write to the returned path,
+ * since this path lives in their private storage.
*
* @return The path of the directory holding application cache files.
- *
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -950,6 +1011,9 @@
* This location is optimal for storing compiled or optimized code generated
* by your application at runtime.
* <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
* Apps require no extra permissions to read or write to the returned path,
* since this path lives in their private storage.
*
@@ -958,120 +1022,161 @@
public abstract File getCodeCacheDir();
/**
- * Returns the absolute path to the directory on the primary external filesystem
- * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
- * Environment.getExternalStorageDirectory()} where the application can
- * place cache files it owns. These files are internal to the application, and
- * not typically visible to the user as media.
- *
- * <p>This is like {@link #getCacheDir()} in that these
- * files will be deleted when the application is uninstalled, however there
- * are some important differences:
- *
+ * Returns absolute path to application-specific directory on the primary
+ * shared/external storage device where the application can place cache
+ * files it owns. These files are internal to the application, and not
+ * typically visible to the user as media.
+ * <p>
+ * This is like {@link #getCacheDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>The platform does not always monitor the space available in external
- * storage, and thus may not automatically delete these files. Currently
- * the only time files here will be deleted by the platform is when running
- * on {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
- * {@link android.os.Environment#isExternalStorageEmulated()
- * Environment.isExternalStorageEmulated()} returns true. Note that you should
- * be managing the maximum space you will use for these anyway, just like
- * with {@link #getCacheDir()}.
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it. See the
- * APIs on {@link android.os.Environment} for information in the storage state.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>The platform does not always monitor the space available in shared
+ * storage, and thus may not automatically delete these files. Apps should
+ * always manage the maximum space used in this location. Currently the only
+ * time files here will be deleted by the platform is when running on
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
+ * {@link Environment#isExternalStorageEmulated(File)} returns true.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
- *
- * <p>Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * <p>
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directory returned by
+ * {@link #getCacheDir()}.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * <p>
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * @return The path of the directory holding application cache files
- * on external storage. Returns null if external storage is not currently
- * mounted so it could not ensure the path exists; you will need to call
- * this method again when it is available.
- *
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
* @see #getCacheDir
+ * @see #getExternalCacheDirs()
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
@Nullable
public abstract File getExternalCacheDir();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place cache files it
- * owns. These files are internal to the application, and not typically
- * visible to the user as media.
+ * shared/external storage devices where the application can place cache
+ * files it owns. These files are internal to the application, and not
+ * typically visible to the user as media.
* <p>
- * This is like {@link #getCacheDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getCacheDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>The platform does not always monitor the space available in shared
+ * storage, and thus may not automatically delete these files. Apps should
+ * always manage the maximum space used in this location. Currently the only
+ * time files here will be deleted by the platform is when running on
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
+ * {@link Environment#isExternalStorageEmulated(File)} returns true.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directory returned by
+ * {@link #getCacheDir()}.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
+ * <p>
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * The first path returned is the same as {@link #getExternalCacheDir()}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned paths may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getExternalCacheDir()}.
* @see #getExternalCacheDir()
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalCacheDirs();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place media files.
- * These files are scanned and made available to other apps through
+ * shared/external storage devices where the application can place media
+ * files. These files are scanned and made available to other apps through
* {@link MediaStore}.
* <p>
* This is like {@link #getExternalFilesDirs} in that these files will be
* deleted when the application is uninstalled, however there are some
* important differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned paths may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available.
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalMediaDirs();
@@ -1094,6 +1199,12 @@
* created through a File object will only be accessible by your own
* application; you can only set the mode of the entire directory, not
* of individual files.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * Apps require no extra permissions to read or write to the returned path,
+ * since this path lives in their private storage.
*
* @param name Name of the directory to retrieve. This is a directory
* that is created as part of your application data.
@@ -1177,6 +1288,9 @@
/**
* Returns the absolute path on the filesystem where a database created with
* {@link #openOrCreateDatabase} is stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
*
* @param name The name of the database for which you would like to get
* its path.
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index a121b4d..3853772 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -67,7 +67,7 @@
* The launch mode style requested by the activity. From the
* {@link android.R.attr#launchMode} attribute, one of
* {@link #LAUNCH_MULTIPLE},
- * {@link #LAUNCH_SINGLE_TOP}, {@link #LAUNCH_SINGLE_TASK}, or
+ * {@link #LAUNCH_SINGLE_TOP}, {@link #LAUNCH_SINGLE_TASK}, or
* {@link #LAUNCH_SINGLE_INSTANCE}.
*/
public int launchMode;
@@ -140,7 +140,7 @@
* Activity. From the "permission" attribute.
*/
public String permission;
-
+
/**
* The affinity this activity has for another task in the system. The
* string here is the name of the task, often the package name of the
@@ -148,13 +148,13 @@
* {@link android.R.attr#taskAffinity} attribute.
*/
public String taskAffinity;
-
+
/**
* If this is an activity alias, this is the real activity class to run
* for it. Otherwise, this is null.
*/
public String targetActivity;
-
+
/**
* Bit in {@link #flags} indicating whether this activity is able to
* run in multiple processes. If
@@ -362,7 +362,7 @@
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_SENSOR = 4;
-
+
/**
* Constant corresponding to <code>nosensor</code> in
* the {@link android.R.attr#screenOrientation} attribute.
@@ -427,7 +427,7 @@
* The preferred screen orientation this activity would like to run in.
* From the {@link android.R.attr#screenOrientation} attribute, one of
* {@link #SCREEN_ORIENTATION_UNSPECIFIED},
- * {@link #SCREEN_ORIENTATION_LANDSCAPE},
+ * {@link #SCREEN_ORIENTATION_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_PORTRAIT},
* {@link #SCREEN_ORIENTATION_USER},
* {@link #SCREEN_ORIENTATION_BEHIND},
@@ -445,7 +445,7 @@
*/
@ScreenOrientation
public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
+
/**
* Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the IMSI MCC. Set from the
@@ -552,7 +552,7 @@
* constant starts at the high bits.
*/
public static final int CONFIG_FONT_SCALE = 0x40000000;
-
+
/** @hide
* Unfortunately the constants for config changes in native code are
* different from ActivityInfo. :( Here are the values we should use for the
@@ -702,7 +702,7 @@
*/
public int lockTaskLaunchMode;
- public InitialLayout initialLayout;
+ public Layout layout;
public ActivityInfo() {
}
@@ -724,7 +724,7 @@
maxRecents = orig.maxRecents;
resizeable = orig.resizeable;
lockTaskLaunchMode = orig.lockTaskLaunchMode;
- initialLayout = orig.initialLayout;
+ layout = orig.layout;
}
/**
@@ -771,10 +771,10 @@
}
pw.println(prefix + "resizeable=" + resizeable + " lockTaskLaunchMode="
+ lockTaskLaunchModeToString(lockTaskLaunchMode));
- if (initialLayout != null) {
- pw.println(prefix + "initialLayout=" + initialLayout.width + "|"
- + initialLayout.widthFraction + ", " + initialLayout.height + "|"
- + initialLayout.heightFraction + ", " + initialLayout.gravity);
+ if (layout != null) {
+ pw.println(prefix + "initialLayout=" + layout.width + "|"
+ + layout.widthFraction + ", " + layout.height + "|"
+ + layout.heightFraction + ", " + layout.gravity);
}
super.dumpBack(pw, prefix);
}
@@ -807,13 +807,14 @@
dest.writeInt(maxRecents);
dest.writeInt(resizeable ? 1 : 0);
dest.writeInt(lockTaskLaunchMode);
- if (initialLayout != null) {
+ if (layout != null) {
dest.writeInt(1);
- dest.writeInt(initialLayout.width);
- dest.writeFloat(initialLayout.widthFraction);
- dest.writeInt(initialLayout.height);
- dest.writeFloat(initialLayout.heightFraction);
- dest.writeInt(initialLayout.gravity);
+ dest.writeInt(layout.width);
+ dest.writeFloat(layout.widthFraction);
+ dest.writeInt(layout.height);
+ dest.writeFloat(layout.heightFraction);
+ dest.writeInt(layout.gravity);
+ dest.writeInt(layout.minimalSize);
} else {
dest.writeInt(0);
}
@@ -848,26 +849,28 @@
resizeable = (source.readInt() == 1);
lockTaskLaunchMode = source.readInt();
if (source.readInt() == 1) {
- initialLayout = new InitialLayout(source);
+ layout = new Layout(source);
}
}
- public static final class InitialLayout {
- public InitialLayout(int width, float widthFraction, int height, float heightFraction,
- int gravity) {
+ public static final class Layout {
+ public Layout(int width, float widthFraction, int height, float heightFraction, int gravity,
+ int minimalSize) {
this.width = width;
this.widthFraction = widthFraction;
this.height = height;
this.heightFraction = heightFraction;
this.gravity = gravity;
+ this.minimalSize = minimalSize;
}
- InitialLayout(Parcel source) {
+ Layout(Parcel source) {
width = source.readInt();
widthFraction = source.readFloat();
height = source.readInt();
heightFraction = source.readFloat();
gravity = source.readInt();
+ minimalSize = source.readInt();
}
public final int width;
@@ -875,5 +878,6 @@
public final int height;
public final float heightFraction;
public final int gravity;
+ public final int minimalSize;
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1a8602b..bf54415 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -128,7 +128,7 @@
public final String name;
public final int sdkVersion;
public final int fileVersion;
-
+
public NewPermissionInfo(String name, int sdkVersion, int fileVersion) {
this.name = name;
this.sdkVersion = sdkVersion;
@@ -215,10 +215,10 @@
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 _bannerRes) {
owner = _owner;
@@ -230,14 +230,14 @@
bannerRes = _bannerRes;
}
}
-
+
static class ParseComponentArgs extends ParsePackageItemArgs {
final String[] sepProcesses;
final int processRes;
final int descriptionRes;
final int enabledRes;
int flags;
-
+
ParseComponentArgs(Package _owner, String[] _outError,
int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes,
String[] _sepProcesses, int _processRes,
@@ -349,7 +349,7 @@
private ParseComponentArgs mParseActivityAliasArgs;
private ParseComponentArgs mParseServiceArgs;
private ParseComponentArgs mParseProviderArgs;
-
+
/** If set to true, we will only allow package files that exactly match
* the DTD. Otherwise, we try to get as much from the package as we
* can without failing. This should normally be set to false, to
@@ -1456,7 +1456,7 @@
int supportsXLargeScreens = 1;
int resizeable = 1;
int anyDensity = 1;
-
+
int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -1612,7 +1612,7 @@
String minCode = null;
int targetVers = 0;
String targetCode = null;
-
+
TypedValue val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) {
@@ -1623,7 +1623,7 @@
targetVers = minVers = val.data;
}
}
-
+
val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
if (val != null) {
@@ -1634,7 +1634,7 @@
targetVers = val.data;
}
}
-
+
sa.recycle();
if (minCode != null) {
@@ -1663,7 +1663,7 @@
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
-
+
if (targetCode != null) {
boolean allowedCodename = false;
for (String codename : SDK_CODENAMES) {
@@ -1730,9 +1730,9 @@
anyDensity);
sa.recycle();
-
+
XmlUtils.skipCurrentTag(parser);
-
+
} else if (tagName.equals("protected-broadcast")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestProtectedBroadcast);
@@ -1754,12 +1754,12 @@
}
XmlUtils.skipCurrentTag(parser);
-
+
} else if (tagName.equals("instrumentation")) {
if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
return null;
}
-
+
} else if (tagName.equals("original-package")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestOriginalPackage);
@@ -1777,7 +1777,7 @@
sa.recycle();
XmlUtils.skipCurrentTag(parser);
-
+
} else if (tagName.equals("adopt-permissions")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestOriginalPackage);
@@ -1795,12 +1795,12 @@
}
XmlUtils.skipCurrentTag(parser);
-
+
} else if (tagName.equals("uses-gl-texture")) {
// Just skip this tag
XmlUtils.skipCurrentTag(parser);
continue;
-
+
} else if (tagName.equals("compatible-screens")) {
// Just skip this tag
XmlUtils.skipCurrentTag(parser);
@@ -1808,12 +1808,12 @@
} else if (tagName.equals("supports-input")) {
XmlUtils.skipCurrentTag(parser);
continue;
-
+
} else if (tagName.equals("eat-comment")) {
// Just skip this tag
XmlUtils.skipCurrentTag(parser);
continue;
-
+
} else if (RIGID_PARSER) {
outError[0] = "Bad element under <manifest>: "
+ parser.getName();
@@ -2017,7 +2017,7 @@
}
return proc.intern();
}
-
+
private static String buildProcessName(String pkg, String defProc,
CharSequence procSeq, int flags, String[] separateProcesses,
String[] outError) {
@@ -2226,7 +2226,7 @@
}
sa.recycle();
-
+
if (!parseAllMetaData(res, parser, attrs, "<permission-group>", perm,
outError)) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -2265,7 +2265,7 @@
if (perm.info.group != null) {
perm.info.group = perm.info.group.intern();
}
-
+
perm.info.descriptionRes = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestPermission_description,
0);
@@ -2296,7 +2296,7 @@
return null;
}
}
-
+
if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
outError)) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -2329,7 +2329,7 @@
}
sa.recycle();
-
+
int index = perm.info.name.indexOf('.');
if (index > 0) {
index = perm.info.name.indexOf('.', index+1);
@@ -2371,9 +2371,9 @@
com.android.internal.R.styleable.AndroidManifestInstrumentation_banner);
mParseInstrumentationArgs.tag = "<instrumentation>";
}
-
+
mParseInstrumentationArgs.sa = sa;
-
+
Instrumentation a = new Instrumentation(mParseInstrumentationArgs,
new InstrumentationInfo());
if (outError[0] != null) {
@@ -2650,10 +2650,10 @@
}
ai.processName = buildProcessName(ai.packageName, null, pname,
flags, mSeparateProcesses, outError);
-
+
ai.enabled = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
-
+
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_isGame, false)) {
ai.flags |= ApplicationInfo.FLAG_IS_GAME;
@@ -3022,7 +3022,7 @@
outInfo.icon = iconVal;
outInfo.nonLocalizedLabel = null;
}
-
+
int logoVal = sa.getResourceId(logoRes, 0);
if (logoVal != 0) {
outInfo.logo = logoVal;
@@ -3061,11 +3061,11 @@
R.styleable.AndroidManifestActivity_description,
R.styleable.AndroidManifestActivity_enabled);
}
-
+
mParseActivityArgs.tag = receiver ? "<receiver>" : "<activity>";
mParseActivityArgs.sa = sa;
mParseActivityArgs.flags = flags;
-
+
Activity a = new Activity(mParseActivityArgs, new ActivityInfo());
if (outError[0] != null) {
sa.recycle();
@@ -3236,7 +3236,7 @@
outError[0] = "Heavy-weight applications can not have receivers in main process";
}
}
-
+
if (outError[0] != null) {
return null;
}
@@ -3282,8 +3282,8 @@
outError)) == null) {
return null;
}
- } else if (!receiver && parser.getName().equals("initial-layout")) {
- parseInitialLayout(res, attrs, a);
+ } else if (!receiver && parser.getName().equals("layout")) {
+ parseLayout(res, attrs, a);
} else {
if (!RIGID_PARSER) {
Slog.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
@@ -3316,41 +3316,44 @@
return a;
}
- private void parseInitialLayout(Resources res, AttributeSet attrs, Activity a) {
+ private void parseLayout(Resources res, AttributeSet attrs, Activity a) {
TypedArray sw = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestInitialLayout);
+ com.android.internal.R.styleable.AndroidManifestLayout);
int width = -1;
float widthFraction = -1f;
int height = -1;
float heightFraction = -1f;
final int widthType = sw.getType(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth);
+ com.android.internal.R.styleable.AndroidManifestLayout_initialWidth);
if (widthType == TypedValue.TYPE_FRACTION) {
widthFraction = sw.getFraction(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth,
+ com.android.internal.R.styleable.AndroidManifestLayout_initialWidth,
1, 1, -1);
} else if (widthType == TypedValue.TYPE_DIMENSION) {
width = sw.getDimensionPixelSize(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth,
+ com.android.internal.R.styleable.AndroidManifestLayout_initialWidth,
-1);
}
final int heightType = sw.getType(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight);
+ com.android.internal.R.styleable.AndroidManifestLayout_initialHeight);
if (heightType == TypedValue.TYPE_FRACTION) {
heightFraction = sw.getFraction(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight,
+ com.android.internal.R.styleable.AndroidManifestLayout_initialHeight,
1, 1, -1);
} else if (heightType == TypedValue.TYPE_DIMENSION) {
height = sw.getDimensionPixelSize(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight,
+ com.android.internal.R.styleable.AndroidManifestLayout_initialHeight,
-1);
}
int gravity = sw.getInt(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_gravity,
+ com.android.internal.R.styleable.AndroidManifestLayout_gravity,
Gravity.CENTER);
+ int minimalSize = sw.getDimensionPixelSize(
+ com.android.internal.R.styleable.AndroidManifestLayout_minimalSize,
+ -1);
sw.recycle();
- a.info.initialLayout = new ActivityInfo.InitialLayout(width, widthFraction,
- height, heightFraction, gravity);
+ a.info.layout = new ActivityInfo.Layout(width, widthFraction,
+ height, heightFraction, gravity, minimalSize);
}
private Activity parseActivityAlias(Package owner, Resources res,
@@ -3388,10 +3391,10 @@
com.android.internal.R.styleable.AndroidManifestActivityAlias_enabled);
mParseActivityAliasArgs.tag = "<activity-alias>";
}
-
+
mParseActivityAliasArgs.sa = sa;
mParseActivityAliasArgs.flags = flags;
-
+
Activity target = null;
final int NA = owner.activities.size();
@@ -3432,7 +3435,7 @@
info.uiOptions = target.info.uiOptions;
info.parentActivityName = target.info.parentActivityName;
info.maxRecents = target.info.maxRecents;
- info.initialLayout = target.info.initialLayout;
+ info.layout = target.info.layout;
Activity a = new Activity(mParseActivityAliasArgs, info);
if (outError[0] != null) {
@@ -3540,10 +3543,10 @@
com.android.internal.R.styleable.AndroidManifestProvider_enabled);
mParseProviderArgs.tag = "<provider>";
}
-
+
mParseProviderArgs.sa = sa;
mParseProviderArgs.flags = flags;
-
+
Provider p = new Provider(mParseProviderArgs, new ProviderInfo());
if (outError[0] != null) {
sa.recycle();
@@ -3632,7 +3635,7 @@
return null;
}
}
-
+
if (cpname == null) {
outError[0] = "<provider> does not include authorities attribute";
return null;
@@ -3675,7 +3678,7 @@
outInfo.metaData, outError)) == null) {
return false;
}
-
+
} else if (parser.getName().equals("grant-uri-permission")) {
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestGrantUriPermission);
@@ -3699,7 +3702,7 @@
if (str != null) {
pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
}
-
+
sa.recycle();
if (pa != null) {
@@ -3746,7 +3749,7 @@
if (writePermission == null) {
writePermission = permission;
}
-
+
boolean havePerm = false;
if (readPermission != null) {
readPermission = readPermission.intern();
@@ -3769,7 +3772,7 @@
return false;
}
}
-
+
String path = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestPathPermission_path, 0);
if (path != null) {
@@ -3852,10 +3855,10 @@
com.android.internal.R.styleable.AndroidManifestService_enabled);
mParseServiceArgs.tag = "<service>";
}
-
+
mParseServiceArgs.sa = sa;
mParseServiceArgs.flags = flags;
-
+
Service s = new Service(mParseServiceArgs, new ServiceInfo());
if (outError[0] != null) {
sa.recycle();
@@ -3912,7 +3915,7 @@
return null;
}
}
-
+
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -4010,7 +4013,7 @@
}
name = name.intern();
-
+
TypedValue v = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestMetaData_resource);
if (v != null && v.resourceId != 0) {
@@ -4152,7 +4155,7 @@
outInfo.icon = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
-
+
outInfo.logo = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);
@@ -4373,7 +4376,7 @@
public ArrayList<String> mOriginalPackages = null;
public String mRealPackage = null;
public ArrayList<String> mAdoptPermissions = null;
-
+
// We store the application meta-data independently to avoid multiple unwanted references
public Bundle mAppMetaData = null;
@@ -4382,7 +4385,7 @@
// The version name declared for this package.
public String mVersionName;
-
+
// The shared user id that this package wants to use.
public String mSharedUserId;
@@ -4604,7 +4607,7 @@
ComponentName componentName;
String componentShortName;
-
+
public Component(Package _owner) {
owner = _owner;
intents = null;
@@ -4636,7 +4639,7 @@
outInfo.icon = iconVal;
outInfo.nonLocalizedLabel = null;
}
-
+
int logoVal = args.sa.getResourceId(args.logoRes, 0);
if (logoVal != 0) {
outInfo.logo = logoVal;
@@ -4676,11 +4679,11 @@
owner.applicationInfo.processName, pname,
args.flags, args.sepProcesses, args.outError);
}
-
+
if (args.descriptionRes != 0) {
outInfo.descriptionRes = args.sa.getResourceId(args.descriptionRes, 0);
}
-
+
outInfo.enabled = args.sa.getBoolean(args.enabledRes, true);
}
@@ -4691,7 +4694,7 @@
componentName = clone.componentName;
componentShortName = clone.componentShortName;
}
-
+
public ComponentName getComponentName() {
if (componentName != null) {
return componentName;
@@ -4716,7 +4719,7 @@
componentShortName = null;
}
}
-
+
public final static class Permission extends Component<IntentInfo> {
public final PermissionInfo info;
public boolean tree;
@@ -4731,7 +4734,7 @@
super(_owner);
info = _info;
}
-
+
public void setPackageName(String packageName) {
super.setPackageName(packageName);
info.packageName = packageName;
@@ -4922,7 +4925,7 @@
info = _info;
info.applicationInfo = args.owner.applicationInfo;
}
-
+
public void setPackageName(String packageName) {
super.setPackageName(packageName);
info.packageName = packageName;
@@ -4976,7 +4979,7 @@
info = _info;
info.applicationInfo = args.owner.applicationInfo;
}
-
+
public void setPackageName(String packageName) {
super.setPackageName(packageName);
info.packageName = packageName;
@@ -5019,7 +5022,7 @@
info.applicationInfo = args.owner.applicationInfo;
syncable = false;
}
-
+
public Provider(Provider existingProvider) {
super(existingProvider);
this.info = existingProvider.info;
@@ -5070,7 +5073,7 @@
super(args, _info);
info = _info;
}
-
+
public void setPackageName(String packageName) {
super.setPackageName(packageName);
info.packageName = packageName;
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 64d6da5..f346fe7 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -276,8 +276,8 @@
}
/**
- * Return the primary external storage directory. This directory may not
- * currently be accessible if it has been mounted by the user on their
+ * Return the primary shared/external storage directory. This directory may
+ * not currently be accessible if it has been mounted by the user on their
* computer, has been removed from the device, or some other problem has
* happened. You can determine its current state with
* {@link #getExternalStorageState()}.
@@ -291,12 +291,15 @@
* filesystem on a computer.</em>
* <p>
* On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only have
- * access to the external storage for the user they're running as.
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
* <p>
- * In devices with multiple "external" storage directories, this directory
- * represents the "primary" external storage that the user will interact
+ * In devices with multiple shared/external storage directories, this
+ * directory represents the primary storage that the user will interact
* with. Access to secondary storage is available through
+ * {@link Context#getExternalFilesDirs(String)},
+ * {@link Context#getExternalCacheDirs()}, and
+ * {@link Context#getExternalMediaDirs()}.
* <p>
* Applications should not directly use this top-level directory, in order
* to avoid polluting the user's root namespace. Any files that are private
@@ -315,8 +318,9 @@
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, if your
* application only needs to store internal data, consider using
- * {@link Context#getExternalFilesDir(String)} or
- * {@link Context#getExternalCacheDir()}, which require no permissions to
+ * {@link Context#getExternalFilesDir(String)},
+ * {@link Context#getExternalCacheDir()}, or
+ * {@link Context#getExternalMediaDirs()}, which require no permissions to
* read or write.
* <p>
* This path may change between platform versions, so applications should
@@ -325,8 +329,7 @@
* Here is an example of typical code to monitor the state of external
* storage:
* <p>
- * {@sample
- * development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* monitor_storage}
*
* @see #getExternalStorageState()
@@ -446,32 +449,32 @@
public static String DIRECTORY_DOCUMENTS = "Documents";
/**
- * Get a top-level public external storage directory for placing files of
- * a particular type. This is where the user will typically place and
- * manage their own files, so you should be careful about what you put here
- * to ensure you don't erase their files or get in the way of their own
+ * Get a top-level shared/external storage directory for placing files of a
+ * particular type. This is where the user will typically place and manage
+ * their own files, so you should be careful about what you put here to
+ * ensure you don't erase their files or get in the way of their own
* organization.
- *
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * <p>Here is an example of typical code to manipulate a picture on
- * the public external storage:</p>
- *
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * </p>
+ * <p>
+ * Here is an example of typical code to manipulate a picture on the public
+ * shared storage:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* public_picture}
*
- * @param type The type of storage directory to return. Should be one of
- * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
- * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
- * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
- * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
- * {@link #DIRECTORY_DCIM}. May not be null.
- *
- * @return Returns the File path for the directory. Note that this
- * directory may not yet exist, so you must make sure it exists before
- * using it such as with {@link File#mkdirs File.mkdirs()}.
+ * @param type The type of storage directory to return. Should be one of
+ * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
+ * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
+ * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
+ * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
+ * {@link #DIRECTORY_DCIM}. May not be null.
+ * @return Returns the File path for the directory. Note that this directory
+ * may not yet exist, so you must make sure it exists before using
+ * it such as with {@link File#mkdirs File.mkdirs()}.
*/
public static File getExternalStoragePublicDirectory(String type) {
throwIfUserRequired();
@@ -623,7 +626,7 @@
public static final String MEDIA_EJECTING = "ejecting";
/**
- * Returns the current state of the primary "external" storage device.
+ * Returns the current state of the primary shared/external storage media.
*
* @see #getExternalStorageDirectory()
* @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
@@ -646,8 +649,8 @@
}
/**
- * Returns the current state of the storage device that provides the given
- * path.
+ * Returns the current state of the shared/external storage media at the
+ * given path.
*
* @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
* {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING},
@@ -665,7 +668,8 @@
}
/**
- * Returns whether the primary "external" storage device is removable.
+ * Returns whether the primary shared/external storage media is physically
+ * removable.
*
* @return true if the storage device can be removed (such as an SD card),
* or false if the storage device is built in and cannot be
@@ -678,8 +682,8 @@
}
/**
- * Returns whether the storage device that provides the given path is
- * removable.
+ * Returns whether the shared/external storage media at the given path is
+ * physically removable.
*
* @return true if the storage device can be removed (such as an SD card),
* or false if the storage device is built in and cannot be
@@ -697,9 +701,15 @@
}
/**
- * Returns whether the primary "external" storage device is emulated. If
- * true, data stored on this device will be stored on a portion of the
- * internal storage system.
+ * Returns whether the primary shared/external storage media is emulated.
+ * <p>
+ * The contents of emulated storage devices are backed by a private user
+ * data partition, which means there is little benefit to apps storing data
+ * here instead of the private directories returned by
+ * {@link Context#getFilesDir()}, etc.
+ * <p>
+ * This returns true when emulated storage is backed by either internal
+ * storage or an adopted storage device.
*
* @see DevicePolicyManager#setStorageEncryption(android.content.ComponentName,
* boolean)
@@ -711,9 +721,16 @@
}
/**
- * Returns whether the storage device that provides the given path is
- * emulated. If true, data stored on this device will be stored on a portion
- * of the internal storage system.
+ * Returns whether the shared/external storage media at the given path is
+ * emulated.
+ * <p>
+ * The contents of emulated storage devices are backed by a private user
+ * data partition, which means there is little benefit to apps storing data
+ * here instead of the private directories returned by
+ * {@link Context#getFilesDir()}, etc.
+ * <p>
+ * This returns true when emulated storage is backed by either internal
+ * storage or an adopted storage device.
*
* @throws IllegalArgumentException if the path is not a valid storage
* device.
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 4c19ddd..3ade170 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -46,6 +46,7 @@
List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
boolean canAddMoreManagedProfiles(int userId);
UserInfo getProfileParent(int userHandle);
+ boolean isSameProfileGroup(int userId, int otherUserId);
UserInfo getUserInfo(int userHandle);
long getUserCreationTime(int userHandle);
boolean isRestricted();
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 796addc..95da438 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -270,13 +270,24 @@
* Returns true if this UserHandle refers to the owner user; false otherwise.
* @return true if this UserHandle refers to the owner user; false otherwise.
* @hide
- * TODO: find an alternative to this Api.
+ * @deprecated please use {@link #isSystem()} or check for
+ * {@link android.content.pm.UserInfo#isPrimary()}
+ * {@link android.content.pm.UserInfo#isAdmin()} based on your particular use case.
*/
@SystemApi
public boolean isOwner() {
return this.equals(OWNER);
}
+ /**
+ * @return true if this UserHandle refers to the system user; false otherwise.
+ * @hide
+ */
+ @SystemApi
+ public boolean isSystem() {
+ return this.equals(SYSTEM);
+ }
+
/** @hide */
public UserHandle(int h) {
mHandle = h;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d178d20..1c1575e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1093,6 +1093,22 @@
}
/**
+ * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ * @param userId one of the two user ids to check.
+ * @param otherUserId one of the two user ids to check.
+ * @return true if the two user ids are in the same profile group.
+ * @hide
+ */
+ public boolean isSameProfileGroup(int userId, int otherUserId) {
+ try {
+ return mService.isSameProfileGroup(userId, otherUserId);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not get user list", re);
+ return false;
+ }
+ }
+
+ /**
* Returns list of the profiles of userHandle including
* userHandle itself.
* Note that this returns only enabled.
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 13544851..d9ec866 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -666,7 +666,7 @@
void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
CharSequence curTitle = wp.getTitle();
if (wp.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
- wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
+ wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
if (wp.token == null) {
View decor = peekDecorView();
if (decor != null) {
@@ -674,24 +674,38 @@
}
}
if (curTitle == null || curTitle.length() == 0) {
- String title;
+ final StringBuilder title = new StringBuilder(32);
if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {
- title="Media";
+ title.append("Media");
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {
- title="MediaOvr";
+ title.append("MediaOvr");
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
- title="Panel";
+ title.append("Panel");
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {
- title="SubPanel";
+ title.append("SubPanel");
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL) {
- title="AboveSubPanel";
+ title.append("AboveSubPanel");
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {
- title="AtchDlg";
+ title.append("AtchDlg");
} else {
- title=Integer.toString(wp.type);
+ title.append(wp.type);
}
if (mAppName != null) {
- title += ":" + mAppName;
+ title.append(":").append(mAppName);
+ }
+ wp.setTitle(title);
+ }
+ } else if (wp.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW &&
+ wp.type <= WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
+ // We don't set the app token to this system window because the life cycles should be
+ // independent. If an app creates a system window and then the app goes to the stopped
+ // state, the system window should not be affected (can still show and receive input
+ // events).
+ if (curTitle == null || curTitle.length() == 0) {
+ final StringBuilder title = new StringBuilder(32);
+ title.append("Sys").append(wp.type);
+ if (mAppName != null) {
+ title.append(":").append(mAppName);
}
wp.setTitle(title);
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index aaa89df..9a5cde6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -70,6 +70,7 @@
private static final String TAG = "Zygote";
private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
+ private static final String PROPERTY_RUNNING_IN_CONTAINER = "ro.boot.container";
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
@@ -503,7 +504,6 @@
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
- OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
@@ -515,6 +515,10 @@
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
+ /* Containers run without this capability, so avoid setting it in that case */
+ if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
+ capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
+ }
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 81d46c3..f12d208f 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -767,94 +767,94 @@
{ "nativeAddBatch",
"(JJ[Landroid/view/MotionEvent$PointerCoords;I)V",
(void*)android_view_MotionEvent_nativeAddBatch },
- { "nativeGetDeviceId",
+ { "!nativeGetDeviceId",
"(J)I",
(void*)android_view_MotionEvent_nativeGetDeviceId },
- { "nativeGetSource",
+ { "!nativeGetSource",
"(J)I",
(void*)android_view_MotionEvent_nativeGetSource },
- { "nativeSetSource",
+ { "!nativeSetSource",
"(JI)I",
(void*)android_view_MotionEvent_nativeSetSource },
- { "nativeGetAction",
+ { "!nativeGetAction",
"(J)I",
(void*)android_view_MotionEvent_nativeGetAction },
- { "nativeSetAction",
+ { "!nativeSetAction",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetAction },
- { "nativeGetActionButton",
+ { "!nativeGetActionButton",
"(J)I",
(void*)android_view_MotionEvent_nativeGetActionButton},
- { "nativeSetActionButton",
+ { "!nativeSetActionButton",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetActionButton},
- { "nativeIsTouchEvent",
+ { "!nativeIsTouchEvent",
"(J)Z",
(void*)android_view_MotionEvent_nativeIsTouchEvent },
- { "nativeGetFlags",
+ { "!nativeGetFlags",
"(J)I",
(void*)android_view_MotionEvent_nativeGetFlags },
- { "nativeSetFlags",
+ { "!nativeSetFlags",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetFlags },
- { "nativeGetEdgeFlags",
+ { "!nativeGetEdgeFlags",
"(J)I",
(void*)android_view_MotionEvent_nativeGetEdgeFlags },
- { "nativeSetEdgeFlags",
+ { "!nativeSetEdgeFlags",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetEdgeFlags },
- { "nativeGetMetaState",
+ { "!nativeGetMetaState",
"(J)I",
(void*)android_view_MotionEvent_nativeGetMetaState },
- { "nativeGetButtonState",
+ { "!nativeGetButtonState",
"(J)I",
(void*)android_view_MotionEvent_nativeGetButtonState },
- { "nativeSetButtonState",
+ { "!nativeSetButtonState",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetButtonState },
- { "nativeOffsetLocation",
+ { "!nativeOffsetLocation",
"(JFF)V",
(void*)android_view_MotionEvent_nativeOffsetLocation },
- { "nativeGetXOffset",
+ { "!nativeGetXOffset",
"(J)F",
(void*)android_view_MotionEvent_nativeGetXOffset },
- { "nativeGetYOffset",
+ { "!nativeGetYOffset",
"(J)F",
(void*)android_view_MotionEvent_nativeGetYOffset },
- { "nativeGetXPrecision",
+ { "!nativeGetXPrecision",
"(J)F",
(void*)android_view_MotionEvent_nativeGetXPrecision },
- { "nativeGetYPrecision",
+ { "!nativeGetYPrecision",
"(J)F",
(void*)android_view_MotionEvent_nativeGetYPrecision },
- { "nativeGetDownTimeNanos",
+ { "!nativeGetDownTimeNanos",
"(J)J",
(void*)android_view_MotionEvent_nativeGetDownTimeNanos },
- { "nativeSetDownTimeNanos",
+ { "!nativeSetDownTimeNanos",
"(JJ)V",
(void*)android_view_MotionEvent_nativeSetDownTimeNanos },
- { "nativeGetPointerCount",
+ { "!nativeGetPointerCount",
"(J)I",
(void*)android_view_MotionEvent_nativeGetPointerCount },
- { "nativeGetPointerId",
+ { "!nativeGetPointerId",
"(JI)I",
(void*)android_view_MotionEvent_nativeGetPointerId },
- { "nativeGetToolType",
+ { "!nativeGetToolType",
"(JI)I",
(void*)android_view_MotionEvent_nativeGetToolType },
- { "nativeFindPointerIndex",
+ { "!nativeFindPointerIndex",
"(JI)I",
(void*)android_view_MotionEvent_nativeFindPointerIndex },
- { "nativeGetHistorySize",
+ { "!nativeGetHistorySize",
"(J)I",
(void*)android_view_MotionEvent_nativeGetHistorySize },
- { "nativeGetEventTimeNanos",
+ { "!nativeGetEventTimeNanos",
"(JI)J",
(void*)android_view_MotionEvent_nativeGetEventTimeNanos },
- { "nativeGetRawAxisValue",
+ { "!nativeGetRawAxisValue",
"(JIII)F",
(void*)android_view_MotionEvent_nativeGetRawAxisValue },
- { "nativeGetAxisValue",
+ { "!nativeGetAxisValue",
"(JIII)F",
(void*)android_view_MotionEvent_nativeGetAxisValue },
{ "nativeGetPointerCoords",
@@ -863,7 +863,7 @@
{ "nativeGetPointerProperties",
"(JILandroid/view/MotionEvent$PointerProperties;)V",
(void*)android_view_MotionEvent_nativeGetPointerProperties },
- { "nativeScale",
+ { "!nativeScale",
"(JF)V",
(void*)android_view_MotionEvent_nativeScale },
{ "nativeTransform",
diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml
index d37f5b7..c2a2a26 100644
--- a/core/res/res/drawable/spinner_background_material.xml
+++ b/core/res/res/drawable/spinner_background_material.xml
@@ -17,18 +17,18 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingMode="stack"
android:paddingStart="0dp"
- android:paddingEnd="24dp"
+ android:paddingEnd="48dp"
android:paddingLeft="0dp"
android:paddingRight="0dp">
<item
- android:gravity="end|center_vertical"
- android:width="24dp"
- android:height="24dp"
+ android:gravity="end|fill_vertical"
+ android:width="48dp"
android:drawable="@drawable/control_background_40dp_material" />
<item
android:drawable="@drawable/ic_spinner_caret"
android:gravity="end|center_vertical"
android:width="24dp"
- android:height="24dp" />
+ android:height="24dp"
+ android:end="12dp" />
</layer-list>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 9d844a8..322ac4f 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2197,18 +2197,25 @@
<attr name="name" />
</declare-styleable>
- <!-- <code>initial-layout</code> tag allows configuring the initial layout for the activity
- within multi-window environment. -->
- <declare-styleable name="AndroidManifestInitialLayout" parent="AndroidManifestActivity">
+ <!-- <code>layout</code> tag allows configuring the layout for the activity within multi-window
+ environment. -->
+ <declare-styleable name="AndroidManifestLayout" parent="AndroidManifestActivity">
<!-- Initial width of the activity. Can be either a fixed value or fraction, in which case
the width will be constructed as a fraction of the total available width. -->
- <attr name="activityWidth" format="dimension|fraction" />
+ <attr name="initialWidth" format="dimension|fraction" />
<!-- Initial height of the activity. Can be either a fixed value or fraction, in which case
the height will be constructed as a fraction of the total available height. -->
- <attr name="activityHeight" format="dimension|fraction" />
+ <attr name="initialHeight" format="dimension|fraction" />
<!-- Where to initially position the activity inside the available space. Uses constants
defined in {@link android.view.Gravity}. -->
<attr name="gravity" />
+ <!-- Minimal height of the activity.
+
+ <p>NOTE: A task's root activity value is applied to all additional activities launched
+ in the task. That is if the root activity of a task set minimal size, then the system
+ will set the same minimal size on all other activities in the task. It will also
+ ignore any other minimal size attributes of non-root activities. -->
+ <attr name="minimalSize" format="dimension" />
</declare-styleable>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6e956d7..f833719 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2321,7 +2321,7 @@
<!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
<bool name="config_eap_sim_based_auth_supported">true</bool>
-
+
<!-- How long history of previous vibrations should be kept for the dumpsys. -->
<integer name="config_previousVibrationsDumpLimit">20</integer>
@@ -2352,4 +2352,8 @@
<!-- Name of the component to handle network policy notifications. If present,
disables NetworkPolicyManagerService's presentation of data-usage notifications. -->
<string translatable="false" name="config_networkPolicyNotificationComponent"></string>
+
+ <!-- The fraction of display size (lower of height and width) that will be used to determine
+ the default minimal size for resizeable tasks. -->
+ <fraction name="config_displayFractionForDefaultMinimalSizeOfResizeableTask">25%</fraction>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f4d0b39..957cb50 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2662,8 +2662,9 @@
<public type="attr" name="listMenuViewStyle" />
<public type="attr" name="subMenuArrow" />
- <public type="attr" name="activityWidth" />
- <public type="attr" name="activityHeight" />
+ <public type="attr" name="initialWidth" />
+ <public type="attr" name="initialHeight" />
+ <public type="attr" name="minimalSize" />
<public type="attr" name="resizeableActivity" />
<public type="attr" name="titleMargin" />
<public type="attr" name="titleMarginStart" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 953b98f..1239b87 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1686,6 +1686,7 @@
<java-symbol type="id" name="replace_app_icon" />
<java-symbol type="id" name="replace_message" />
<java-symbol type="fraction" name="config_dimBehindFadeDuration" />
+ <java-symbol type="fraction" name="config_displayFractionForDefaultMinimalSizeOfResizeableTask" />
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
<java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
<java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/>
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 6f548bc..9fc3924 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -254,6 +254,7 @@
LOCAL_STATIC_LIBRARIES := libbenchmark libbase
LOCAL_SRC_FILES += \
- microbench/DisplayListCanvasBench.cpp
+ microbench/DisplayListCanvasBench.cpp \
+ microbench/LinearAllocatorBench.cpp
include $(BUILD_EXECUTABLE)
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 2337299..793d8c0 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -67,13 +67,8 @@
regions.clear();
}
-#if HWUI_NEW_OPS
-size_t DisplayListData::addChild(RenderNodeOp* op) {
+size_t DisplayListData::addChild(NodeOpType* op) {
mReferenceHolders.push_back(op->renderNode);
-#else
-size_t DisplayListData::addChild(DrawRenderNodeOp* op) {
- mReferenceHolders.push_back(op->renderNode);
-#endif
size_t index = mChildren.size();
mChildren.push_back(op);
return index;
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 8ba9ac3..80ff96a 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -58,8 +58,14 @@
#if HWUI_NEW_OPS
struct RecordedOp;
struct RenderNodeOp;
+
+typedef RecordedOp BaseOpType;
+typedef RenderNodeOp NodeOpType;
#else
class DrawRenderNodeOp;
+
+typedef DisplayListOp BaseOpType;
+typedef DrawRenderNodeOp NodeOpType;
#endif
/**
@@ -143,19 +149,12 @@
const std::vector<Chunk>& getChunks() const {
return chunks;
}
-#if HWUI_NEW_OPS
- const std::vector<RecordedOp*>& getOps() const {
+ const std::vector<BaseOpType*>& getOps() const {
return ops;
}
-#endif
-#if HWUI_NEW_OPS
- size_t addChild(RenderNodeOp* childOp);
- const std::vector<RenderNodeOp*>& children() { return mChildren; }
-#else
- size_t addChild(DrawRenderNodeOp* childOp);
- const std::vector<DrawRenderNodeOp*>& children() { return mChildren; }
-#endif
+ size_t addChild(NodeOpType* childOp);
+ const std::vector<NodeOpType*>& children() { return mChildren; }
void ref(VirtualLightRefBase* prop) {
mReferenceHolders.push_back(prop);
@@ -169,18 +168,12 @@
}
private:
-#if HWUI_NEW_OPS
- std::vector<RecordedOp*> ops;
-#endif
+ std::vector<BaseOpType*> ops;
std::vector< sp<VirtualLightRefBase> > mReferenceHolders;
-#if HWUI_NEW_OPS
- std::vector<RenderNodeOp*> mChildren;
-#else
// list of children display lists for quick, non-drawing traversal
- std::vector<DrawRenderNodeOp*> mChildren;
-#endif
+ std::vector<NodeOpType*> mChildren;
std::vector<Chunk> chunks;
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 8d0ab03..a1adb80 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -514,8 +514,12 @@
}
size_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) {
- int insertIndex = mDisplayListData->displayListOps.size();
- mDisplayListData->displayListOps.push_back(op);
+ int insertIndex = mDisplayListData->ops.size();
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("unsupported");
+#else
+ mDisplayListData->ops.push_back(op);
+#endif
if (mDeferredBarrierType != kBarrier_None) {
// op is first in new chunk
mDisplayListData->chunks.emplace_back();
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 392bb3e..8f4ae3d 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -66,8 +66,7 @@
virtual ~DisplayListCanvas();
void reset(int width, int height);
-
- DisplayListData* finishRecording();
+ __attribute__((warn_unused_result)) DisplayListData* finishRecording();
// ----------------------------------------------------------------------------
// HWUI Canvas state operations
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index 1d8be2b..2e02306 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -212,10 +212,11 @@
: mCanvasState(sNullClient) {
}
-void OpReorderer::defer(int viewportWidth, int viewportHeight,
+void OpReorderer::defer(const SkRect& clip, int viewportWidth, int viewportHeight,
const std::vector< sp<RenderNode> >& nodes) {
mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
- 0, 0, viewportWidth, viewportHeight, Vector3());
+ clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
+ Vector3());
for (const sp<RenderNode>& node : nodes) {
if (node->nothingToDraw()) continue;
@@ -325,7 +326,7 @@
// if no target, merging ops still interate to find similar batch to insert after
void OpReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds,
BatchBase** targetBatch, size_t* insertBatchIndex) const {
- for (size_t i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
+ for (int i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
BatchBase* overBatch = mBatches[i];
if (overBatch == *targetBatch) break;
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index b99172c..395a1ba 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -25,6 +25,8 @@
#include <vector>
#include <unordered_map>
+struct SkRect;
+
namespace android {
namespace uirenderer {
@@ -57,7 +59,8 @@
OpReorderer();
// TODO: not final, just presented this way for simplicity. Layers too?
- void defer(int viewportWidth, int viewportHeight, const std::vector< sp<RenderNode> >& nodes);
+ void defer(const SkRect& clip, int viewportWidth, int viewportHeight,
+ const std::vector< sp<RenderNode> >& nodes);
void defer(int viewportWidth, int viewportHeight,
const std::vector<DisplayListData::Chunk>& chunks, const std::vector<RecordedOp*>& ops);
@@ -133,7 +136,7 @@
// contains ResolvedOps and Batches
LinearAllocator mAllocator;
- size_t mEarliestBatchIndex = 0;
+ int mEarliestBatchIndex = 0;
};
}; // namespace uirenderer
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index ed299e5..8f44ff0 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -41,7 +41,7 @@
virtual ~RecordingCanvas();
void reset(int width, int height);
- DisplayListData* finishRecording();
+ __attribute__((warn_unused_result)) DisplayListData* finishRecording();
// ----------------------------------------------------------------------------
// MISC HWUI OPERATIONS - TODO: CATEGORIZE
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d122a55..28586fa 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -49,8 +49,8 @@
mLayer->wasBuildLayered ? "true" : "false");
}
if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- mDisplayListData->children()[i]->renderNode->debugDumpLayers(prefix);
+ for (auto&& child : mDisplayListData->children()) {
+ child->renderNode->debugDumpLayers(prefix);
}
}
}
@@ -97,12 +97,16 @@
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
properties().debugOutputProperties(level);
- int flags = DisplayListOp::kOpLogFlag_Recurse;
+
if (mDisplayListData) {
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("op dumping unsupported");
+#else
// TODO: consider printing the chunk boundaries here
- for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
- mDisplayListData->displayListOps[i]->output(level, flags);
+ for (auto&& op : mDisplayListData->getOps()) {
+ op->output(level, DisplayListOp::kOpLogFlag_Recurse);
}
+#endif
}
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName());
@@ -916,7 +920,12 @@
// Transform renderer to match background we're projecting onto
// (by offsetting canvas by translationX/Y of background rendernode, since only those are set)
const DisplayListOp* op =
- (mDisplayListData->displayListOps[mDisplayListData->projectionReceiveIndex]);
+#if HWUI_NEW_OPS
+ nullptr;
+ LOG_ALWAYS_FATAL("unsupported");
+#else
+ (mDisplayListData->getOps()[mDisplayListData->projectionReceiveIndex]);
+#endif
const DrawRenderNodeOp* backgroundOp = reinterpret_cast<const DrawRenderNodeOp*>(op);
const RenderProperties& backgroundProps = backgroundOp->renderNode->properties();
renderer.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY());
@@ -997,6 +1006,9 @@
setViewProperties<T>(renderer, handler);
}
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("legacy op traversal not supported");
+#else
bool quickRejected = properties().getClipToBounds()
&& renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
if (!quickRejected) {
@@ -1018,9 +1030,8 @@
issueOperationsOf3dChildren(ChildrenSelectMode::NegativeZChildren,
initialTransform, zTranslatedNodes, renderer, handler);
-
for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
- DisplayListOp *op = mDisplayListData->displayListOps[opIndex];
+ DisplayListOp *op = mDisplayListData->getOps()[opIndex];
#if DEBUG_DISPLAY_LIST
op->output(handler.level() + 1);
#endif
@@ -1037,6 +1048,7 @@
}
}
}
+#endif
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (handler.level() + 1) * 2, "", restoreTo);
handler(new (alloc) RestoreToCountOp(restoreTo),
diff --git a/libs/hwui/microbench/DisplayListCanvasBench.cpp b/libs/hwui/microbench/DisplayListCanvasBench.cpp
index fd42adb..dccbe0b 100644
--- a/libs/hwui/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/microbench/DisplayListCanvasBench.cpp
@@ -15,7 +15,6 @@
*/
#include <benchmark/Benchmark.h>
-#include <utils/Singleton.h>
#include "DisplayList.h"
#if HWUI_NEW_OPS
@@ -59,13 +58,13 @@
BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_empty);
void BM_DisplayListCanvas_record_empty::Run(int iters) {
TestCanvas canvas(100, 100);
- canvas.finishRecording();
+ delete canvas.finishRecording();
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
canvas.reset(100, 100);
MicroBench::DoNotOptimize(&canvas);
- canvas.finishRecording();
+ delete canvas.finishRecording();
}
StopBenchmarkTiming();
}
@@ -73,7 +72,7 @@
BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_saverestore);
void BM_DisplayListCanvas_record_saverestore::Run(int iters) {
TestCanvas canvas(100, 100);
- canvas.finishRecording();
+ delete canvas.finishRecording();
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -83,7 +82,7 @@
MicroBench::DoNotOptimize(&canvas);
canvas.restore();
canvas.restore();
- canvas.finishRecording();
+ delete canvas.finishRecording();
}
StopBenchmarkTiming();
}
@@ -91,14 +90,14 @@
BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_translate);
void BM_DisplayListCanvas_record_translate::Run(int iters) {
TestCanvas canvas(100, 100);
- canvas.finishRecording();
+ delete canvas.finishRecording();
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
canvas.reset(100, 100);
canvas.scale(10, 10);
MicroBench::DoNotOptimize(&canvas);
- canvas.finishRecording();
+ delete canvas.finishRecording();
}
StopBenchmarkTiming();
}
diff --git a/libs/hwui/microbench/LinearAllocatorBench.cpp b/libs/hwui/microbench/LinearAllocatorBench.cpp
new file mode 100644
index 0000000..75f57cb
--- /dev/null
+++ b/libs/hwui/microbench/LinearAllocatorBench.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <benchmark/Benchmark.h>
+
+#include "utils/LinearAllocator.h"
+#include "microbench/MicroBench.h"
+
+#include <vector>
+
+using namespace android;
+using namespace android::uirenderer;
+
+BENCHMARK_NO_ARG(BM_LinearStdAllocator_vectorBaseline);
+void BM_LinearStdAllocator_vectorBaseline::Run(int iters) {
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ std::vector<char> v;
+ for (int j = 0; j < 200; j++) {
+ v.push_back(j);
+ }
+ MicroBench::DoNotOptimize(&v);
+ }
+ StopBenchmarkTiming();
+}
+
+BENCHMARK_NO_ARG(BM_LinearStdAllocator_vector);
+void BM_LinearStdAllocator_vector::Run(int iters) {
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ LinearAllocator la;
+ LinearStdAllocator<void*> stdAllocator(la);
+ std::vector<char, LinearStdAllocator<char> > v(stdAllocator);
+ for (int j = 0; j < 200; j++) {
+ v.push_back(j);
+ }
+ MicroBench::DoNotOptimize(&v);
+ }
+ StopBenchmarkTiming();
+}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index e1d8abd..238cf06 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -266,11 +266,11 @@
Frame frame = mEglManager.beginFrame(mEglSurface);
-#if !HWUI_NEW_OPS
- if (frame.width() != mCanvas->getViewportWidth()
- || frame.height() != mCanvas->getViewportHeight()) {
+ if (frame.width() != lastFrameWidth || frame.height() != lastFrameHeight) {
// can't rely on prior content of window if viewport size changes
dirty.setEmpty();
+ lastFrameWidth = frame.width();
+ lastFrameHeight = frame.height();
} else if (mHaveNewSurface || frame.bufferAge() == 0) {
// New surface needs a full draw
dirty.setEmpty();
@@ -316,6 +316,18 @@
mDamageHistory.next() = screenDirty;
mEglManager.damageFrame(frame, dirty);
+
+#if HWUI_NEW_OPS
+ OpReorderer reorderer;
+ reorderer.defer(dirty, frame.width(), frame.height(), mRenderNodes);
+ BakedOpRenderer::Info info(Caches::getInstance(), mRenderThread.renderState(),
+ frame.width(), frame.height(), mOpaque);
+ // TODO: profiler().draw(mCanvas);
+ reorderer.replayBakedOps<BakedOpRenderer>(&info);
+
+ bool drew = info.didDraw;
+
+#else
mCanvas->prepareDirty(frame.width(), frame.height(),
dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque);
@@ -426,20 +438,10 @@
profiler().draw(mCanvas);
bool drew = mCanvas->finish();
-
+#endif
// Even if we decided to cancel the frame, from the perspective of jank
// metrics the frame was swapped at this point
mCurrentFrameInfo->markSwapBuffers();
-#else
- OpReorderer reorderer;
- reorderer.defer(frame.width(), frame.height(), mRenderNodes);
- BakedOpRenderer::Info info(Caches::getInstance(), mRenderThread.renderState(),
- frame.width(), frame.height(), mOpaque);
- reorderer.replayBakedOps<BakedOpRenderer>(&info);
-
- bool drew = info.didDraw;
- SkRect screenDirty = SkRect::MakeWH(frame.width(), frame.height());
-#endif
if (drew) {
if (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty))) {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index e0cbabd..16956e6 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -141,6 +141,9 @@
void freePrefetechedLayers();
+ int lastFrameWidth = 0;
+ int lastFrameHeight = 0;
+
RenderThread& mRenderThread;
EglManager& mEglManager;
sp<ANativeWindow> mNativeWindow;
diff --git a/libs/hwui/unit_tests/LinearAllocatorTests.cpp b/libs/hwui/unit_tests/LinearAllocatorTests.cpp
index b3959d1..02cd77a 100644
--- a/libs/hwui/unit_tests/LinearAllocatorTests.cpp
+++ b/libs/hwui/unit_tests/LinearAllocatorTests.cpp
@@ -106,3 +106,31 @@
// Checking for a double-destroy case
EXPECT_EQ(destroyed, false);
}
+
+TEST(LinearStdAllocator, simpleAllocate) {
+ LinearAllocator la;
+ LinearStdAllocator<void*> stdAllocator(la);
+
+ std::vector<char, LinearStdAllocator<char> > v(stdAllocator);
+ v.push_back(0);
+ char* initialLocation = &v[0];
+ v.push_back(10);
+ v.push_back(20);
+ v.push_back(30);
+
+ // expect to have allocated (since no space reserved), so [0] will have moved to
+ // slightly further down in the same LinearAllocator page
+ EXPECT_LT(initialLocation, &v[0]);
+ EXPECT_GT(initialLocation + 20, &v[0]);
+
+ // expect to have allocated again inserting 4 more entries
+ char* lastLocation = &v[0];
+ v.push_back(40);
+ v.push_back(50);
+ v.push_back(60);
+ v.push_back(70);
+
+ EXPECT_LT(lastLocation, &v[0]);
+ EXPECT_GT(lastLocation + 20, &v[0]);
+
+}
diff --git a/libs/hwui/unit_tests/OpReordererTests.cpp b/libs/hwui/unit_tests/OpReordererTests.cpp
index fcaea1e..cbfbb23 100644
--- a/libs/hwui/unit_tests/OpReordererTests.cpp
+++ b/libs/hwui/unit_tests/OpReordererTests.cpp
@@ -50,9 +50,7 @@
};
TEST(OpReorderer, simple) {
auto dld = TestUtils::createDLD<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
- SkBitmap bitmap;
- bitmap.setInfo(SkImageInfo::MakeUnknown(25, 25));
-
+ SkBitmap bitmap = TestUtils::createSkBitmap(25, 25);
canvas.drawRect(0, 0, 100, 200, SkPaint());
canvas.drawBitmap(bitmap, 10, 10, nullptr);
});
@@ -81,8 +79,7 @@
};
TEST(OpReorderer, simpleBatching) {
auto dld = TestUtils::createDLD<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
- SkBitmap bitmap;
- bitmap.setInfo(SkImageInfo::MakeUnknown(10, 10));
+ SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
// Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
// Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
@@ -134,14 +131,14 @@
RenderNode* childPtr = child.get();
sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [childPtr](RecordingCanvas& canvas) {
- SkPaint paint;
- paint.setColor(SK_ColorDKGRAY);
- canvas.drawRect(0, 0, 200, 200, paint);
+ SkPaint paint;
+ paint.setColor(SK_ColorDKGRAY);
+ canvas.drawRect(0, 0, 200, 200, paint);
- canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- canvas.translate(40, 40);
- canvas.drawRenderNode(childPtr);
- canvas.restore();
+ canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ canvas.translate(40, 40);
+ canvas.drawRenderNode(childPtr);
+ canvas.restore();
});
TestUtils::syncNodePropertiesAndDisplayList(child);
@@ -151,11 +148,42 @@
nodes.push_back(parent.get());
OpReorderer reorderer;
- reorderer.defer(200, 200, nodes);
+ reorderer.defer(SkRect::MakeWH(200, 200), 200, 200, nodes);
Info info;
reorderer.replayBakedOps<RenderNodeReceiver>(&info);
}
+class ClippedReceiver {
+public:
+ static void onBitmapOp(Info* info, const BitmapOp& op, const BakedOpState& state) {
+ EXPECT_EQ(0, info->index++);
+ EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clippedBounds);
+ EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clipRect);
+ EXPECT_TRUE(state.computedState.transform.isIdentity());
+ }
+ UNSUPPORTED_OP(Info, RectOp)
+ UNSUPPORTED_OP(Info, RenderNodeOp)
+ UNSUPPORTED_OP(Info, SimpleRectsOp)
+ static void startFrame(Info& info) {}
+ static void endFrame(Info& info) {}
+};
+TEST(OpReorderer, clipped) {
+ sp<RenderNode> node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [](RecordingCanvas& canvas) {
+ SkBitmap bitmap = TestUtils::createSkBitmap(200, 200);
+ canvas.drawBitmap(bitmap, 0, 0, nullptr);
+ });
+ TestUtils::syncNodePropertiesAndDisplayList(node);
+ std::vector< sp<RenderNode> > nodes;
+ nodes.push_back(node.get());
+
+ OpReorderer reorderer;
+ reorderer.defer(SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver
+ 200, 200, nodes);
+
+ Info info;
+ reorderer.replayBakedOps<ClippedReceiver>(&info);
+}
+
}
}
diff --git a/libs/hwui/unit_tests/TestUtils.h b/libs/hwui/unit_tests/TestUtils.h
index 257dd28..9b7d1b9 100644
--- a/libs/hwui/unit_tests/TestUtils.h
+++ b/libs/hwui/unit_tests/TestUtils.h
@@ -46,6 +46,12 @@
return snapshot;
}
+ static SkBitmap createSkBitmap(int width, int height) {
+ SkBitmap bitmap;
+ bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
+ return bitmap;
+ }
+
template<class CanvasType>
static std::unique_ptr<DisplayListData> createDLD(int width, int height,
std::function<void(CanvasType& canvas)> canvasCallback) {
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 0abe88b..e6a4c03 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -52,8 +52,8 @@
#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p)))
#if LOG_NDEBUG
-#define ADD_ALLOCATION(size)
-#define RM_ALLOCATION(size)
+#define ADD_ALLOCATION()
+#define RM_ALLOCATION()
#else
#include <utils/Thread.h>
#include <utils/Timers.h>
@@ -65,18 +65,18 @@
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (now > s_nextLog) {
s_nextLog = now + milliseconds_to_nanoseconds(10);
- ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024);
+ ALOGV("Total pages allocated: %zu", s_totalAllocations);
}
}
-static void _addAllocation(size_t size) {
+static void _addAllocation(int count) {
android::AutoMutex lock(s_mutex);
- s_totalAllocations += size;
+ s_totalAllocations += count;
_logUsageLocked();
}
-#define ADD_ALLOCATION(size) _addAllocation(size);
-#define RM_ALLOCATION(size) _addAllocation(-size);
+#define ADD_ALLOCATION(size) _addAllocation(1);
+#define RM_ALLOCATION(size) _addAllocation(-1);
#endif
#define min(x,y) (((x) < (y)) ? (x) : (y))
@@ -134,7 +134,7 @@
Page* next = p->next();
p->~Page();
free(p);
- RM_ALLOCATION(mPageSize);
+ RM_ALLOCATION();
p = next;
}
}
@@ -238,7 +238,7 @@
LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) {
pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page));
- ADD_ALLOCATION(pageSize);
+ ADD_ALLOCATION();
mTotalAllocated += pageSize;
mPageCount++;
void* buf = malloc(pageSize);
diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h
index d90dd82..ade4ab3 100644
--- a/libs/hwui/utils/LinearAllocator.h
+++ b/libs/hwui/utils/LinearAllocator.h
@@ -134,6 +134,47 @@
size_t mDedicatedPageCount;
};
+template <class T>
+class LinearStdAllocator {
+public:
+ typedef T value_type; // needed to implement std::allocator
+ typedef T* pointer; // needed to implement std::allocator
+
+ LinearStdAllocator(LinearAllocator& allocator)
+ : linearAllocator(allocator) {}
+ LinearStdAllocator(const LinearStdAllocator& other)
+ : linearAllocator(other.linearAllocator) {}
+ ~LinearStdAllocator() {}
+
+ // rebind marks that allocators can be rebound to different types
+ template <class U>
+ struct rebind {
+ typedef LinearStdAllocator<U> other;
+ };
+ // enable allocators to be constructed from other templated types
+ template <class U>
+ LinearStdAllocator(const LinearStdAllocator<U>& other)
+ : linearAllocator(other.linearAllocator) {}
+
+ T* allocate(size_t num, const void* = 0) {
+ return (T*)(linearAllocator.alloc(num * sizeof(T)));
+ }
+
+ void deallocate(pointer p, size_t num) {
+ // attempt to rewind, but no guarantees
+ linearAllocator.rewindIfLastAlloc(p, num * sizeof(T));
+ }
+
+ // public so template copy constructor can access
+ LinearAllocator& linearAllocator;
+};
+
+// return that all specializations of LinearStdAllocator are interchangeable
+template <class T1, class T2>
+bool operator== (const LinearStdAllocator<T1>&, const LinearStdAllocator<T2>&) { return true; }
+template <class T1, class T2>
+bool operator!= (const LinearStdAllocator<T1>&, const LinearStdAllocator<T2>&) { return false; }
+
}; // namespace uirenderer
}; // namespace android
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 9d2d171..83e3440 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -469,14 +469,18 @@
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (DEBUG) Log.d(mTag, "onKeyUp: keycode = " + keyCode);
- DirectoryFragment dir = DirectoryFragment.get(getFragmentManager());
- switch (keyCode) {
- case KeyEvent.KEYCODE_MOVE_HOME:
- dir.focusFirstFile();
- return true;
- case KeyEvent.KEYCODE_MOVE_END:
- dir.focusLastFile();
- return true;
+
+ // TODO: Support for RecentsCreateFragment.
+ DirectoryFragment fragment = DirectoryFragment.get(getFragmentManager());
+ if (fragment != null) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_MOVE_HOME:
+ fragment.focusFirstFile();
+ return true;
+ case KeyEvent.KEYCODE_MOVE_END:
+ fragment.focusLastFile();
+ return true;
+ }
}
return super.onKeyUp(keyCode, event);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 94fce59..a3a431f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -205,9 +205,12 @@
return builder.toString();
}
- public static DirectoryFragment get(FragmentManager fm) {
+ public static @Nullable DirectoryFragment get(FragmentManager fm) {
// TODO: deal with multiple directories shown at once
- return (DirectoryFragment) fm.findFragmentById(R.id.container_directory);
+ Fragment fragment = fm.findFragmentById(R.id.container_directory);
+ return fragment instanceof DirectoryFragment
+ ? (DirectoryFragment) fragment
+ : null;
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 6b428f5..aae5269 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -337,7 +337,7 @@
if (mState.action == ACTION_CREATE) {
final FragmentManager fm = getFragmentManager();
- SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
+ SaveFragment.get(fm).prepareForDirectory(cwd);
}
Menus.disableHiddenItems(menu);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index ce98db2..f3b750a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -23,6 +23,7 @@
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -79,6 +80,17 @@
mDisplayName = (EditText) view.findViewById(android.R.id.title);
mDisplayName.addTextChangedListener(mDisplayNameWatcher);
mDisplayName.setText(getArguments().getString(EXTRA_DISPLAY_NAME));
+ mDisplayName.setOnKeyListener(
+ new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER && mSave.isEnabled()) {
+ performSave();
+ return true;
+ }
+ return false;
+ }
+ });
mSave = (Button) view.findViewById(android.R.id.button1);
mSave.setOnClickListener(mSaveListener);
@@ -113,17 +125,22 @@
private View.OnClickListener mSaveListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
- if (mReplaceTarget != null) {
- activity.onSaveRequested(mReplaceTarget);
- } else {
- final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
- final String displayName = mDisplayName.getText().toString();
- activity.onSaveRequested(mimeType, displayName);
- }
+ performSave();
}
+
};
+ private void performSave() {
+ final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
+ if (mReplaceTarget != null) {
+ activity.onSaveRequested(mReplaceTarget);
+ } else {
+ final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
+ final String displayName = mDisplayName.getText().toString();
+ activity.onSaveRequested(mimeType, displayName);
+ }
+ }
+
/**
* Set given document as target for in-place writing if user hits save
* without changing the filename. Can be set to {@code null} if user
@@ -139,7 +156,11 @@
}
}
- public void setSaveEnabled(boolean enabled) {
+ public void prepareForDirectory(DocumentInfo cwd) {
+ setSaveEnabled(cwd != null && cwd.isCreateSupported());
+ }
+
+ private void setSaveEnabled(boolean enabled) {
mSave.setEnabled(enabled);
}
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index d778c98..0b8da83 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -23,6 +23,8 @@
android:layout_width="@dimen/notification_panel_width"
android:layout_height="@dimen/status_bar_header_height"
android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:paddingStart="@dimen/notification_side_padding"
+ android:paddingEnd="@dimen/notification_side_padding"
android:baselineAligned="false"
android:elevation="4dp"
android:background="@drawable/notification_header_bg"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index a64dbbd..bfa13e2 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -102,8 +102,7 @@
android:id="@+id/status_bar_header"
android:layout_width="@dimen/notification_panel_width"
android:layout_height="@dimen/status_bar_header_height"
- android:layout_marginStart="@dimen/notification_side_padding"
- android:layout_marginEnd="@dimen/notification_side_padding" />
+ android:layout_gravity="@integer/notification_panel_layout_gravity" />
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/qs_navbar_scrim"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index dd75dbf..5eca471 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -23,6 +23,8 @@
android:layout_width="@dimen/notification_panel_width"
android:layout_height="@dimen/status_bar_header_height"
android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:paddingStart="@dimen/notification_side_padding"
+ android:paddingEnd="@dimen/notification_side_padding"
android:baselineAligned="false"
android:elevation="4dp"
android:background="@drawable/notification_header_bg"
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 882899e..08f0952e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -971,8 +971,8 @@
// This is a special alarm that will put the system into idle until it goes off.
// The caller has given the time they want this to happen at, however we need
// to pull that earlier if there are existing alarms that have requested to
- // bring us out of idle.
- if (mNextWakeFromIdle != null) {
+ // bring us out of idle at an earlier time.
+ if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) {
a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed;
}
// Add fuzz to make the alarm go off some time before the actual desired time.
@@ -1256,7 +1256,7 @@
pw.print(" Idling until: ");
if (mPendingIdleUntil != null) {
pw.println(mPendingIdleUntil);
- mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf);
+ mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf);
} else {
pw.println("null");
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index cdb00ef..00664b4 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4572,7 +4572,7 @@
// add the task to stack first, mTaskPositioner might need the stack association
addTask(task, toTop, false);
if (mTaskPositioner != null) {
- mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.initialLayout);
+ mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.layout);
} else if (mBounds != null && task.mResizeable) {
task.updateOverrideConfiguration(mBounds);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3cb9887..2a36230 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -97,6 +97,7 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
@@ -352,6 +353,10 @@
private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
+ // The default minimal size that will be used if the activity doesn't specify its minimal size.
+ // It will be calculated when the default display gets added.
+ private int mDefaultMinimalSizeOfResizeableTask = -1;
+
/**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
@@ -432,6 +437,7 @@
throw new IllegalStateException("Default Display does not exist");
}
mActivityDisplays.put(displayId, activityDisplay);
+ calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
}
createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY, true);
@@ -3075,6 +3081,8 @@
return;
}
+ adjustForMinimalTaskDimensions(task, bounds);
+
// If this is a forced resize, let it go through even if the bounds is not changing,
// as we might need a relayout due to surface size change (to/from fullscreen).
final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
@@ -3123,6 +3131,38 @@
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
+ private void adjustForMinimalTaskDimensions(TaskRecord task, Rect bounds) {
+ if (bounds == null) {
+ return;
+ }
+ int minimalSize = task.mMinimalSize == -1 ? mDefaultMinimalSizeOfResizeableTask
+ : task.mMinimalSize;
+ final boolean adjustWidth = minimalSize > bounds.width();
+ final boolean adjustHeight = minimalSize > bounds.height();
+ if (!(adjustWidth || adjustHeight)) {
+ return;
+ }
+ Rect taskBounds = task.mBounds;
+ if (adjustWidth) {
+ if (taskBounds != null && bounds.right == taskBounds.right) {
+ bounds.left = bounds.right - minimalSize;
+ } else {
+ // Either left bounds match, or neither match, or the previous bounds were
+ // fullscreen and we default to keeping left.
+ bounds.right = bounds.left + minimalSize;
+ }
+ }
+ if (adjustHeight) {
+ if (taskBounds != null && bounds.bottom == taskBounds.bottom) {
+ bounds.top = bounds.bottom - minimalSize;
+ } else {
+ // Either top bounds match, or neither match, or the previous bounds were
+ // fullscreen and we default to keeping top.
+ bounds.bottom = bounds.top + minimalSize;
+ }
+ }
+ }
+
ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -4033,6 +4073,7 @@
return;
}
mActivityDisplays.put(displayId, activityDisplay);
+ calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
}
}
if (newDisplay) {
@@ -4040,6 +4081,16 @@
}
}
+ private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
+ if (display.mDisplayId != Display.DEFAULT_DISPLAY) {
+ return;
+ }
+ final float fraction = mService.mContext.getResources().getFraction(com.android.internal.R.
+ fraction.config_displayFractionForDefaultMinimalSizeOfResizeableTask, 1, 1);
+ mDefaultMinimalSizeOfResizeableTask = (int) (fraction * Math.min(
+ display.mDisplayInfo.logicalWidth, display.mDisplayInfo.logicalHeight));
+ }
+
private void handleDisplayRemoved(int displayId) {
synchronized (mService) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 3d45915..4ba1d0d 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -109,22 +109,22 @@
*
* @param task Task for which we want to find bounds that won't collide with other.
* @param tasks Existing tasks with which we don't want to collide.
- * @param initialLayout Optional information from the client about how it would like to be sized
+ * @param layout Optional information from the client about how it would like to be sized
* and positioned.
*/
void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
- @Nullable ActivityInfo.InitialLayout initialLayout) {
+ @Nullable ActivityInfo.Layout layout) {
if (!mDefaultStartBoundsConfigurationSet) {
return;
}
- if (initialLayout == null) {
+ if (layout == null) {
positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
return;
}
- int width = getFinalWidth(initialLayout);
- int height = getFinalHeight(initialLayout);
- int verticalGravity = initialLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
- int horizontalGravity = initialLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ int width = getFinalWidth(layout);
+ int height = getFinalHeight(layout);
+ int verticalGravity = layout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
+ int horizontalGravity = layout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if (verticalGravity == Gravity.TOP) {
if (horizontalGravity == Gravity.RIGHT) {
positionTopRight(task, tasks, width, height);
@@ -140,30 +140,30 @@
} else {
// Some fancy gravity setting that we don't support yet. We just put the activity in the
// center.
- Slog.w(TAG, "Received unsupported gravity: " + initialLayout.gravity
+ Slog.w(TAG, "Received unsupported gravity: " + layout.gravity
+ ", positioning in the center instead.");
positionCenter(task, tasks, width, height);
}
}
- private int getFinalWidth(ActivityInfo.InitialLayout initialLayout) {
+ private int getFinalWidth(ActivityInfo.Layout layout) {
int width = mDefaultFreeformWidth;
- if (initialLayout.width > 0) {
- width = initialLayout.width;
+ if (layout.width > 0) {
+ width = layout.width;
}
- if (initialLayout.widthFraction > 0) {
- width = (int) (mAvailableRect.width() * initialLayout.widthFraction);
+ if (layout.widthFraction > 0) {
+ width = (int) (mAvailableRect.width() * layout.widthFraction);
}
return width;
}
- private int getFinalHeight(ActivityInfo.InitialLayout initialLayout) {
+ private int getFinalHeight(ActivityInfo.Layout layout) {
int height = mDefaultFreeformHeight;
- if (initialLayout.height > 0) {
- height = initialLayout.height;
+ if (layout.height > 0) {
+ height = layout.height;
}
- if (initialLayout.heightFraction > 0) {
- height = (int) (mAvailableRect.height() * initialLayout.heightFraction);
+ if (layout.heightFraction > 0) {
+ height = (int) (mAvailableRect.height() * layout.heightFraction);
}
return height;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 77dbad4..5d5b5fe 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -217,6 +217,9 @@
// The information is persisted and used to determine the appropriate stack to launch the
// task into on restore.
Rect mLastNonFullscreenBounds = null;
+ // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
+ // default minimal size.
+ final int mMinimalSize;
Configuration mOverrideConfig = Configuration.EMPTY;
@@ -235,6 +238,7 @@
mCallingUid = info.applicationInfo.uid;
mCallingPackage = info.packageName;
setIntent(_intent, info);
+ mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
}
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -263,6 +267,7 @@
mTaskToReturnTo = HOME_ACTIVITY_TYPE;
userId = UserHandle.getUserId(info.applicationInfo.uid);
lastTaskDescription = _taskDescription;
+ mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
}
private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
@@ -310,6 +315,8 @@
mCallingPackage = callingPackage;
mResizeable = resizeable;
mPrivileged = privileged;
+ ActivityInfo info = mActivities.get(0).info;
+ mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
}
void touchActiveTime() {
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 06bd583..3c50102 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -73,7 +73,7 @@
*/
public class JobSchedulerService extends com.android.server.SystemService
implements StateChangedListener, JobCompletedListener {
- static final boolean DEBUG = false;
+ public static final boolean DEBUG = false;
/** The number of concurrent jobs we run at one time. */
private static final int MAX_JOB_CONTEXTS_COUNT
= ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
@@ -99,7 +99,7 @@
* Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
* things early.
*/
- static final int MIN_CONNECTIVITY_COUNT = 2;
+ static final int MIN_CONNECTIVITY_COUNT = 1; // Run connectivity jobs as soon as ready.
/**
* Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
* some work early.
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 341410d..80697ed 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -356,6 +356,27 @@
}
@Override
+ public boolean isSameProfileGroup(int userId, int otherUserId) {
+ if (userId == otherUserId) return true;
+ checkManageUsersPermission("check if in the same profile group");
+ synchronized (mPackagesLock) {
+ return isSameProfileGroupLocked(userId, otherUserId);
+ }
+ }
+
+ private boolean isSameProfileGroupLocked(int userId, int otherUserId) {
+ UserInfo userInfo = getUserInfoLocked(userId);
+ if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+ return false;
+ }
+ UserInfo otherUserInfo = getUserInfoLocked(otherUserId);
+ if (otherUserInfo == null || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+ return false;
+ }
+ return userInfo.profileGroupId == otherUserInfo.profileGroupId;
+ }
+
+ @Override
public UserInfo getProfileParent(int userHandle) {
checkManageUsersPermission("get the profile parent");
synchronized (mPackagesLock) {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cc51d20..9f44fea 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -760,26 +760,24 @@
a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
containingFrame, surfaceInsets, taskId);
} else {
+ mTmpFromClipRect.set(containingFrame);
+ // exclude top screen decor (status bar) region from the source clip.
+ mTmpFromClipRect.top = contentInsets.top;
// App window scaling up to become full screen
+ mTmpToClipRect.set(containingFrame);
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// In portrait, we scale the width and clip to the top/left square
scale = thumbWidth / appWidth;
scaledTopDecor = (int) (scale * contentInsets.top);
int unscaledThumbHeight = (int) (thumbHeight / scale);
- mTmpFromClipRect.set(containingFrame);
- mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
- mTmpToClipRect.set(containingFrame);
+ mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
} else {
// In landscape, we scale the height and clip to the top/left square
scale = thumbHeight / (appHeight - contentInsets.top);
scaledTopDecor = (int) (scale * contentInsets.top);
int unscaledThumbWidth = (int) (thumbWidth / scale);
- mTmpFromClipRect.set(containingFrame);
- mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth);
- mTmpToClipRect.set(containingFrame);
+ mTmpFromClipRect.right = mTmpFromClipRect.left + unscaledThumbWidth;
}
- // exclude top screen decor (status bar) region from the source clip.
- mTmpFromClipRect.top = contentInsets.top;
mNextAppTransitionInsets.set(contentInsets);
@@ -821,25 +819,23 @@
}
case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
// App window scaling down from full screen
+ mTmpFromClipRect.set(containingFrame);
+ mTmpToClipRect.set(containingFrame);
+ // exclude top screen decor (status bar) region from the destination clip.
+ mTmpToClipRect.top = contentInsets.top;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// In portrait, we scale the width and clip to the top/left square
scale = thumbWidth / appWidth;
scaledTopDecor = (int) (scale * contentInsets.top);
int unscaledThumbHeight = (int) (thumbHeight / scale);
- mTmpFromClipRect.set(containingFrame);
- mTmpToClipRect.set(containingFrame);
- mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
+ mTmpToClipRect.bottom = mTmpToClipRect.top + unscaledThumbHeight;
} else {
// In landscape, we scale the height and clip to the top/left square
scale = thumbHeight / (appHeight - contentInsets.top);
scaledTopDecor = (int) (scale * contentInsets.top);
int unscaledThumbWidth = (int) (thumbWidth / scale);
- mTmpFromClipRect.set(containingFrame);
- mTmpToClipRect.set(containingFrame);
- mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth);
+ mTmpToClipRect.right = mTmpToClipRect.left + unscaledThumbWidth;
}
- // exclude top screen decor (status bar) region from the destination clip.
- mTmpToClipRect.top = contentInsets.top;
mNextAppTransitionInsets.set(contentInsets);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3c897fa..1913604 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1190,8 +1190,6 @@
mDtDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
- int w = frame.width();
- int h = frame.height();
mWin.mShownPosition.set((int) x, (int) y);
// Now set the alpha... but because our current hardware
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 5c64168..abb8803 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -584,9 +584,8 @@
out.writeInt(1);
mIcon.writeToParcel(out, flags);
}
-
- out.writeBundle(mExtras);
out.writeByte((byte) (mIsEnabled ? 1 : 0));
+ out.writeBundle(mExtras);
}
public static final Creator<PhoneAccount> CREATOR
@@ -628,8 +627,8 @@
} else {
mIcon = null;
}
- mExtras = in.readBundle();
mIsEnabled = in.readByte() == 1;
+ mExtras = in.readBundle();
}
@Override
@@ -645,7 +644,7 @@
sb.append(scheme)
.append(" ");
}
- sb.append(" Extras : ");
+ sb.append(" Extras: ");
sb.append(mExtras);
sb.append("]");
return sb.toString();
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 37ffa06..e11c8d3 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -334,7 +334,8 @@
@Override
public String toString() {
- return "{id=" + mId + ", iccId=" + mIccId + " simSlotIndex=" + mSimSlotIndex
+ String iccIdToPrint = mIccId != null ? mIccId.substring(0, 9) + "XXXXXXXXXXX" : null;
+ return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
+ " displayName=" + mDisplayName + " carrierName=" + mCarrierName
+ " nameSource=" + mNameSource + " iconTint=" + mIconTint
+ " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc