diff options
65 files changed, 1337 insertions, 240 deletions
diff --git a/api/current.txt b/api/current.txt index 035c76b9cbf8..230d22eb6dd7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5790,6 +5790,7 @@ package android.app.admin { method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String); method public void clearUserRestriction(android.content.ComponentName, java.lang.String); method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle); + method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int); method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String); method public void enableSystemApp(android.content.ComponentName, java.lang.String); method public int enableSystemApp(android.content.ComponentName, android.content.Intent); @@ -5982,6 +5983,7 @@ package android.app.admin { field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 + field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 } @@ -13373,6 +13375,7 @@ package android.hardware { field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field"; field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated"; field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation"; + field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof"; field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure"; field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity"; field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity"; @@ -13395,6 +13398,7 @@ package android.hardware { field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2 field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3 + field public static final int TYPE_POSE_6DOF = 28; // 0x1c field public static final int TYPE_PRESSURE = 6; // 0x6 field public static final int TYPE_PROXIMITY = 8; // 0x8 field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc @@ -22938,9 +22942,6 @@ package android.net { method public abstract void onNetworkActive(); } - public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation { - } - public class Credentials { ctor public Credentials(int, int, int); method public int getGid(); @@ -32931,6 +32932,7 @@ package android.renderscript { method public void getVarV(int, android.renderscript.FieldPacker); method protected void invoke(int); method protected void invoke(int, android.renderscript.FieldPacker); + method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions); method public void setTimeZone(java.lang.String); method public void setVar(int, float); method public void setVar(int, double); @@ -35949,6 +35951,8 @@ package android.telephony { public final class CellIdentityGsm implements android.os.Parcelable { method public int describeContents(); + method public int getArfcn(); + method public int getBsic(); method public int getCid(); method public int getLac(); method public int getMcc(); @@ -35961,6 +35965,7 @@ package android.telephony { public final class CellIdentityLte implements android.os.Parcelable { method public int describeContents(); method public int getCi(); + method public int getEarfcn(); method public int getMcc(); method public int getMnc(); method public int getPci(); @@ -35976,6 +35981,7 @@ package android.telephony { method public int getMcc(); method public int getMnc(); method public int getPsc(); + method public int getUarfcn(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR; } diff --git a/api/system-current.txt b/api/system-current.txt index 88fc3d726afd..e4f42c05843f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5927,6 +5927,7 @@ package android.app.admin { method public void clearProfileOwner(android.content.ComponentName); method public void clearUserRestriction(android.content.ComponentName, java.lang.String); method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle); + method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int); method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String); method public void enableSystemApp(android.content.ComponentName, java.lang.String); method public int enableSystemApp(android.content.ComponentName, android.content.Intent); @@ -6131,6 +6132,7 @@ package android.app.admin { field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 + field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 } @@ -13770,6 +13772,7 @@ package android.hardware { field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field"; field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated"; field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation"; + field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof"; field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure"; field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity"; field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity"; @@ -13793,6 +13796,7 @@ package android.hardware { field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2 field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3 + field public static final int TYPE_POSE_6DOF = 28; // 0x1c field public static final int TYPE_PRESSURE = 6; // 0x6 field public static final int TYPE_PROXIMITY = 8; // 0x8 field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc @@ -24541,9 +24545,6 @@ package android.net { method public abstract void onNetworkActive(); } - public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation { - } - public class Credentials { ctor public Credentials(int, int, int); method public int getGid(); @@ -35135,6 +35136,7 @@ package android.renderscript { method public void getVarV(int, android.renderscript.FieldPacker); method protected void invoke(int); method protected void invoke(int, android.renderscript.FieldPacker); + method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions); method public void setTimeZone(java.lang.String); method public void setVar(int, float); method public void setVar(int, double); @@ -38325,6 +38327,8 @@ package android.telephony { public final class CellIdentityGsm implements android.os.Parcelable { method public int describeContents(); + method public int getArfcn(); + method public int getBsic(); method public int getCid(); method public int getLac(); method public int getMcc(); @@ -38337,6 +38341,7 @@ package android.telephony { public final class CellIdentityLte implements android.os.Parcelable { method public int describeContents(); method public int getCi(); + method public int getEarfcn(); method public int getMcc(); method public int getMnc(); method public int getPci(); @@ -38352,6 +38357,7 @@ package android.telephony { method public int getMcc(); method public int getMnc(); method public int getPsc(); + method public int getUarfcn(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR; } diff --git a/api/test-current.txt b/api/test-current.txt index 4ff037bee47e..1a9b469a991e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5792,6 +5792,7 @@ package android.app.admin { method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String); method public void clearUserRestriction(android.content.ComponentName, java.lang.String); method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle); + method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int); method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String); method public void enableSystemApp(android.content.ComponentName, java.lang.String); method public int enableSystemApp(android.content.ComponentName, android.content.Intent); @@ -5984,6 +5985,7 @@ package android.app.admin { field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 + field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 } @@ -13381,6 +13383,7 @@ package android.hardware { field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field"; field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated"; field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation"; + field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof"; field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure"; field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity"; field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity"; @@ -13403,6 +13406,7 @@ package android.hardware { field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2 field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3 + field public static final int TYPE_POSE_6DOF = 28; // 0x1c field public static final int TYPE_PRESSURE = 6; // 0x6 field public static final int TYPE_PROXIMITY = 8; // 0x8 field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc @@ -22946,9 +22950,6 @@ package android.net { method public abstract void onNetworkActive(); } - public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation { - } - public class Credentials { ctor public Credentials(int, int, int); method public int getGid(); @@ -32945,6 +32946,7 @@ package android.renderscript { method public void getVarV(int, android.renderscript.FieldPacker); method protected void invoke(int); method protected void invoke(int, android.renderscript.FieldPacker); + method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions); method public void setTimeZone(java.lang.String); method public void setVar(int, float); method public void setVar(int, double); @@ -35963,6 +35965,8 @@ package android.telephony { public final class CellIdentityGsm implements android.os.Parcelable { method public int describeContents(); + method public int getArfcn(); + method public int getBsic(); method public int getCid(); method public int getLac(); method public int getMcc(); @@ -35975,6 +35979,7 @@ package android.telephony { public final class CellIdentityLte implements android.os.Parcelable { method public int describeContents(); method public int getCi(); + method public int getEarfcn(); method public int getMcc(); method public int getMnc(); method public int getPci(); @@ -35990,6 +35995,7 @@ package android.telephony { method public int getMcc(); method public int getMnc(); method public int getPsc(); + method public int getUarfcn(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR; } diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl index 560e22a3be1d..fa1123423e35 100644 --- a/core/java/android/app/ITaskStackListener.aidl +++ b/core/java/android/app/ITaskStackListener.aidl @@ -23,4 +23,11 @@ oneway interface ITaskStackListener { /** Called whenever an Activity is moved to the pinned stack from another stack. */ void onActivityPinned(); + + /** + * Called whenever IActivityManager.startActivity is called on an activity that is already + * running in the pinned stack and the activity is not actually started, but the task is either + * brought to the front or a new Intent is delivered to it. + */ + void onPinnedActivityRestartAttempt(); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c78174f2a594..7007afee5890 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -4125,21 +4125,21 @@ public class DevicePolicyManager { } /** - * Flag used by {@link createAndManageUser} to skip setup wizard after creating a new user. - * @hide + * Flag used by {@link #createAndManageUser} to skip setup wizard after creating a new user. */ public static final int SKIP_SETUP_WIZARD = 0x0001; /** - * Called by a device owner to create a user with the specified name and the caller as profile - * owner. The UserHandle returned by this method should not be persisted as user handles are - * recycled as users are removed and created. If you need to persist an identifier for this - * user, use {@link UserManager#getSerialNumberForUser}. The new user will not be started in the - * background. + * Called by a device owner to create a user with the specified name and a given component of + * the calling package as profile owner. The UserHandle returned by this method should not be + * persisted as user handles are recycled as users are removed and created. If you need to + * persist an identifier for this user, use {@link UserManager#getSerialNumberForUser}. The new + * user will not be started in the background. * - * <p> admin is the {@link DeviceAdminReceiver} which is the device owner, and will become the - * profile owner and will be registered as an active admin on the new user. The profile owner - * package will be installed on the new user. + * <p>admin is the {@link DeviceAdminReceiver} which is the device owner. profileOwner is also + * a DeviceAdminReceiver in the same package as admin, and will become the profile owner and + * will be registered as an active admin on the new user. The profile owner package will be + * installed on the new user. * * <p>If the adminExtras are not null, they will be stored on the device until the user is * started for the first time. Then the extras will be passed to the admin when @@ -4147,18 +4147,21 @@ public class DevicePolicyManager { * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param name The user's name. + * @param profileOwner Which {@link DeviceAdminReceiver} will be profile owner. Has to be in the + * same package as admin, otherwise no user is created and an IllegalArgumentException is + * thrown. * @param adminExtras Extras that will be passed to onEnable of the admin receiver on the new * user. - * @param flags {@link SKIP_SETUP_WIZARD} is supported. + * @param flags {@link #SKIP_SETUP_WIZARD} is supported. * @see UserHandle * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the * user could not be created. - * @hide */ public UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name, - @Nullable PersistableBundle adminExtras, int flags) { + @NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras, + int flags) { try { - return mService.createAndManageUser(admin, name, adminExtras, flags); + return mService.createAndManageUser(admin, name, profileOwner, adminExtras, flags); } catch (RemoteException re) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index e08b80b27145..e97bdf2bd4e9 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -179,7 +179,7 @@ interface IDevicePolicyManager { UserHandle createUser(in ComponentName who, in String name); UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras); - UserHandle createAndManageUser(in ComponentName who, in String name, in PersistableBundle adminExtras, in int flags); + UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags); boolean removeUser(in ComponentName who, in UserHandle userHandle); boolean switchUser(in ComponentName who, in UserHandle userHandle); diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 2bbc54f7e4e6..999d8260cad3 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -155,7 +155,7 @@ public class TrustManager { } /** - * @return whether {@userId} has enabled and configured trust agents. Ignores short-term + * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}. */ @RequiresPermission(android.Manifest.permission.TRUST_LISTENER) diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 01689087043f..654396bc5dfa 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -176,7 +176,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * Value for {@link #flags}: this is set if this application has been - * install as an update to a built-in system application. + * installed as an update to a built-in system application. */ public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7; diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java index 6935174f58d6..e5efd568abc7 100644 --- a/core/java/android/hardware/Sensor.java +++ b/core/java/android/hardware/Sensor.java @@ -551,6 +551,29 @@ public final class Sensor { */ public static final String STRING_TYPE_DEVICE_ORIENTATION = "android.sensor.device_orientation"; + /** + * A constant describing a pose sensor with 6 degrees of freedom. + * + * Similar to {@link #TYPE_ROTATION_VECTOR}, with additional delta + * translation from an arbitrary reference point. + * + * Can use camera, depth sensor etc to compute output value. + * + * This is expected to be a high power sensor and expected only to be + * used when the screen is on. + * + * Expected to be more accurate than the rotation vector alone. + * + */ + public static final int TYPE_POSE_6DOF = 28; + + /** + * A constant string describing a pose sensor with 6 degrees of freedom. + * + * @see #TYPE_POSE_6DOF + */ + public static final String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof"; + /** * A constant describing all sensor types. */ @@ -637,6 +660,7 @@ public final class Sensor { 1, // SENSOR_TYPE_PICK_UP_GESTURE 1, // SENSOR_TYPE_WRIST_TILT_GESTURE 1, // SENSOR_TYPE_DEVICE_ORIENTATION + 16, // SENSOR_TYPE_POSE_6DOF }; /** diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java index 9937b2cb2d26..416c74c37f2f 100644 --- a/core/java/android/hardware/SensorEvent.java +++ b/core/java/android/hardware/SensorEvent.java @@ -497,6 +497,40 @@ public class SensorEvent { * <li> 3: device is rotated 90 degrees clockwise from default orientation (X axis * is vertical and points down) * </ul> + * + * <h4>{@link android.hardware.Sensor#TYPE_POSE_6DOF + * Sensor.TYPE_POSE_6DOF}:</h4> + * + * A TYPE_POSE_6DOF event consists of a rotation expressed as a quaternion and a translation + * expressed in SI units. The event also contains a delta rotation and translation that show + * how the device?s pose has changed since the previous sequence numbered pose. + * The event uses the cannonical Android Sensor axes. + * + * + * <ul> + * <li> values[0]: x*sin(θ/2) </li> + * <li> values[1]: y*sin(θ/2) </li> + * <li> values[2]: z*sin(θ/2) </li> + * <li> values[3]: cos(θ/2) </li> + * + * + * <li> values[4]: Translation along x axis from an arbitrary origin. </li> + * li> values[5]: Translation along y axis from an arbitrary origin. </li> + * <li> values[6]: Translation along z axis from an arbitrary origin. </li> + * + * <li> values[7]: Delta quaternion rotation x*sin(θ/2) </li> + * <li> values[8]: Delta quaternion rotation y*sin(θ/2) </li> + * <li> values[9]: Delta quaternion rotation z*sin(θ/2) </li> + * <li> values[10]: Delta quaternion rotation cos(θ/2) </li> + * + * <li> values[11]: Delta translation along x axis. </li> + * <li> values[12]: Delta translation along y axis. </li> + * <li> values[13]: Delta translation along z axis. </li> + * + * <li> values[14]: Sequence number </li> + * + * </ul> + * */ public final float[] values; diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 5584cde2aa6c..08c0c094a473 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3051,12 +3051,13 @@ public class ConnectivityManager { */ public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) @IntDef(flag = false, value = { RESTRICT_BACKGROUND_STATUS_DISABLED, RESTRICT_BACKGROUND_STATUS_WHITELISTED, RESTRICT_BACKGROUND_STATUS_ENABLED, }) - @Retention(RetentionPolicy.SOURCE) public @interface RestrictBackgroundStatus { } diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index e34560b80bda..787202eded02 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -965,10 +965,10 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable (spanStart != queryEnd && spanEnd != queryStart)) && (Object.class == kind || kind.isInstance(mSpans[i]))) { int spanPriority = mSpanFlags[i] & SPAN_PRIORITY; - if(sort) { - ret[count] = (T) mSpans[i]; - priority[count] = spanPriority; - insertionOrder[count] = mSpanOrder[i]; + int target = count; + if (sort) { + priority[target] = spanPriority; + insertionOrder[target] = mSpanOrder[i]; } else if (spanPriority != 0) { //insertion sort for elements with priority int j = 0; @@ -977,8 +977,9 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (spanPriority > p) break; } System.arraycopy(ret, j, ret, j + 1, count - j); - ret[j] = (T) mSpans[i]; + target = j; } + ret[target] = (T) mSpans[i]; count++; } if (count < ret.length && (i & 1) != 0) { diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 923139406088..c5ed39af5fb8 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -76,6 +76,11 @@ oneway interface IWindow { void dispatchDragEvent(in DragEvent event); /** + * Pointer icon events + */ + void updatePointerIcon(float x, float y); + + /** * System chrome visibility changes */ void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6c3f308f6846..dc50e17e1050 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5795,8 +5795,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <p>A View should call this if it maintains some notion of which part * of its content is interesting. For example, a text editing view * should call this when its cursor moves. + * <p>The Rectangle passed into this method should be in the View's content coordinate space. + * It should not be affected by which part of the View is currently visible or its scroll + * position. * - * @param rectangle The rectangle. + * @param rectangle The rectangle in the View's content coordinate space * @return Whether any parent scrolled. */ public boolean requestRectangleOnScreen(Rect rectangle) { @@ -5810,11 +5813,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <p>A View should call this if it maintains some notion of which part * of its content is interesting. For example, a text editing view * should call this when its cursor moves. - * + * <p>The Rectangle passed into this method should be in the View's content coordinate space. + * It should not be affected by which part of the View is currently visible or its scroll + * position. * <p>When <code>immediate</code> is set to true, scrolling will not be * animated. * - * @param rectangle The rectangle. + * @param rectangle The rectangle in the View's content coordinate space * @param immediate True to forbid animated scrolling, false otherwise * @return Whether any parent scrolled. */ @@ -5834,24 +5839,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, rectangle.set((int) position.left, (int) position.top, (int) position.right, (int) position.bottom); - scrolled |= parent.requestChildRectangleOnScreen(child, - rectangle, immediate); - - if (!child.hasIdentityMatrix()) { - child.getMatrix().mapRect(position); - } - - position.offset(child.mLeft, child.mTop); + scrolled |= parent.requestChildRectangleOnScreen(child, rectangle, immediate); if (!(parent instanceof View)) { break; } - View parentView = (View) parent; - - position.offset(-parentView.getScrollX(), -parentView.getScrollY()); + // move it from child's content coordinate space to parent's content coordinate space + position.offset(child.mLeft - child.getScrollX(), child.mTop -child.getScrollY()); - child = parentView; + child = (View) parent; parent = child.getParent(); } diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index e9b123b5b9be..1962be86ffb1 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -266,14 +266,14 @@ public interface ViewParent { * intercept touch events. */ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept); - + /** * Called when a child of this group wants a particular rectangle to be * positioned onto the screen. {@link ViewGroup}s overriding this can trust * that: * <ul> * <li>child will be a direct child of this group</li> - * <li>rectangle will be in the child's coordinates</li> + * <li>rectangle will be in the child's content coordinates</li> * </ul> * * <p>{@link ViewGroup}s overriding this should uphold the contract:</p> diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 131ad4c05825..5d41477d3c0f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3278,6 +3278,7 @@ public final class ViewRootImpl implements ViewParent, private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24; private final static int MSG_DISPATCH_WINDOW_SHOWN = 25; private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; + private final static int MSG_UPDATE_POINTER_ICON = 27; final class ViewRootHandler extends Handler { @Override @@ -3327,6 +3328,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_SYNTHESIZE_INPUT_EVENT"; case MSG_DISPATCH_WINDOW_SHOWN: return "MSG_DISPATCH_WINDOW_SHOWN"; + case MSG_UPDATE_POINTER_ICON: + return "MSG_UPDATE_POINTER_ICON"; } return super.getMessageName(message); } @@ -3568,6 +3571,10 @@ public final class ViewRootImpl implements ViewParent, IResultReceiver receiver = (IResultReceiver) msg.obj; handleRequestKeyboardShortcuts(receiver); } break; + case MSG_UPDATE_POINTER_ICON: { + MotionEvent event = (MotionEvent) msg.obj; + resetPointerIcon(event); + } break; } } } @@ -4309,31 +4316,11 @@ public final class ViewRootImpl implements ViewParent, mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; } - final float x = event.getX(); - final float y = event.getY(); - if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT - && x >= 0 && x < mView.getWidth() && y >= 0 && y < mView.getHeight()) { - PointerIcon pointerIcon = mView.getPointerIcon(event, x, y); - int pointerShape = (pointerIcon != null) ? - pointerIcon.getStyle() : PointerIcon.STYLE_DEFAULT; - - final InputDevice inputDevice = event.getDevice(); - if (inputDevice != null) { - if (mPointerIconShape != pointerShape) { - mPointerIconShape = pointerShape; - if (mPointerIconShape != PointerIcon.STYLE_CUSTOM) { - mCustomPointerIcon = null; - inputDevice.setPointerShape(pointerShape); - } - } - if (mPointerIconShape == PointerIcon.STYLE_CUSTOM && - !pointerIcon.equals(mCustomPointerIcon)) { - mCustomPointerIcon = pointerIcon; - inputDevice.setCustomPointerIcon(mCustomPointerIcon); - } + if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { + if (!updatePointerIcon(event) && + event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) { + mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; } - } else if (event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) { - mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; } } @@ -4371,6 +4358,38 @@ public final class ViewRootImpl implements ViewParent, } } + private void resetPointerIcon(MotionEvent event) { + mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; + updatePointerIcon(event); + } + + private boolean updatePointerIcon(MotionEvent event) { + final float x = event.getX(); + final float y = event.getY(); + if (x < 0 || x >= mView.getWidth() || y < 0 || y >= mView.getHeight()) { + Slog.e(mTag, "updatePointerIcon called with position out of bounds"); + return false; + } + final PointerIcon pointerIcon = mView.getPointerIcon(event, x, y); + final int pointerShape = (pointerIcon != null) ? + pointerIcon.getStyle() : PointerIcon.STYLE_DEFAULT; + + if (mPointerIconShape != pointerShape) { + mPointerIconShape = pointerShape; + if (mPointerIconShape != PointerIcon.STYLE_CUSTOM) { + mCustomPointerIcon = null; + InputManager.getInstance().setPointerIconShape(pointerShape); + return true; + } + } + if (mPointerIconShape == PointerIcon.STYLE_CUSTOM && + !pointerIcon.equals(mCustomPointerIcon)) { + mCustomPointerIcon = pointerIcon; + InputManager.getInstance().setCustomPointerIcon(mCustomPointerIcon); + } + return true; + } + /** * Performs synthesis of new input events from unhandled input events. */ @@ -6389,6 +6408,16 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } + public void updatePointerIcon(float x, float y) { + final int what = MSG_UPDATE_POINTER_ICON; + mHandler.removeMessages(what); + final long now = SystemClock.uptimeMillis(); + final MotionEvent event = MotionEvent.obtain( + 0, now, MotionEvent.ACTION_HOVER_MOVE, x, y, 0); + Message msg = mHandler.obtainMessage(what, event); + mHandler.sendMessage(msg); + } + public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue, int localChanges) { SystemUiVisibilityInfo args = new SystemUiVisibilityInfo(); @@ -6700,16 +6729,19 @@ public final class ViewRootImpl implements ViewParent, @Override public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { + if (rectangle == null) { + return scrollToRectOrFocus(null, immediate); + } + rectangle.offset(child.getLeft() - child.getScrollX(), + child.getTop() - child.getScrollY()); final boolean scrolled = scrollToRectOrFocus(rectangle, immediate); - if (rectangle != null) { - mTempRect.set(rectangle); - mTempRect.offset(0, -mCurScrollY); - mTempRect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop); - try { - mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect); - } catch (RemoteException re) { - /* ignore */ - } + mTempRect.set(rectangle); + mTempRect.offset(0, -mCurScrollY); + mTempRect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop); + try { + mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect); + } catch (RemoteException re) { + /* ignore */ } return scrolled; } @@ -6967,6 +6999,14 @@ public final class ViewRootImpl implements ViewParent, } @Override + public void updatePointerIcon(float x, float y) { + final ViewRootImpl viewAncestor = mViewAncestor.get(); + if (viewAncestor != null) { + viewAncestor.updatePointerIcon(x, y); + } + } + + @Override public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue, int localChanges) { final ViewRootImpl viewAncestor = mViewAncestor.get(); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 4355eb3bcd69..67473c6a4521 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1082,6 +1082,20 @@ public class Editor { return true; } + private void startDragAndDrop() { + final int start = mTextView.getSelectionStart(); + final int end = mTextView.getSelectionEnd(); + CharSequence selectedText = mTextView.getTransformedText(start, end); + ClipData data = ClipData.newPlainText(null, selectedText); + DragLocalState localState = new DragLocalState(mTextView, start, end); + mTextView.startDragAndDrop(data, getTextThumbnailBuilder(selectedText), localState, + View.DRAG_FLAG_GLOBAL); + stopTextActionMode(); + if (hasSelectionController()) { + getSelectionController().resetTouchOffsets(); + } + } + public boolean performLongClick(boolean handled) { // Long press in empty space moves cursor and starts the insertion action mode. if (!handled && !isPositionOnText(mLastDownPositionX, mLastDownPositionY) && @@ -1097,15 +1111,7 @@ public class Editor { if (!handled && mTextActionMode != null) { if (touchPositionIsInSelection()) { - // Start a drag - final int start = mTextView.getSelectionStart(); - final int end = mTextView.getSelectionEnd(); - CharSequence selectedText = mTextView.getTransformedText(start, end); - ClipData data = ClipData.newPlainText(null, selectedText); - DragLocalState localState = new DragLocalState(mTextView, start, end); - mTextView.startDrag(data, getTextThumbnailBuilder(selectedText), localState, - View.DRAG_FLAG_GLOBAL); - stopTextActionMode(); + startDragAndDrop(); } else { stopTextActionMode(); selectCurrentWordAndStartDrag(); @@ -4925,6 +4931,14 @@ public class Editor { if (isMouse && !isDragAcceleratorActive()) { final int offset = mTextView.getOffsetForPosition(eventX, eventY); + if (mTextView.hasSelection() + && (!mHaventMovedEnoughToStartDrag || mStartOffset != offset) + && offset >= mTextView.getSelectionStart() + && offset <= mTextView.getSelectionEnd()) { + startDragAndDrop(); + break; + } + if (mStartOffset != offset) { // Start character based drag accelerator. if (mTextActionMode != null) { diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index aa4b564c3800..7dfc15d9195e 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -86,6 +86,10 @@ public class BaseIWindow extends IWindow.Stub { } @Override + public void updatePointerIcon(float x, float y) { + } + + @Override public void dispatchSystemUiVisibilityChanged(int seq, int globalUi, int localValue, int localChanges) { mSeq = seq; diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 5a08887a7380..cf7978c12bfe 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -214,7 +214,7 @@ <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm), visual voicemail code for T-Mobile: 122 --> - <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327|654)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" /> + <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:567|578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" /> <!-- Vietnam --> <shortcode country="vn" free="5001" /> diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index c0453f8ac991..eb0075b6b0b7 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -53,6 +53,7 @@ <uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" /> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.INJECT_EVENTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java index afd0bc4e5295..00df87d19b94 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java @@ -37,6 +37,7 @@ import static android.support.test.espresso.action.ViewActions.typeTextIntoFocus import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; import com.android.frameworks.coretests.R; @@ -145,6 +146,40 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< } @SmallTest + public void testDragAndDrop() throws Exception { + final String text = "abc def ghi."; + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); + onView(withId(R.id.textview)).perform( + mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1)); + + onView(withId(R.id.textview)).perform( + mouseDragOnText(text.indexOf("e"), text.length())); + + onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); + onView(withId(R.id.textview)).check(hasSelection("")); + assertNoSelectionHandles(); + onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); + } + + @SmallTest + public void testDragAndDrop_longClick() throws Exception { + final String text = "abc def ghi."; + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); + onView(withId(R.id.textview)).perform( + mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1)); + + onView(withId(R.id.textview)).perform( + mouseLongClickAndDragOnText(text.indexOf("e"), text.length())); + + onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); + onView(withId(R.id.textview)).check(hasSelection("")); + assertNoSelectionHandles(); + onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); + } + + @SmallTest public void testSelectTextByLongClick() throws Exception { final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index edbfef9c82bc..5dae4a878bf4 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -159,6 +159,22 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV } @SmallTest + public void testDragAndDrop() throws Exception { + final String text = "abc def ghi."; + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e"))); + + onView(withId(R.id.textview)).perform( + longPressAndDragOnText(text.indexOf("e"), text.length())); + + onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); + onView(withId(R.id.textview)).check(hasSelection("")); + assertNoSelectionHandles(); + onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); + } + + @SmallTest public void testDoubleTapToSelect() throws Exception { final String helloWorld = "Hello SuetYi!"; onView(withId(R.id.textview)).perform(click()); diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml index 46267a218a3f..15b2a978a04a 100644 --- a/packages/SettingsLib/res/values/attrs.xml +++ b/packages/SettingsLib/res/values/attrs.xml @@ -18,4 +18,9 @@ <declare-styleable name="RestrictedPreference"> <attr name="userRestriction" format="string"/> </declare-styleable> -</resources>
\ No newline at end of file + <declare-styleable name="WifiEncryptionState"> + <attr name="state_encrypted" format="boolean" /> + </declare-styleable> + <attr name="wifi_signal" format="reference" /> + +</resources> diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml index 9a1d6a404b08..811751cd00a5 100644 --- a/packages/SettingsLib/res/values/dimens.xml +++ b/packages/SettingsLib/res/values/dimens.xml @@ -35,4 +35,7 @@ <!-- Lock icon for preferences locked by admin --> <dimen name="restricted_lock_icon_size">16dp</dimen> <dimen name="restricted_lock_icon_padding">4dp</dimen> + + <dimen name="wifi_preference_badge_padding">8dip</dimen> + </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java new file mode 100644 index 000000000000..284827b57929 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.settingslib.wifi; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.StateListDrawable; +import android.net.wifi.WifiConfiguration; +import android.os.Looper; +import android.os.UserHandle; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceViewHolder; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.widget.TextView; + +import com.android.settingslib.R; + +public class AccessPointPreference extends Preference { + + private static final int[] STATE_SECURED = { + R.attr.state_encrypted + }; + private static final int[] STATE_NONE = {}; + + private static int[] wifi_signal_attributes = { R.attr.wifi_signal }; + + private final StateListDrawable mWifiSld; + private final int mBadgePadding; + private final UserBadgeCache mBadgeCache; + + private TextView mTitleView; + private boolean mForSavedNetworks = false; + private AccessPoint mAccessPoint; + private Drawable mBadge; + private int mLevel; + private CharSequence mContentDescription; + + static final int[] WIFI_CONNECTION_STRENGTH = { + R.string.accessibility_wifi_one_bar, + R.string.accessibility_wifi_two_bars, + R.string.accessibility_wifi_three_bars, + R.string.accessibility_wifi_signal_full + }; + + // Used for dummy pref. + public AccessPointPreference(Context context, AttributeSet attrs) { + super(context, attrs); + mWifiSld = null; + mBadgePadding = 0; + mBadgeCache = null; + } + + public AccessPointPreference(AccessPoint accessPoint, Context context, UserBadgeCache cache, + boolean forSavedNetworks) { + super(context); + mBadgeCache = cache; + mAccessPoint = accessPoint; + mForSavedNetworks = forSavedNetworks; + mAccessPoint.setTag(this); + mLevel = -1; + + mWifiSld = (StateListDrawable) context.getTheme() + .obtainStyledAttributes(wifi_signal_attributes).getDrawable(0); + + // Distance from the end of the title at which this AP's user badge should sit. + mBadgePadding = context.getResources() + .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding); + refresh(); + } + + public AccessPoint getAccessPoint() { + return mAccessPoint; + } + + @Override + public void onBindViewHolder(final PreferenceViewHolder view) { + super.onBindViewHolder(view); + if (mAccessPoint == null) { + // Used for dummy pref. + return; + } + Drawable drawable = getIcon(); + if (drawable != null) { + drawable.setLevel(mLevel); + } + + mTitleView = (TextView) view.findViewById(com.android.internal.R.id.title); + if (mTitleView != null) { + // Attach to the end of the title view + mTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mBadge, null); + mTitleView.setCompoundDrawablePadding(mBadgePadding); + } + view.itemView.setContentDescription(mContentDescription); + } + + protected void updateIcon(int level, Context context) { + if (level == -1) { + setIcon(null); + } else { + if (getIcon() == null) { + // To avoid a drawing race condition, we first set the state (SECURE/NONE) and then + // set the icon (drawable) to that state's drawable. + // If sld is null then we are indexing and therefore do not have access to + // (nor need to display) the drawable. + if (mWifiSld != null) { + mWifiSld.setState((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) + ? STATE_SECURED + : STATE_NONE); + Drawable drawable = mWifiSld.getCurrent(); + if (!mForSavedNetworks) { + setIcon(drawable); + } else { + setIcon(null); + } + } + } + } + } + + protected void updateBadge(Context context) { + WifiConfiguration config = mAccessPoint.getConfig(); + if (config != null) { + // Fetch badge (may be null) + // Get the badge using a cache since the PM will ask the UserManager for the list + // of profiles every time otherwise. + mBadge = mBadgeCache.getUserBadge(config.creatorUid); + } + } + + /** + * Updates the title and summary; may indirectly call notifyChanged(). + */ + public void refresh() { + if (mForSavedNetworks) { + setTitle(mAccessPoint.getConfigName()); + } else { + setTitle(mAccessPoint.getSsid()); + } + + final Context context = getContext(); + int level = mAccessPoint.getLevel(); + if (level != mLevel) { + mLevel = level; + updateIcon(mLevel, context); + notifyChanged(); + } + updateBadge(context); + + setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary() + : mAccessPoint.getSettingsSummary()); + + mContentDescription = getTitle(); + if (getSummary() != null) { + mContentDescription = TextUtils.concat(mContentDescription, ",", getSummary()); + } + if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) { + mContentDescription = TextUtils.concat(mContentDescription, ",", + getContext().getString(WIFI_CONNECTION_STRENGTH[level])); + } + } + + @Override + protected void notifyChanged() { + if (Looper.getMainLooper() != Looper.myLooper()) { + // Let our BG thread callbacks call setTitle/setSummary. + postNotifyChanged(); + } else { + super.notifyChanged(); + } + } + + public void onLevelChanged() { + postNotifyChanged(); + } + + private void postNotifyChanged() { + if (mTitleView != null) { + mTitleView.post(mNotifyChanged); + } // Otherwise we haven't been bound yet, and don't need to update. + } + + private final Runnable mNotifyChanged = new Runnable() { + @Override + public void run() { + notifyChanged(); + } + }; + + public static class UserBadgeCache { + private final SparseArray<Drawable> mBadges = new SparseArray<>(); + private final PackageManager mPm; + + public UserBadgeCache(PackageManager pm) { + mPm = pm; + } + + private Drawable getUserBadge(int userId) { + int index = mBadges.indexOfKey(userId); + if (index < 0) { + Drawable badge = mPm.getUserBadgeForDensity(new UserHandle(userId), 0 /* dpi */); + mBadges.put(userId, badge); + return badge; + } + return mBadges.valueAt(index); + } + } +} diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..426238c05f4b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_data_saver.xml @@ -0,0 +1,28 @@ +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData=" + M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z + m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z + m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z + m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml new file mode 100644 index 000000000000..0713548fcd4d --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml @@ -0,0 +1,28 @@ +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#4DFFFFFF" + android:pathData=" + M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z + m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z + m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z + m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml index b953ff2c976a..9ef743d9e15b 100644 --- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml +++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml @@ -39,13 +39,13 @@ android:paddingStart="@dimen/car_lockscreen_disclaimer_text_padding_start" android:paddingEnd="@dimen/car_lockscreen_disclaimer_text_padding_end" android:paddingTop="@dimen/car_lockscreen_disclaimer_text_padding_top" /> - <com.android.systemui.statusbar.UserGridView + <com.android.systemui.statusbar.car.UserGridView android:id="@+id/user_grid" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="@dimen/car_lockscreen_user_grid_view_padding_top" android:stretchMode="columnWidth"> - </com.android.systemui.statusbar.UserGridView> + </com.android.systemui.statusbar.car.UserGridView> </LinearLayout> </FrameLayout> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 814e7eae0474..faf36eca176f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1333,4 +1333,13 @@ <!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] --> <string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string> + <!-- Label for quick settings tile for data saver [CHAR LIMIT=30] --> + <string name="data_saver">Data Saver</string> + + <!-- Accessibility description for data saver being on [CHAR LIMIT=NONE] --> + <string name="accessibility_data_saver_on">Data Saver is on</string> + + <!-- Accessibility description for data saver being off [CHAR LIMIT=NONE] --> + <string name="accessibility_data_saver_off">Data Saver is off</string> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 6e22dde542d0..543a2f32b090 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -73,7 +73,7 @@ public class TileAdapter extends BaseAdapter { mCurrentTiles = tileSpecs; final TileGroup group = new TileGroup("com.android.settings", mContext); String possible = mContext.getString(R.string.quick_settings_tiles_default) - + ",user,hotspot,inversion"; + + ",user,hotspot,inversion,saver"; String[] possibleTiles = possible.split(","); for (int i = 0; i < possibleTiles.length; i++) { final String spec = possibleTiles[i]; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java new file mode 100644 index 000000000000..1aeb0fe6c9dd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs.tiles; + +import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.systemui.R; +import com.android.systemui.qs.QSTile; +import com.android.systemui.statusbar.policy.DataSaverController; + +public class DataSaverTile extends QSTile<QSTile.BooleanState> implements + DataSaverController.Listener{ + + private final DataSaverController mDataSaverController; + + public DataSaverTile(Host host) { + super(host); + mDataSaverController = host.getNetworkController().getDataSaverController(); + } + + @Override + protected BooleanState newTileState() { + return new BooleanState(); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + mDataSaverController.addListener(this); + } else { + mDataSaverController.remListener(this); + } + } + + @Override + protected void handleClick() { + mState.value = !mDataSaverController.isDataSaverEnabled(); + mDataSaverController.setDataSaverEnabled(mState.value); + refreshState(mState.value); + } + + @Override + protected void handleUpdateState(BooleanState state, Object arg) { + state.value = arg instanceof Boolean ? (Boolean) arg + : mDataSaverController.isDataSaverEnabled(); + state.label = mContext.getString(R.string.data_saver); + state.contentDescription = mContext.getString(state.value ? + R.string.accessibility_data_saver_on : R.string.accessibility_data_saver_off); + state.icon = ResourceIcon.get(state.value ? R.drawable.ic_data_saver + : R.drawable.ic_data_saver_off); + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.QS_DATA_SAVER; + } + + @Override + public void onDataSaverChanged(boolean isDataSaving) { + refreshState(isDataSaving); + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java index 881aa6ac688f..5cd540bcb789 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java @@ -26,10 +26,6 @@ import com.android.systemui.tuner.TunerService; */ public class RecentsDebugFlags implements TunerService.Tunable { - private static final String KEY_FAST_TOGGLE = "overview_fast_toggle_via_button"; - private static final String KEY_FAST_TOGGLE_INDICATOR = "overview_fast_toggle_indicator"; - private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging"; - public static class Static { // Enables debug drawing for the transition thumbnail public static final boolean EnableTransitionThumbnailDebugMode = false; @@ -39,18 +35,23 @@ public class RecentsDebugFlags implements TunerService.Tunable { public static final boolean DisableBackgroundCache = false; // Enables the task affiliations public static final boolean EnableAffiliatedTaskGroups = true; - // Enables the simulated task affiliations - public static final boolean EnableSimulatedTaskGroups = false; - // Defines the number of mock task affiliations per group - public static final int TaskAffiliationsGroupCount = 12; + // Enables us to create mock recents tasks - public static final boolean EnableSystemServicesProxy = false; + public static final boolean EnableMockTasks = false; // Defines the number of mock recents packages to create - public static final int SystemServicesProxyMockPackageCount = 3; + public static final int MockTasksPackageCount = 3; // Defines the number of mock recents tasks to create - public static final int SystemServicesProxyMockTaskCount = 100; + public static final int MockTaskCount = 100; + // Enables the simulated task affiliations + public static final boolean EnableMockTaskGroups = false; + // Defines the number of mock task affiliations per group + public static final int MockTaskGroupsTaskCount = 12; } + private static final String KEY_FAST_TOGGLE = "overview_fast_toggle_via_button"; + private static final String KEY_FAST_TOGGLE_INDICATOR = "overview_fast_toggle_indicator"; + private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging"; + private boolean mFastToggleRecents; private boolean mFastToggleIndicator; private boolean mInitialStatePaging; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index f8cbf656dfa0..5f11bee9249a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -108,6 +108,10 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements public void onActivityPinned() { } + @Override + public void onPinnedActivityRestartAttempt() { + } + /** Preloads the next task */ public void run() { RecentsConfiguration config = Recents.getConfiguration(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 3f52ae8d7ed1..87cfcff1066e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -151,7 +151,7 @@ public class SystemServicesProxy { // Resolve the assist intent mAssistComponent = mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()); - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { // Create a dummy icon mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); mDummyIcon.eraseColor(0xFF999999); @@ -164,20 +164,20 @@ public class SystemServicesProxy { if (mAm == null) return null; // If we are mocking, then create some recent tasks - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { ArrayList<ActivityManager.RecentTaskInfo> tasks = new ArrayList<ActivityManager.RecentTaskInfo>(); - int count = Math.min(numLatestTasks, RecentsDebugFlags.Static.SystemServicesProxyMockTaskCount); + int count = Math.min(numLatestTasks, RecentsDebugFlags.Static.MockTaskCount); for (int i = 0; i < count; i++) { // Create a dummy component name - int packageIndex = i % RecentsDebugFlags.Static.SystemServicesProxyMockPackageCount; + int packageIndex = i % RecentsDebugFlags.Static.MockTasksPackageCount; ComponentName cn = new ComponentName("com.android.test" + packageIndex, "com.android.test" + i + ".Activity"); String description = "" + i + " - " + Long.toString(Math.abs(new Random().nextLong()), 36); // Create the recent task info ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); - rti.id = rti.persistentId = i; + rti.id = rti.persistentId = rti.affiliatedTaskId = i; rti.baseIntent = new Intent(); rti.baseIntent.setComponent(cn); rti.description = description; @@ -418,7 +418,7 @@ public class SystemServicesProxy { if (mAm == null) return null; // If we are mocking, then just return a dummy thumbnail - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight, Bitmap.Config.ARGB_8888); thumbnail.eraseColor(0xff333333); @@ -484,7 +484,7 @@ public class SystemServicesProxy { /** Moves a task to the front with the specified activity options. */ public void moveTaskToFront(int taskId, ActivityOptions opts) { if (mAm == null) return; - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return; + if (RecentsDebugFlags.Static.EnableMockTasks) return; if (opts != null) { mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME, @@ -497,7 +497,7 @@ public class SystemServicesProxy { /** Removes the task */ public void removeTask(final int taskId) { if (mAm == null) return; - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return; + if (RecentsDebugFlags.Static.EnableMockTasks) return; // Remove the task. BackgroundThread.getHandler().post(new Runnable() { @@ -528,7 +528,7 @@ public class SystemServicesProxy { */ public ActivityInfo getActivityInfo(ComponentName cn, int userId) { if (mIpm == null) return null; - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return new ActivityInfo(); + if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo(); try { return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId); @@ -545,7 +545,7 @@ public class SystemServicesProxy { */ public ActivityInfo getActivityInfo(ComponentName cn) { if (mPm == null) return null; - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return new ActivityInfo(); + if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo(); try { return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA); @@ -562,7 +562,7 @@ public class SystemServicesProxy { if (mPm == null) return null; // If we are mocking, then return a mock label - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { return "Recent Task: " + userId; } @@ -576,7 +576,7 @@ public class SystemServicesProxy { if (mPm == null) return null; // If we are mocking, then return a mock label - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { return "Recent Task App: " + userId; } @@ -588,6 +588,11 @@ public class SystemServicesProxy { * description joins the app and activity labels. */ public String getBadgedContentDescription(ActivityInfo info, int userId, Resources res) { + // If we are mocking, then return a mock label + if (RecentsDebugFlags.Static.EnableMockTasks) { + return "Recent Task Content Description: " + userId; + } + String activityLabel = info.loadLabel(mPm).toString(); String applicationLabel = info.applicationInfo.loadLabel(mPm).toString(); String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId); @@ -604,7 +609,7 @@ public class SystemServicesProxy { if (mPm == null) return null; // If we are mocking, then return a mock label - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { return new ColorDrawable(0xFF666666); } @@ -620,7 +625,7 @@ public class SystemServicesProxy { if (mPm == null) return null; // If we are mocking, then return a mock label - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { return new ColorDrawable(0xFF666666); } @@ -635,7 +640,7 @@ public class SystemServicesProxy { int userId, Resources res) { // If we are mocking, then return a mock label - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) { + if (RecentsDebugFlags.Static.EnableMockTasks) { return new ColorDrawable(0xFF666666); } @@ -673,7 +678,7 @@ public class SystemServicesProxy { /** Returns the package name of the home activity. */ public String getHomeActivityPackageName() { if (mPm == null) return null; - if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return null; + if (RecentsDebugFlags.Static.EnableMockTasks) return null; ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index 9cdd703852fe..d15828a96554 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -22,6 +22,7 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.os.Debug; import android.os.UserHandle; import android.os.UserManager; import android.util.ArraySet; @@ -31,6 +32,7 @@ import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.RecentsDebugFlags; import com.android.systemui.recents.misc.SystemServicesProxy; import java.util.ArrayList; @@ -130,6 +132,9 @@ public class RecentsTaskLoadPlan { R.string.accessibility_recents_item_will_be_dismissed); long lastStackActiveTime = Prefs.getLong(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, 0); + if (RecentsDebugFlags.Static.EnableMockTasks) { + lastStackActiveTime = 0; + } long newLastStackActiveTime = -1; int taskCount = mRawTasks.size(); for (int i = 0; i < taskCount; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index de1daa8ea988..66eeac60d801 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -776,7 +776,7 @@ public class TaskStack { * Temporary: This method will simulate affiliation groups by */ public void createAffiliatedGroupings(Context context) { - if (RecentsDebugFlags.Static.EnableSimulatedTaskGroups) { + if (RecentsDebugFlags.Static.EnableMockTaskGroups) { ArrayMap<Task.TaskKey, Task> taskMap = new ArrayMap<>(); // Sort all tasks by increasing firstActiveTime of the task ArrayList<Task> tasks = mStackTaskList.getTasks(); @@ -792,7 +792,7 @@ public class TaskStack { String prevPackage = ""; int prevAffiliation = -1; Random r = new Random(); - int groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount; + int groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount; for (int i = 0; i < taskCount; i++) { Task t = tasks.get(i); String packageName = t.key.getComponent().getPackageName(); @@ -807,7 +807,7 @@ public class TaskStack { addGroup(group); prevAffiliation = affiliation; prevPackage = packageName; - groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount; + groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount; } group.addTask(t); taskMap.put(t.key, t); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java new file mode 100644 index 000000000000..9f2b00a50e60 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.recents.views; + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +/** + * This is an optimized FrameLayout whose layout is completely directed by its parent, and as a + * result, does not propagate <code>requestLayout()</code> up the view hierarchy. Instead, it will + * relayout its children with the last known layout bounds when a layout is requested from a child + * view. + */ +public class FixedSizeFrameLayout extends FrameLayout { + + private final Rect mLayoutBounds = new Rect(); + + public FixedSizeFrameLayout(Context context) { + super(context); + } + + public FixedSizeFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + measureContents(MeasureSpec.getSize(widthMeasureSpec), + MeasureSpec.getSize(heightMeasureSpec)); + } + + @Override + protected final void onLayout(boolean changed, int left, int top, int right, int bottom) { + mLayoutBounds.set(left, top, right, bottom); + layoutContents(mLayoutBounds, changed); + } + + @Override + public final void requestLayout() { + // The base ViewGroup constructor attempts to call requestLayout() before this class's + // members are initialized so we should just propagate in that case + if (mLayoutBounds == null || mLayoutBounds.isEmpty()) { + super.requestLayout(); + } else { + // If we are already laid out, then just reuse the same bounds to layout the children + // (but not itself) + // TODO: Investigate whether we should coalesce these to the next frame if needed + measureContents(getMeasuredWidth(), getMeasuredHeight()); + layoutContents(mLayoutBounds, false); + } + } + + /** + * Measures the contents of this fixed layout. + */ + protected void measureContents(int width, int height) { + super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); + } + + /** + * Lays out the contents of this fixed layout. + */ + protected void layoutContents(Rect bounds, boolean changed) { + super.onLayout(changed, bounds.left, bounds.top, bounds.right, bounds.bottom); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java index 3f5d0a846299..f5ab01f5bf5b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java @@ -23,13 +23,13 @@ import android.util.AttributeSet; import android.widget.ImageView; /** - * This is an optimized ImageView that does not trigger a requestLayout() or invalidate() when - * setting the image to Null. + * This is an optimized ImageView that does not trigger a <code>requestLayout()</code> or + * <code>invalidate()</code> when setting the image to <code>null</code>. */ public class FixedSizeImageView extends ImageView { - boolean mAllowRelayout = true; - boolean mAllowInvalidate = true; + private boolean mAllowRelayout = true; + private boolean mAllowInvalidate = true; public FixedSizeImageView(Context context) { this(context, null); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index fe9c68eaf239..ccc858100d48 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -1375,11 +1375,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Report that this tasks's data is no longer being used Recents.getTaskLoader().unloadTaskData(task); - // Detach the view from the hierarchy - detachViewFromParent(tv); - // Update the task views list after removing the task view - updateTaskViewsList(); - // Reset the view properties and view state tv.resetViewProperties(); tv.setFocusedState(false, false /* requestViewFocus */); @@ -1387,19 +1382,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (mScreenPinningEnabled) { tv.hideActionButton(false /* fadeOut */, 0 /* duration */, false /* scaleDown */, null); } + + // Detach the view from the hierarchy + detachViewFromParent(tv); + // Update the task views list after removing the task view + updateTaskViewsList(); } @Override public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) { - // Rebind the task and request that this task's data be filled into the TaskView - tv.onTaskBound(task); - - // Load the task data - Recents.getTaskLoader().loadTaskData(task); - - // If the doze trigger has already fired, then update the state for this task view - tv.setNoUserInteractionState(); - // Find the index where this task should be placed in the stack int taskIndex = mStack.indexOfStackTask(task); int insertIndex = findTaskViewInsertIndex(task, taskIndex); @@ -1413,6 +1404,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Update the task views list after adding the new task view updateTaskViewsList(); + // Rebind the task and request that this task's data be filled into the TaskView + tv.onTaskBound(task); + + // Load the task data + Recents.getTaskLoader().loadTaskData(task); + + // If the doze trigger has already fired, then update the state for this task view + tv.setNoUserInteractionState(); + // Set the new state for this view, including the callbacks and view clipping tv.setCallbacks(this); tv.setTouchEnabled(true); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 32bebb36d17f..5a4064a686bf 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -17,7 +17,6 @@ package com.android.systemui.recents.views; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; @@ -40,7 +39,6 @@ import android.view.ViewOutlineProvider; import android.view.animation.AccelerateInterpolator; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; -import android.widget.FrameLayout; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; @@ -62,8 +60,13 @@ import java.util.ArrayList; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; -/* A task view */ -public class TaskView extends FrameLayout implements Task.TaskCallbacks, +/** + * A {@link TaskView} represents a fixed view of a task. Because the TaskView's layout is directed + * solely by the {@link TaskStackView}, we make it a fixed size layout which allows relayouts down + * the view hierarchy, but not upwards from any of its children (the TaskView will relayout itself + * with the previous bounds if any child requests layout). + */ +public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks, TaskStackAnimationHelper.Callbacks, View.OnClickListener, View.OnLongClickListener { /** The TaskView callbacks */ @@ -219,33 +222,20 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, return super.onInterceptTouchEvent(ev); } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = MeasureSpec.getSize(widthMeasureSpec); - int height = MeasureSpec.getSize(heightMeasureSpec); + @Override + protected void measureContents(int width, int height) { int widthWithoutPadding = width - mPaddingLeft - mPaddingRight; int heightWithoutPadding = height - mPaddingTop - mPaddingBottom; - int taskBarHeight = getResources().getDimensionPixelSize(R.dimen.recents_task_bar_height); // Measure the content mContent.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY)); - // Measure the bar view, and action button - mHeaderView.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(taskBarHeight, MeasureSpec.EXACTLY)); - mActionButtonView.measure( - MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.AT_MOST)); - // Measure the thumbnail to be square - mThumbnailView.measure( - MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY)); + // Optimization: Prevent overdraw of the thumbnail under the header view mThumbnailView.updateClipToTaskBar(mHeaderView); setMeasuredDimension(width, height); - invalidateOutline(); } void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index 827ee4088d57..cb108daab3ac 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -245,11 +245,7 @@ public class TaskViewHeader extends FrameLayout * to match the frame changes. */ public void onTaskViewSizeChanged(int width, int height) { - // Return early if the bounds have not changed - if (mTaskViewRect.width() == width && mTaskViewRect.height() == height) { - return; - } - + // TODO: Optimize this path mTaskViewRect.set(0, 0, width, height); boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE; boolean isFreeformTask = (mTask != null) && mTask.isFreeformTask(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java index 39d06049edaf..de96d9da8e85 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java @@ -190,7 +190,6 @@ public class TaskViewThumbnail extends View { if (!mInvisible) { updateThumbnailPaintFilter(); } - invalidate(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index f6f1f94017aa..e20936b7dec4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -24,11 +24,13 @@ import android.os.Handler; import android.os.Looper; import android.view.View; import android.view.ViewGroup.LayoutParams; +import android.view.ViewStub; import android.view.WindowManager; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.PhoneStatusBar; /** @@ -41,6 +43,7 @@ public class CarStatusBar extends PhoneStatusBar { private CarNavigationBarView mCarNavigationBar; private CarNavigationBarController mController; + private FullscreenUserSwitcher mFullscreenUserSwitcher; @Override public void start() { @@ -102,6 +105,10 @@ public class CarStatusBar extends PhoneStatusBar { } @Override + public void onPinnedActivityRestartAttempt() { + } + + @Override public void onTaskStackChanged() { mHandler.removeCallbacks(this); mHandler.post(this); @@ -121,4 +128,34 @@ public class CarStatusBar extends PhoneStatusBar { } } } + + @Override + protected void createUserSwitcher() { + if (mUserSwitcherController.useFullscreenUserSwitcher()) { + mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController, + (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub)); + } else { + super.createUserSwitcher(); + } + } + + @Override + public void userSwitched(int newUserId) { + super.userSwitched(newUserId); + if (mFullscreenUserSwitcher != null) { + mFullscreenUserSwitcher.onUserSwitched(newUserId); + } + } + + @Override + public void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) { + super.updateKeyguardState(goingToFullShade, fromShadeLocked); + if (mFullscreenUserSwitcher != null) { + if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) { + mFullscreenUserSwitcher.show(); + } else { + mFullscreenUserSwitcher.hide(); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java index fd8852e6d34b..3025092f70d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java @@ -14,7 +14,7 @@ * limitations under the License */ -package com.android.systemui.statusbar.policy; +package com.android.systemui.statusbar.car; import android.content.Context; import android.provider.Settings; @@ -22,8 +22,8 @@ import android.view.View; import android.view.ViewStub; import com.android.systemui.R; -import com.android.systemui.statusbar.UserGridView; import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.statusbar.policy.UserSwitcherController; /** * Manages the fullscreen user switcher. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java index 2f8bc2d4cb0f..28f4e05a85ce 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java @@ -14,7 +14,7 @@ * limitations under the License */ -package com.android.systemui.statusbar; +package com.android.systemui.statusbar.car; import android.content.Context; import android.content.DialogInterface; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java index d0c14f1fd52b..ed6d94004ad8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java @@ -1108,6 +1108,10 @@ class NavigationBarApps extends LinearLayout @Override public void onActivityPinned() { } + + @Override + public void onPinnedActivityRestartAttempt() { + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 3a41832e3f4c..e2a61849c9c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -141,7 +141,6 @@ import com.android.systemui.statusbar.policy.BluetoothControllerImpl; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.CastControllerImpl; import com.android.systemui.statusbar.policy.FlashlightController; -import com.android.systemui.statusbar.policy.FullscreenUserSwitcher; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.HotspotControllerImpl; import com.android.systemui.statusbar.policy.KeyguardMonitor; @@ -285,7 +284,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, protected KeyguardMonitor mKeyguardMonitor; BrightnessMirrorController mBrightnessMirrorController; AccessibilityController mAccessibilityController; - FullscreenUserSwitcher mFullscreenUserSwitcher; FingerprintUnlockController mFingerprintUnlockController; int mNaturalBarHeight = -1; @@ -854,16 +852,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (UserManager.get(mContext).isUserSwitcherEnabled()) { mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor, mHandler, this); - if (mUserSwitcherController.useFullscreenUserSwitcher()) { - mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController, - (ViewStub) mStatusBarWindow.findViewById( - R.id.fullscreen_user_switcher_stub)); - } else { - // Fullscreen user switcher does not show keyguard. Hence no KeyguardUserSwitcher. - mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, - (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), - mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController); - } + createUserSwitcher(); } // Set up the quick settings tile panel @@ -934,6 +923,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mStatusBarView; } + protected void createUserSwitcher() { + mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, + (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), + mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController); + } + protected void inflateStatusBarWindow(Context context) { mStatusBarWindow = (StatusBarWindowView) View.inflate(context, R.layout.super_status_bar, null); @@ -3093,9 +3088,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, setControllerUsers(); clearCurrentMediaNotification(); updateMediaMetaData(true); - if (mFullscreenUserSwitcher != null) { - mFullscreenUserSwitcher.onUserSwitched(newUserId); - } } private void setControllerUsers() { @@ -3720,7 +3712,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, .isSecure(mCurrentUserId)); } - private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) { + protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) { if (mState == StatusBarState.KEYGUARD) { mKeyguardIndicationController.setVisible(true); mNotificationPanel.resetViews(); @@ -3744,13 +3736,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScrimController.setKeyguardShowing(false); mIconPolicy.setKeyguardShowing(false); } - if (mFullscreenUserSwitcher != null) { - if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) { - mFullscreenUserSwitcher.show(); - } else { - mFullscreenUserSwitcher.hide(); - } - } + mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade); updateDozingState(); updatePublicMode(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index 7e278560ba55..9c2159be1b98 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -38,6 +38,7 @@ import com.android.systemui.qs.tiles.BluetoothTile; import com.android.systemui.qs.tiles.CastTile; import com.android.systemui.qs.tiles.CellularTile; import com.android.systemui.qs.tiles.ColorInversionTile; +import com.android.systemui.qs.tiles.DataSaverTile; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.FlashlightTile; import com.android.systemui.qs.tiles.HotspotTile; @@ -346,6 +347,7 @@ public final class QSTileHost implements QSTile.Host, Tunable { else if (tileSpec.equals("hotspot")) return new HotspotTile(this); else if (tileSpec.equals("user")) return new UserTile(this); else if (tileSpec.equals("battery")) return new BatteryTile(this); + else if (tileSpec.equals("saver")) return new DataSaverTile(this); else if (tileSpec.equals(ColorMatrixTile.COLOR_MATRIX_SPEC)) return new ColorMatrixTile(this); // Intent tiles. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java new file mode 100644 index 000000000000..186e8b51d58c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.statusbar.policy; + +import android.content.Context; +import android.net.INetworkPolicyListener; +import android.net.NetworkPolicyManager; +import android.os.Handler; +import android.os.RemoteException; + +import java.util.ArrayList; + +public class DataSaverController { + + private final Handler mHandler = new Handler(); + private final ArrayList<Listener> mListeners = new ArrayList<>(); + private final NetworkPolicyManager mPolicyManager; + + public DataSaverController(Context context) { + mPolicyManager = NetworkPolicyManager.from(context); + } + + private void handleRestrictBackgroundChanged(boolean isDataSaving) { + final int N = mListeners.size(); + for (int i = 0; i < N; i++) { + mListeners.get(i).onDataSaverChanged(isDataSaving); + } + } + + public void addListener(Listener listener) { + mListeners.add(listener); + if (mListeners.size() == 1) { + mPolicyManager.registerListener(mPolicyListener); + } + listener.onDataSaverChanged(isDataSaverEnabled()); + } + + public void remListener(Listener listener) { + mListeners.remove(listener); + if (mListeners.size() == 0) { + mPolicyManager.unregisterListener(mPolicyListener); + } + } + + public boolean isDataSaverEnabled() { + return mPolicyManager.getRestrictBackground(); + } + + public void setDataSaverEnabled(boolean enabled) { + mPolicyManager.setRestrictBackground(enabled); + } + + private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { + @Override + public void onUidRulesChanged(int i, int i1) throws RemoteException { + } + + @Override + public void onMeteredIfacesChanged(String[] strings) throws RemoteException { + } + + @Override + public void onRestrictBackgroundChanged(final boolean isDataSaving) throws RemoteException { + mHandler.post(new Runnable() { + @Override + public void run() { + handleRestrictBackgroundChanged(isDataSaving); + } + }); + } + }; + + public interface Listener { + void onDataSaverChanged(boolean isDataSaving); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index b2bcde3db937..755a5b3f511d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -33,6 +33,7 @@ public interface NetworkController { void onUserSwitched(int newUserId); AccessPointController getAccessPointController(); DataUsageController getMobileDataController(); + DataSaverController getDataSaverController(); public interface SignalCallback { void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 3385c820a64f..dbb0295e7029 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -78,6 +78,7 @@ public class NetworkControllerImpl extends BroadcastReceiver private final SubscriptionManager mSubscriptionManager; private final boolean mHasMobileDataFeature; private final SubscriptionDefaults mSubDefaults; + private final DataSaverController mDataSaverController; private Config mConfig; // Subcontrollers. @@ -156,6 +157,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mConfig = config; mReceiverHandler = new Handler(bgLooper); mCallbackHandler = callbackHandler; + mDataSaverController = new DataSaverController(context); mSubscriptionManager = subManager; mSubDefaults = defaultsHandler; @@ -189,6 +191,10 @@ public class NetworkControllerImpl extends BroadcastReceiver updateAirplaneMode(true /* force callback */); } + public DataSaverController getDataSaverController() { + return mDataSaverController; + } + private void registerListeners() { for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { mobileSignalController.registerListener(); diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index bed1e9e39cce..b237400db484 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -29,7 +29,6 @@ import android.content.res.Resources; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Log; import java.util.ArrayList; @@ -38,7 +37,6 @@ import java.util.List; import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; -import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; /** @@ -314,6 +312,10 @@ public class PipManager { // Post the message back to the UI thread. mHandler.post(mOnActivityPinnedRunnable); } + + @Override + public void onPinnedActivityRestartAttempt() { + } } /** diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 88e55ddb4fda..697777c718a3 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -339,5 +339,8 @@ message MetricsEvent { // Logged when the user calls an emergency contact. ACTION_CALL_EMERGENCY_CONTACT = 283; + + // QS Tile for Data Saver. + QS_DATA_SAVER = 284; } } diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java index a4876b92fadf..a71ba6364ac8 100644 --- a/rs/java/android/renderscript/Allocation.java +++ b/rs/java/android/renderscript/Allocation.java @@ -16,14 +16,16 @@ package android.renderscript; +import java.nio.ByteBuffer; import java.util.HashMap; + import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.view.Surface; -import android.util.Log; import android.graphics.Canvas; import android.os.Trace; +import android.util.Log; +import android.view.Surface; /** * <p> This class provides the primary method through which data is passed to @@ -78,6 +80,8 @@ public class Allocation extends BaseObj { OnBufferAvailableListener mBufferNotifier; private Surface mGetSurfaceSurface = null; + private ByteBuffer mByteBuffer = null; + private long mByteBufferStride = -1; private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) { final Class c = d.getClass(); @@ -2050,6 +2054,59 @@ public class Allocation extends BaseObj { } /** + * @hide + * Gets or creates a ByteBuffer that contains the raw data of the current Allocation. + * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer + * would contain the up-to-date data as READ ONLY. + * For a 2D or 3D Allocation, the raw data maybe padded so that each row of + * the Allocation has certain alignment. The size of each row including padding, + * called stride, can be queried using the {@link #getStride()} method. + * + * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors. + * + * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation. + */ + public ByteBuffer getByteBuffer() { + // Create a new ByteBuffer if it is not initialized or using IO_INPUT. + if (mType.hasFaces()) { + throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer()."); + } + if (mType.getYuv() == android.graphics.ImageFormat.NV21 || + mType.getYuv() == android.graphics.ImageFormat.YV12 || + mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) { + throw new RSInvalidStateException("YUV format is not supported for getByteBuffer()."); + } + if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) { + int xBytesSize = mType.getX() * mType.getElement().getBytesSize(); + long[] stride = new long[1]; + mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ()); + mByteBufferStride = stride[0]; + } + if ((mUsage & USAGE_IO_INPUT) != 0) { + return mByteBuffer.asReadOnlyBuffer(); + } + return mByteBuffer; + } + + /** + * @hide + * Gets the stride of the Allocation. + * For a 2D or 3D Allocation, the raw data maybe padded so that each row of + * the Allocation has certain alignment. The size of each row including such + * padding is called stride. + * + * @return the stride. For 1D Allocation, the stride will be the number of + * bytes of this Allocation. For 2D and 3D Allocations, the stride + * will be the stride in X dimension measuring in bytes. + */ + public long getStride() { + if (mByteBufferStride == -1) { + getByteBuffer(); + } + return mByteBufferStride; + } + + /** * Returns the handle to a raw buffer that is being managed by the screen * compositor. This operation is only valid for Allocations with {@link * #USAGE_IO_INPUT}. diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 3668ddd62303..4788223b4357 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -18,17 +18,18 @@ package android.renderscript; import java.io.File; import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.concurrent.locks.ReentrantReadWriteLock; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.SurfaceTexture; -import android.util.Log; -import android.view.Surface; import android.os.SystemProperties; import android.os.Trace; -import java.util.ArrayList; +import android.util.Log; +import android.view.Surface; // TODO: Clean up the whitespace that separates methods in this class. @@ -489,6 +490,13 @@ public class RenderScript { validate(); rsnAllocationSyncAll(mContext, alloc, src); } + + native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, long[] stride, int xBytesSize, int dimY, int dimZ); + synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, long[] stride, int xBytesSize, int dimY, int dimZ) { + validate(); + return rsnAllocationGetByteBuffer(mContext, alloc, stride, xBytesSize, dimY, dimZ); + } + native Surface rsnAllocationGetSurface(long con, long alloc); synchronized Surface nAllocationGetSurface(long alloc) { validate(); diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java index 84f980dc24cd..2b0678046e32 100644 --- a/rs/java/android/renderscript/Script.java +++ b/rs/java/android/renderscript/Script.java @@ -315,7 +315,6 @@ public class Script extends BaseObj { /** * Only intended for use by generated reflected code. (General reduction) * - * @hide */ protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) { mRS.validate(); diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp index 39540709b16e..398d89b20b1e 100644 --- a/rs/jni/android_renderscript_RenderScript.cpp +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -2752,7 +2752,43 @@ nSystemGetPointerSize(JNIEnv *_env, jobject _this) { return (jint)sizeof(void*); } +static jobject +nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc, + jlongArray strideArr, jint xBytesSize, + jint dimY, jint dimZ) { + if (kLogApi) { + ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc); + } + + jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr); + if (jStridePtr == nullptr) { + ALOGE("Failed to get Java array elements: strideArr"); + return 0; + } + size_t strideIn = xBytesSize; + void* ptr = nullptr; + if (alloc != 0) { + ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0, + RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, + &strideIn, sizeof(size_t)); + } + + jobject byteBuffer = nullptr; + if (ptr != nullptr) { + size_t bufferSize = strideIn; + jStridePtr[0] = strideIn; + if (dimY > 0) { + bufferSize *= dimY; + } + if (dimZ > 0) { + bufferSize *= dimZ; + } + byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize); + } + _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0); + return byteBuffer; +} // --------------------------------------------------------------------------- @@ -2909,6 +2945,7 @@ static const JNINativeMethod methods[] = { {"rsnMeshGetIndices", "(JJ[J[II)V", (void*)nMeshGetIndices }, {"rsnSystemGetPointerSize", "()I", (void*)nSystemGetPointerSize }, +{"rsnAllocationGetByteBuffer", "(JJ[JIII)Ljava/nio/ByteBuffer;", (void*)nAllocationGetByteBuffer }, }; static int registerFuncs(JNIEnv *_env) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1434e5e1b759..b8327c14a984 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -203,7 +203,6 @@ import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; -import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.Xml; import android.view.Display; @@ -1473,6 +1472,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int LOG_STACK_STATE = 62; static final int VR_MODE_CHANGE_MSG = 63; static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64; + static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -2056,6 +2056,20 @@ public final class ActivityManagerService extends ActivityManagerNative } break; } + case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: { + synchronized (ActivityManagerService.this) { + for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) { + try { + // Make a one-way callback to the listener + mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt(); + } catch (RemoteException e){ + // Handled by the RemoteCallbackList + } + } + mTaskStackListeners.finishBroadcast(); + } + break; + } case NOTIFY_CLEARTEXT_NETWORK_MSG: { final int uid = msg.arg1; final byte[] firstPacket = (byte[]) msg.obj; @@ -11284,6 +11298,16 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget(); } + /** + * Notifies all listeners when an attempt was made to start an an activity that is already + * running in the pinned stack and the activity was not actually started, but the task is + * either brought to the front or a new Intent is delivered to it. + */ + void notifyPinnedActivityRestartAttemptLocked() { + mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG); + mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget(); + } + @Override public void notifyCleartextNetwork(int uid, byte[] firstPacket) { mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 23dc0f6746ed..7b7359f5ee1e 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -504,18 +504,45 @@ class ActivityStarter { err = startActivityUnchecked( r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); + postStartActivityUncheckedProcessing(r, err, stack.mStackId); + return err; + } - if (err < 0) { - // If someone asked to have the keyguard dismissed on the next - // activity start, but we are not actually doing an activity - // switch... just dismiss the keyguard now, because we - // probably want to see whatever is behind it. + void postStartActivityUncheckedProcessing( + ActivityRecord r, int result, int prevFocusedStackId) { + + if (result < START_SUCCESS) { + // If someone asked to have the keyguard dismissed on the next activity start, + // but we are not actually doing an activity switch... just dismiss the keyguard now, + // because we probably want to see whatever is behind it. mSupervisor.notifyActivityDrawnForKeyguard(); - } else { - launchRecentsAppIfNeeded(stack); + return; } - return err; + int startedActivityStackId = INVALID_STACK_ID; + if (r.task != null && r.task.stack != null) { + startedActivityStackId = r.task.stack.mStackId; + } else if (mTargetStack != null) { + startedActivityStackId = mTargetStack.mStackId; + } + + if (startedActivityStackId == DOCKED_STACK_ID && prevFocusedStackId == HOME_STACK_ID) { + // We launch an activity while being in home stack, which means either launcher or + // recents into docked stack. We don't want the launched activity to be alone in a + // docked stack, so we want to immediately launch recents too. + if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch."); + mWindowManager.showRecentApps(); + return; + } + + if (startedActivityStackId == PINNED_STACK_ID + && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP)) { + // The activity was already running in the pinned stack so it wasn't started, but either + // brought to the front or the new intent was delivered to it since it was already in + // front. Notify anyone interested in this piece of information. + mService.notifyPinnedActivityRestartAttemptLocked(); + return; + } } void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) { @@ -985,17 +1012,6 @@ class ActivityStarter { return START_SUCCESS; } - private void launchRecentsAppIfNeeded(ActivityStack topStack) { - if (topStack.mStackId == HOME_STACK_ID && mTargetStack != null - && mTargetStack.mStackId == DOCKED_STACK_ID) { - // We launch an activity while being in home stack, which means either launcher or - // recents into docked stack. We don't want the launched activity to be alone in a - // docked stack, so we want to immediately launch recents too. - if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch."); - mWindowManager.showRecentApps(); - } - } - private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { @@ -1557,11 +1573,13 @@ class ActivityStarter { final void doPendingActivityLaunchesLocked(boolean doResume) { while (!mPendingActivityLaunches.isEmpty()) { - PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); - + final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); + final boolean resume = doResume && mPendingActivityLaunches.isEmpty(); try { - startActivityUnchecked(pal.r, pal.sourceRecord, null, null, pal.startFlags, - doResume && mPendingActivityLaunches.isEmpty(), null, null); + final int result = startActivityUnchecked( + pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null); + postStartActivityUncheckedProcessing( + pal.r, result, mSupervisor.mFocusedStack.mStackId); } catch (Exception e) { Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e); pal.sendErrorResult(e.getMessage()); diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index c4653cf61afd..d1c088175a17 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -527,14 +527,26 @@ class DragState { ClipDescription description, ClipData data, IDropPermissions dropPermissions, boolean result) { + final float winX = translateToWindowX(win, x); + final float winY = translateToWindowY(win, y); + return DragEvent.obtain(action, winX, winY, localState, description, data, + dropPermissions, result); + } + + private static float translateToWindowX(WindowState win, float x) { float winX = x - win.mFrame.left; - float winY = y - win.mFrame.top; if (win.mEnforceSizeCompat) { winX *= win.mGlobalScale; + } + return winX; + } + + private static float translateToWindowY(WindowState win, float y) { + float winY = y - win.mFrame.top; + if (win.mEnforceSizeCompat) { winY *= win.mGlobalScale; } - return DragEvent.obtain(action, winX, winY, localState, description, data, - dropPermissions, result); + return winY; } boolean stepAnimationLocked(long currentTimeMs) { @@ -595,6 +607,17 @@ class DragState { private void restorePointerIconLw() { if (isFromSource(InputDevice.SOURCE_MOUSE)) { + WindowState touchWin = getTouchedWinAtPointLw(mCurrentX, mCurrentY); + if (touchWin != null) { + try { + touchWin.mClient.updatePointerIcon( + translateToWindowX(touchWin, mCurrentX), + translateToWindowY(touchWin, mCurrentY)); + return; + } catch (RemoteException e) { + Slog.w(TAG_WM, "unable to restore pointer icon"); + } + } InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 0fffd76ec401..e3e90b668bb9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -6389,9 +6389,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public UserHandle createAndManageUser(ComponentName admin, String name, - PersistableBundle adminExtras, int flags) { + ComponentName profileOwner, PersistableBundle adminExtras, int flags) { + Preconditions.checkNotNull(admin, "admin is null"); + Preconditions.checkNotNull(profileOwner, "profileOwner is null"); + if (!admin.getPackageName().equals(profileOwner.getPackageName())) { + throw new IllegalArgumentException("profileOwner " + profileOwner + " and admin " + + admin + " are not in the same package"); + } // Create user. - Preconditions.checkNotNull(admin, "ComponentName is null"); UserHandle user = null; synchronized (this) { getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); @@ -6427,7 +6432,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } - setActiveAdmin(admin, true, userHandle); + setActiveAdmin(profileOwner, true, userHandle); // User is not started yet, the broadcast by setActiveAdmin will not be received. // So we store adminExtras for broadcasting when the user starts for first time. synchronized(this) { @@ -6437,7 +6442,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { saveSettingsLocked(userHandle); } final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier()); - setProfileOwner(admin, ownerName, userHandle); + setProfileOwner(profileOwner, ownerName, userHandle); if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) { Settings.Secure.putIntForUser(mContext.getContentResolver(), diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 90d2aa0223a0..74f11719d237 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -38,6 +38,10 @@ public final class CellIdentityGsm implements Parcelable { private final int mLac; // 16-bit GSM Cell Identity described in TS 27.007, 0..65535 private final int mCid; + // 16-bit GSM Absolute RF Channel Number + private final int mArfcn; + // 6-bit Base Station Identity Code + private final int mBsic; /** * @hide @@ -47,6 +51,8 @@ public final class CellIdentityGsm implements Parcelable { mMnc = Integer.MAX_VALUE; mLac = Integer.MAX_VALUE; mCid = Integer.MAX_VALUE; + mArfcn = Integer.MAX_VALUE; + mBsic = Integer.MAX_VALUE; } /** * public constructor @@ -58,10 +64,27 @@ public final class CellIdentityGsm implements Parcelable { * @hide */ public CellIdentityGsm (int mcc, int mnc, int lac, int cid) { + this(mcc, mnc, lac, cid, Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * public constructor + * @param mcc 3-digit Mobile Country Code, 0..999 + * @param mnc 2 or 3-digit Mobile Network Code, 0..999 + * @param lac 16-bit Location Area Code, 0..65535 + * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity + * @param arfcn 16-bit GSM Absolute RF Channel Number + * @param bsic 6-bit Base Station Identity Code + * + * @hide + */ + public CellIdentityGsm (int mcc, int mnc, int lac, int cid, int arfcn, int bsic) { mMcc = mcc; mMnc = mnc; mLac = lac; mCid = cid; + mArfcn = arfcn; + mBsic = bsic; } private CellIdentityGsm(CellIdentityGsm cid) { @@ -69,6 +92,8 @@ public final class CellIdentityGsm implements Parcelable { mMnc = cid.mMnc; mLac = cid.mLac; mCid = cid.mCid; + mArfcn = cid.mArfcn; + mBsic = cid.mBsic; } CellIdentityGsm copy() { @@ -106,6 +131,21 @@ public final class CellIdentityGsm implements Parcelable { } /** + * @return 16-bit GSM Absolute RF Channel Number, Integer.MAX_VALUE if unknown + */ + public int getArfcn() { + return mArfcn; + } + + /** + * @return 6-bit Base Station Identity Code, Integer.MAX_VALUE if unknown + */ + public int getBsic() { + return mBsic; + } + + + /** * @return Integer.MAX_VALUE, undefined for GSM */ @Deprecated @@ -132,7 +172,9 @@ public final class CellIdentityGsm implements Parcelable { return mMcc == o.mMcc && mMnc == o.mMnc && mLac == o.mLac && - mCid == o.mCid; + mCid == o.mCid && + mArfcn == o.mArfcn && + mBsic == o.mBsic; } @Override @@ -142,6 +184,8 @@ public final class CellIdentityGsm implements Parcelable { sb.append(" mMnc=").append(mMnc); sb.append(" mLac=").append(mLac); sb.append(" mCid=").append(mCid); + sb.append(" mArfcn=").append(mArfcn); + sb.append(" mBsic=").append("0x").append(Integer.toHexString(mBsic)); sb.append("}"); return sb.toString(); @@ -161,6 +205,8 @@ public final class CellIdentityGsm implements Parcelable { dest.writeInt(mMnc); dest.writeInt(mLac); dest.writeInt(mCid); + dest.writeInt(mArfcn); + dest.writeInt(mBsic); } /** Construct from Parcel, type has already been processed */ @@ -169,6 +215,8 @@ public final class CellIdentityGsm implements Parcelable { mMnc = in.readInt(); mLac = in.readInt(); mCid = in.readInt(); + mArfcn = in.readInt(); + mBsic = in.readInt(); if (DBG) log("CellIdentityGsm(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index 1e7ac08b3e43..ce7438354a50 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -40,6 +40,8 @@ public final class CellIdentityLte implements Parcelable { private final int mPci; // 16-bit tracking area code private final int mTac; + // 18-bit Absolute RF Channel Number + private final int mEarfcn; /** * @hide @@ -50,6 +52,7 @@ public final class CellIdentityLte implements Parcelable { mCi = Integer.MAX_VALUE; mPci = Integer.MAX_VALUE; mTac = Integer.MAX_VALUE; + mEarfcn = Integer.MAX_VALUE; } /** @@ -63,11 +66,27 @@ public final class CellIdentityLte implements Parcelable { * @hide */ public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac) { + this(mcc, mnc, ci, pci, tac, Integer.MAX_VALUE); + } + + /** + * + * @param mcc 3-digit Mobile Country Code, 0..999 + * @param mnc 2 or 3-digit Mobile Network Code, 0..999 + * @param ci 28-bit Cell Identity + * @param pci Physical Cell Id 0..503 + * @param tac 16-bit Tracking Area Code + * @param earfcn 18-bit LTE Absolute RF Channel Number + * + * @hide + */ + public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac, int earfcn) { mMcc = mcc; mMnc = mnc; mCi = ci; mPci = pci; mTac = tac; + mEarfcn = earfcn; } private CellIdentityLte(CellIdentityLte cid) { @@ -76,6 +95,7 @@ public final class CellIdentityLte implements Parcelable { mCi = cid.mCi; mPci = cid.mPci; mTac = cid.mTac; + mEarfcn = cid.mEarfcn; } CellIdentityLte copy() { @@ -117,6 +137,13 @@ public final class CellIdentityLte implements Parcelable { return mTac; } + /** + * @return 18-bit Absolute RF Channel Number, Integer.MAX_VALUE if unknown + */ + public int getEarfcn() { + return mEarfcn; + } + @Override public int hashCode() { return Objects.hash(mMcc, mMnc, mCi, mPci, mTac); @@ -137,7 +164,8 @@ public final class CellIdentityLte implements Parcelable { mMnc == o.mMnc && mCi == o.mCi && mPci == o.mPci && - mTac == o.mTac; + mTac == o.mTac && + mEarfcn == o.mEarfcn; } @Override @@ -148,6 +176,7 @@ public final class CellIdentityLte implements Parcelable { sb.append(" mCi="); sb.append(mCi); sb.append(" mPci="); sb.append(mPci); sb.append(" mTac="); sb.append(mTac); + sb.append(" mEarfcn="); sb.append(mEarfcn); sb.append("}"); return sb.toString(); @@ -168,6 +197,7 @@ public final class CellIdentityLte implements Parcelable { dest.writeInt(mCi); dest.writeInt(mPci); dest.writeInt(mTac); + dest.writeInt(mEarfcn); } /** Construct from Parcel, type has already been processed */ @@ -177,6 +207,7 @@ public final class CellIdentityLte implements Parcelable { mCi = in.readInt(); mPci = in.readInt(); mTac = in.readInt(); + mEarfcn = in.readInt(); if (DBG) log("CellIdentityLte(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 56ee8c9df138..0d13efd279c9 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -40,6 +40,8 @@ public final class CellIdentityWcdma implements Parcelable { private final int mCid; // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511 private final int mPsc; + // 16-bit UMTS Absolute RF Channel Number + private final int mUarfcn; /** * @hide @@ -50,6 +52,7 @@ public final class CellIdentityWcdma implements Parcelable { mLac = Integer.MAX_VALUE; mCid = Integer.MAX_VALUE; mPsc = Integer.MAX_VALUE; + mUarfcn = Integer.MAX_VALUE; } /** * public constructor @@ -62,11 +65,27 @@ public final class CellIdentityWcdma implements Parcelable { * @hide */ public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) { + this(mcc, mnc, lac, cid, psc, Integer.MAX_VALUE); + } + + /** + * public constructor + * @param mcc 3-digit Mobile Country Code, 0..999 + * @param mnc 2 or 3-digit Mobile Network Code, 0..999 + * @param lac 16-bit Location Area Code, 0..65535 + * @param cid 28-bit UMTS Cell Identity + * @param psc 9-bit UMTS Primary Scrambling Code + * @param uarfcn 16-bit UMTS Absolute RF Channel Number + * + * @hide + */ + public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) { mMcc = mcc; mMnc = mnc; mLac = lac; mCid = cid; mPsc = psc; + mUarfcn = uarfcn; } private CellIdentityWcdma(CellIdentityWcdma cid) { @@ -75,6 +94,7 @@ public final class CellIdentityWcdma implements Parcelable { mLac = cid.mLac; mCid = cid.mCid; mPsc = cid.mPsc; + mUarfcn = cid.mUarfcn; } CellIdentityWcdma copy() { @@ -123,6 +143,13 @@ public final class CellIdentityWcdma implements Parcelable { return Objects.hash(mMcc, mMnc, mLac, mCid, mPsc); } + /** + * @return 16-bit UMTS Absolute RF Channel Number, Integer.MAX_VALUE if unknown + */ + public int getUarfcn() { + return mUarfcn; + } + @Override public boolean equals(Object other) { if (this == other) { @@ -138,7 +165,8 @@ public final class CellIdentityWcdma implements Parcelable { mMnc == o.mMnc && mLac == o.mLac && mCid == o.mCid && - mPsc == o.mPsc; + mPsc == o.mPsc && + mUarfcn == o.mUarfcn; } @Override @@ -149,6 +177,7 @@ public final class CellIdentityWcdma implements Parcelable { sb.append(" mLac=").append(mLac); sb.append(" mCid=").append(mCid); sb.append(" mPsc=").append(mPsc); + sb.append(" mUarfcn=").append(mUarfcn); sb.append("}"); return sb.toString(); @@ -169,6 +198,7 @@ public final class CellIdentityWcdma implements Parcelable { dest.writeInt(mLac); dest.writeInt(mCid); dest.writeInt(mPsc); + dest.writeInt(mUarfcn); } /** Construct from Parcel, type has already been processed */ @@ -178,6 +208,7 @@ public final class CellIdentityWcdma implements Parcelable { mLac = in.readInt(); mCid = in.readInt(); mPsc = in.readInt(); + mUarfcn = in.readInt(); if (DBG) log("CellIdentityWcdma(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index d27fcec38351..addf7ef025aa 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -34,6 +34,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 + private int mTimingAdvance; /** * Empty constructor @@ -75,6 +76,22 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P public void initialize(int ss, int ber) { mSignalStrength = ss; mBitErrorRate = ber; + mTimingAdvance = Integer.MAX_VALUE; + } + + /** + * Initialize all the values + * + * @param ss SignalStrength as ASU value + * @param ber is Bit Error Rate + * @param ta timing advance + * + * @hide + */ + public void initialize(int ss, int ber, int ta) { + mSignalStrength = ss; + mBitErrorRate = ber; + mTimingAdvance = ta; } /** @@ -83,6 +100,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P protected void copyFrom(CellSignalStrengthGsm s) { mSignalStrength = s.mSignalStrength; mBitErrorRate = s.mBitErrorRate; + mTimingAdvance = s.mTimingAdvance; } /** @@ -98,6 +116,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P public void setDefaultValues() { mSignalStrength = Integer.MAX_VALUE; mBitErrorRate = Integer.MAX_VALUE; + mTimingAdvance = Integer.MAX_VALUE; } /** @@ -174,7 +193,8 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P return false; } - return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate; + return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate && + s.mTimingAdvance == mTimingAdvance; } /** @@ -184,7 +204,8 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P public String toString() { return "CellSignalStrengthGsm:" + " ss=" + mSignalStrength - + " ber=" + mBitErrorRate; + + " ber=" + mBitErrorRate + + " mTa=" + mTimingAdvance; } /** Implement the Parcelable interface */ @@ -193,6 +214,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P if (DBG) log("writeToParcel(Parcel, int): " + toString()); dest.writeInt(mSignalStrength); dest.writeInt(mBitErrorRate); + dest.writeInt(mTimingAdvance); } /** @@ -202,6 +224,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P private CellSignalStrengthGsm(Parcel in) { mSignalStrength = in.readInt(); mBitErrorRate = in.readInt(); + mTimingAdvance = in.readInt(); if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString()); } |