diff options
53 files changed, 1081 insertions, 607 deletions
diff --git a/api/current.txt b/api/current.txt index 9fe6857e5057..3637f148e350 100644 --- a/api/current.txt +++ b/api/current.txt @@ -241,10 +241,8 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 5e1aa419870d..076815eaa9c8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -333,10 +333,8 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 @@ package android.os { 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 e5cfbf3f0109..3f02f17ab349 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -647,20 +647,18 @@ public abstract class Context { /** * 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 @@ public abstract class Context { /** * 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 class Context { 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 @@ public abstract class Context { /** * 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 class Context { 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> + * 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. + * 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 @@ public abstract class Context { * 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 class Context { 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. - * - * <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. + * 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. * + * @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> + * 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. + * 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 @@ public abstract class Context { * 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 @@ public abstract class Context { /** * 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 a121b4d312fd..38537720d119 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -67,7 +67,7 @@ public class ActivityInfo extends ComponentInfo * 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 @@ public class ActivityInfo extends ComponentInfo * 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 @@ public class ActivityInfo extends ComponentInfo * {@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 @@ public class ActivityInfo extends ComponentInfo * 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 @@ public class ActivityInfo extends ComponentInfo * 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 @@ public class ActivityInfo extends ComponentInfo */ @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 @@ public class ActivityInfo extends ComponentInfo * 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 class ActivityInfo extends ComponentInfo */ public int lockTaskLaunchMode; - public InitialLayout initialLayout; + public Layout layout; public ActivityInfo() { } @@ -724,7 +724,7 @@ public class ActivityInfo extends ComponentInfo maxRecents = orig.maxRecents; resizeable = orig.resizeable; lockTaskLaunchMode = orig.lockTaskLaunchMode; - initialLayout = orig.initialLayout; + layout = orig.layout; } /** @@ -771,10 +771,10 @@ public class ActivityInfo extends ComponentInfo } 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 @@ public class ActivityInfo extends ComponentInfo 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 @@ public class ActivityInfo extends ComponentInfo 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 class ActivityInfo extends ComponentInfo 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 1a8602b19c06..bf5441525e39 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -128,7 +128,7 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { targetVers = minVers = val.data; } } - + val = sa.peekValue( com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion); if (val != null) { @@ -1634,7 +1634,7 @@ public class PackageParser { targetVers = val.data; } } - + sa.recycle(); if (minCode != null) { @@ -1663,7 +1663,7 @@ public class PackageParser { mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; return null; } - + if (targetCode != null) { boolean allowedCodename = false; for (String codename : SDK_CODENAMES) { @@ -1730,9 +1730,9 @@ public class PackageParser { 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 @@ public class PackageParser { } 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 @@ public class PackageParser { 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 @@ public class PackageParser { } 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 @@ public class PackageParser { } 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 @@ public class PackageParser { } return proc.intern(); } - + private static String buildProcessName(String pkg, String defProc, CharSequence procSeq, int flags, String[] separateProcesses, String[] outError) { @@ -2226,7 +2226,7 @@ public class PackageParser { } sa.recycle(); - + if (!parseAllMetaData(res, parser, attrs, "<permission-group>", perm, outError)) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; @@ -2265,7 +2265,7 @@ public class PackageParser { 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 @@ public class PackageParser { return null; } } - + if (!parseAllMetaData(res, parser, attrs, "<permission>", perm, outError)) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; @@ -2329,7 +2329,7 @@ public class PackageParser { } sa.recycle(); - + int index = perm.info.name.indexOf('.'); if (index > 0) { index = perm.info.name.indexOf('.', index+1); @@ -2371,9 +2371,9 @@ public class PackageParser { 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 @@ public class PackageParser { } 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 @@ public class PackageParser { outInfo.icon = iconVal; outInfo.nonLocalizedLabel = null; } - + int logoVal = sa.getResourceId(logoRes, 0); if (logoVal != 0) { outInfo.logo = logoVal; @@ -3061,11 +3061,11 @@ public class PackageParser { 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 @@ public class PackageParser { outError[0] = "Heavy-weight applications can not have receivers in main process"; } } - + if (outError[0] != null) { return null; } @@ -3282,8 +3282,8 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { return null; } } - + if (cpname == null) { outError[0] = "<provider> does not include authorities attribute"; return null; @@ -3675,7 +3678,7 @@ public class PackageParser { 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 @@ public class PackageParser { if (str != null) { pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB); } - + sa.recycle(); if (pa != null) { @@ -3746,7 +3749,7 @@ public class PackageParser { if (writePermission == null) { writePermission = permission; } - + boolean havePerm = false; if (readPermission != null) { readPermission = readPermission.intern(); @@ -3769,7 +3772,7 @@ public class PackageParser { return false; } } - + String path = sa.getNonConfigurationString( com.android.internal.R.styleable.AndroidManifestPathPermission_path, 0); if (path != null) { @@ -3852,10 +3855,10 @@ public class PackageParser { 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 @@ public class PackageParser { return null; } } - + int outerDepth = parser.getDepth(); int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT @@ -4010,7 +4013,7 @@ public class PackageParser { } name = name.intern(); - + TypedValue v = sa.peekValue( com.android.internal.R.styleable.AndroidManifestMetaData_resource); if (v != null && v.resourceId != 0) { @@ -4152,7 +4155,7 @@ public class PackageParser { 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 class PackageParser { 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 @@ public class PackageParser { // 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 @@ public class PackageParser { ComponentName componentName; String componentShortName; - + public Component(Package _owner) { owner = _owner; intents = null; @@ -4636,7 +4639,7 @@ public class PackageParser { outInfo.icon = iconVal; outInfo.nonLocalizedLabel = null; } - + int logoVal = args.sa.getResourceId(args.logoRes, 0); if (logoVal != 0) { outInfo.logo = logoVal; @@ -4676,11 +4679,11 @@ public class PackageParser { 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 @@ public class PackageParser { componentName = clone.componentName; componentShortName = clone.componentShortName; } - + public ComponentName getComponentName() { if (componentName != null) { return componentName; @@ -4716,7 +4719,7 @@ public class PackageParser { componentShortName = null; } } - + public final static class Permission extends Component<IntentInfo> { public final PermissionInfo info; public boolean tree; @@ -4731,7 +4734,7 @@ public class PackageParser { super(_owner); info = _info; } - + public void setPackageName(String packageName) { super.setPackageName(packageName); info.packageName = packageName; @@ -4922,7 +4925,7 @@ public class PackageParser { info = _info; info.applicationInfo = args.owner.applicationInfo; } - + public void setPackageName(String packageName) { super.setPackageName(packageName); info.packageName = packageName; @@ -4976,7 +4979,7 @@ public class PackageParser { info = _info; info.applicationInfo = args.owner.applicationInfo; } - + public void setPackageName(String packageName) { super.setPackageName(packageName); info.packageName = packageName; @@ -5019,7 +5022,7 @@ public class PackageParser { info.applicationInfo = args.owner.applicationInfo; syncable = false; } - + public Provider(Provider existingProvider) { super(existingProvider); this.info = existingProvider.info; @@ -5070,7 +5073,7 @@ public class PackageParser { 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 64d6da57718f..f346fe7a721c 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -276,8 +276,8 @@ public class Environment { } /** - * 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 @@ public class Environment { * 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 @@ public class Environment { * <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 @@ public class Environment { * 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 class Environment { 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 class Environment { 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 @@ public class Environment { } /** - * 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 @@ public class Environment { } /** - * 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 @@ public class Environment { } /** - * 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 @@ public class Environment { } /** - * 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 @@ public class Environment { } /** - * 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 4c19ddda19bd..3ade170b9269 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -46,6 +46,7 @@ interface IUserManager { 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 796addc4c3bc..95da438bc869 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -270,13 +270,24 @@ public final class UserHandle implements Parcelable { * 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 d178d20ac14c..1c1575e06f7e 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1093,6 +1093,22 @@ public class UserManager { } /** + * 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 135448511db3..d9ec866ffbab 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -666,7 +666,7 @@ public abstract class Window { 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 @@ public abstract class Window { } } 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 aaa89df1905d..9a5cde67a5ad 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -70,6 +70,7 @@ public class ZygoteInit { 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 @@ public class ZygoteInit { 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 @@ public class ZygoteInit { 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 81d46c3d6988..f12d208f5ebe 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -767,94 +767,94 @@ static const JNINativeMethod gMotionEventMethods[] = { { "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 @@ static const JNINativeMethod gMotionEventMethods[] = { { "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 d37f5b78a4c0..c2a2a26e2fac 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 9d844a880110..322ac4f9dfa7 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 6e956d7f5ba6..f83371996949 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 f4d0b398561f..957cb5027cd8 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 953b98f1c8aa..1239b8754223 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 6f548bcabedc..9fc3924e8efd 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -254,6 +254,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static 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 2337299da145..793d8c0ae75c 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -67,13 +67,8 @@ void DisplayListData::cleanupResources() { regions.clear(); } -#if HWUI_NEW_OPS -size_t DisplayListData::addChild(RenderNodeOp* op) { - mReferenceHolders.push_back(op->renderNode); -#else -size_t DisplayListData::addChild(DrawRenderNodeOp* op) { +size_t DisplayListData::addChild(NodeOpType* 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 8ba9ac357414..80ff96a32fc1 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -58,8 +58,14 @@ class Layer; #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 @@ public: 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 @@ public: } 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 8d0ab0322b5b..a1adb80976d3 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -514,8 +514,12 @@ void DisplayListCanvas::flushTranslate() { } 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 392bb3e5d85f..8f4ae3da8561 100644 --- a/libs/hwui/DisplayListCanvas.h +++ b/libs/hwui/DisplayListCanvas.h @@ -66,8 +66,7 @@ public: 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 1d8be2b47d43..2e02306dcc39 100644 --- a/libs/hwui/OpReorderer.cpp +++ b/libs/hwui/OpReorderer.cpp @@ -212,10 +212,11 @@ OpReorderer::OpReorderer() : 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 @@ void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) { // 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 b99172cb673e..395a1baeebd0 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 @@ public: 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 @@ private: // 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 ed299e56ce7c..8f44ff07f135 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -41,7 +41,7 @@ public: 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 d122a55ef702..28586fa602a7 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -49,8 +49,8 @@ void RenderNode::debugDumpLayers(const char* prefix) { 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 @@ void RenderNode::output(uint32_t level) { 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 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& // 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 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { 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 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { 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 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { } } } +#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 fd42adb13da2..dccbe0b53874 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 @@ void BM_DisplayListData_alloc_theoretical::Run(int iters) { 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 @@ void BM_DisplayListCanvas_record_empty::Run(int iters) { 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 @@ void BM_DisplayListCanvas_record_saverestore::Run(int iters) { MicroBench::DoNotOptimize(&canvas); canvas.restore(); canvas.restore(); - canvas.finishRecording(); + delete canvas.finishRecording(); } StopBenchmarkTiming(); } @@ -91,14 +90,14 @@ void BM_DisplayListCanvas_record_saverestore::Run(int iters) { 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 000000000000..75f57cbd6021 --- /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 e1d8abdd7034..238cf06e77f6 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -266,11 +266,11 @@ void CanvasContext::draw() { 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 @@ void CanvasContext::draw() { 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 @@ void CanvasContext::draw() { 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 e0cbabdc933a..16956e6f1e47 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -141,6 +141,9 @@ private: 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 b3959d169e1d..02cd77ae93db 100644 --- a/libs/hwui/unit_tests/LinearAllocatorTests.cpp +++ b/libs/hwui/unit_tests/LinearAllocatorTests.cpp @@ -106,3 +106,31 @@ TEST(LinearAllocator, rewind) { // 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 fcaea1e36a69..cbfbb23ae25a 100644 --- a/libs/hwui/unit_tests/OpReordererTests.cpp +++ b/libs/hwui/unit_tests/OpReordererTests.cpp @@ -50,9 +50,7 @@ public: }; 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 @@ public: }; 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 @@ TEST(OpReorderer, renderNode) { 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); - - canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); - canvas.translate(40, 40); - canvas.drawRenderNode(childPtr); - canvas.restore(); + 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(); }); TestUtils::syncNodePropertiesAndDisplayList(child); @@ -151,11 +148,42 @@ TEST(OpReorderer, renderNode) { 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 257dd2806d38..9b7d1b9d24ee 100644 --- a/libs/hwui/unit_tests/TestUtils.h +++ b/libs/hwui/unit_tests/TestUtils.h @@ -46,6 +46,12 @@ public: 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 0abe88ba3fbb..e6a4c03156b4 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 @@ static void _logUsageLocked() { 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 @@ LinearAllocator::~LinearAllocator(void) { Page* next = p->next(); p->~Page(); free(p); - RM_ALLOCATION(mPageSize); + RM_ALLOCATION(); p = next; } } @@ -238,7 +238,7 @@ void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { 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 d90dd825ea1d..ade4ab308d86 100644 --- a/libs/hwui/utils/LinearAllocator.h +++ b/libs/hwui/utils/LinearAllocator.h @@ -134,6 +134,47 @@ private: 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 9d2d171b05b6..83e34408db7d 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -469,14 +469,18 @@ abstract class BaseActivity extends Activity { @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 94fce593c573..a3a431f872cd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -205,9 +205,12 @@ public class DirectoryFragment extends Fragment { 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 6b428f58441c..aae526930030 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -337,7 +337,7 @@ public class DocumentsActivity extends BaseActivity { 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 ce98db244270..f3b750a3632c 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.content.Context; 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 @@ public class SaveFragment extends Fragment { 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 @@ public class SaveFragment extends Fragment { 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 class SaveFragment extends Fragment { } } - 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 d778c98dd43e..0b8da8374d77 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 a64dbbdeb2e3..bfa13e2be9b4 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 dd75dbfd47dc..5eca47106a1d 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 882899e4fe96..08f0952e2a0a 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -971,8 +971,8 @@ class AlarmManagerService extends SystemService { // 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 @@ class AlarmManagerService extends SystemService { 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 cdb00ef17823..00664b44f64c 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 @@ final class ActivityStack { // 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 3cb98878ac86..2a36230e0c72 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.provider.Settings.SettingNotFoundException; 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } mActivityDisplays.put(displayId, activityDisplay); + calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); } } if (newDisplay) { @@ -4040,6 +4081,16 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + 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 3d459157edbf..4ba1d0d660c2 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 @@ class LaunchingTaskPositioner { * * @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 @@ class LaunchingTaskPositioner { } 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 77dbad4340ed..5d5b5feda0de 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 @@ final class TaskRecord { // 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 @@ final class TaskRecord { 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 @@ final class TaskRecord { 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 @@ final class TaskRecord { 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 06bd583fc7b3..3c50102157f1 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 @@ import com.android.server.job.controllers.TimeController; */ 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 @@ public class JobSchedulerService extends com.android.server.SystemService * 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 341410d3522d..80697edd50e5 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 @@ public class UserManagerService extends IUserManager.Stub { } @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 cc51d204e98d..9f44fea94d4a 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 @@ public class AppTransition implements Dump { 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 @@ public class AppTransition implements Dump { } 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 3c897fa519b8..191360426e94 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 @@ class WindowStateAnimator { 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 5c6416884aa5..abb88039bb92 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -584,9 +584,8 @@ public final class PhoneAccount implements Parcelable { 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 @@ public final class PhoneAccount implements Parcelable { } else { mIcon = null; } - mExtras = in.readBundle(); mIsEnabled = in.readByte() == 1; + mExtras = in.readBundle(); } @Override @@ -645,7 +644,7 @@ public final class PhoneAccount implements Parcelable { 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 37ffa063c34f..e11c8d3acc43 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -334,7 +334,8 @@ public class SubscriptionInfo implements Parcelable { @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 |