Merge "OobData documentation" into nyc-dev
diff --git a/Android.mk b/Android.mk
index 2017404..f875be2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -472,7 +472,8 @@
LOCAL_AIDL_INCLUDES += \
frameworks/av/camera/aidl \
- frameworks/native/aidl/gui
+ frameworks/native/aidl/gui \
+ system/netd/server/binder
LOCAL_INTERMEDIATE_SOURCES := \
$(framework_res_source_path)/android/R.java \
@@ -688,6 +689,7 @@
frameworks/base/core/java/android/database/CursorWindow.aidl \
frameworks/base/core/java/android/service/quicksettings/Tile.aidl \
frameworks/native/aidl/binder/android/os/PersistableBundle.aidl \
+ system/netd/server/binder/android/net/UidRange.aidl \
gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
$(gen): PRIVATE_SRC_FILES := $(aidl_files)
diff --git a/api/current.txt b/api/current.txt
index 78b8501..a04ecfb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5554,6 +5554,7 @@
method public boolean onUnbind(android.content.Intent);
method public final void startForeground(int, android.app.Notification);
method public final void stopForeground(boolean);
+ method public final void stopForeground(int);
method public final void stopSelf();
method public final void stopSelf(int);
method public final boolean stopSelfResult(int);
@@ -5564,6 +5565,8 @@
field public static final int START_REDELIVER_INTENT = 3; // 0x3
field public static final int START_STICKY = 1; // 0x1
field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
+ field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+ field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
}
public abstract class SharedElementCallback {
@@ -29524,7 +29527,7 @@
field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726
field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b
field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e
- field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750
+ field public static final int MEASUREMENT_CPU_POWER_MAMS = 10064; // 0x2750
field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728
field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b
field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740
@@ -29536,11 +29539,11 @@
field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d
field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711
field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713
- field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f
+ field public static final int MEASUREMENT_SYSTEM_CPU_TIME_MS = 10063; // 0x274f
field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f
field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712
field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714
- field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e
+ field public static final int MEASUREMENT_USER_CPU_TIME_MS = 10062; // 0x274e
field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d
field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720
field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f
diff --git a/api/system-current.txt b/api/system-current.txt
index 14391a3..013d8f1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5689,6 +5689,7 @@
method public boolean onUnbind(android.content.Intent);
method public final void startForeground(int, android.app.Notification);
method public final void stopForeground(boolean);
+ method public final void stopForeground(int);
method public final void stopSelf();
method public final void stopSelf(int);
method public final boolean stopSelfResult(int);
@@ -5699,6 +5700,8 @@
field public static final int START_REDELIVER_INTENT = 3; // 0x3
field public static final int START_STICKY = 1; // 0x1
field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
+ field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+ field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
}
public abstract class SharedElementCallback {
@@ -25338,7 +25341,10 @@
public class ConnectivityMetricsLogger {
ctor public ConnectivityMetricsLogger();
+ method public android.net.ConnectivityMetricsEvent[] getEvents(android.net.ConnectivityMetricsEvent.Reference);
method public void logEvent(long, int, int, android.os.Parcelable);
+ method public boolean register(android.app.PendingIntent);
+ method public boolean unregister(android.app.PendingIntent);
field public static final int COMPONENT_TAG_BLUETOOTH = 1; // 0x1
field public static final int COMPONENT_TAG_CONNECTIVITY = 0; // 0x0
field public static final int COMPONENT_TAG_TELECOM = 3; // 0x3
@@ -32018,7 +32024,7 @@
field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726
field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b
field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e
- field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750
+ field public static final int MEASUREMENT_CPU_POWER_MAMS = 10064; // 0x2750
field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728
field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b
field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740
@@ -32030,11 +32036,11 @@
field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d
field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711
field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713
- field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f
+ field public static final int MEASUREMENT_SYSTEM_CPU_TIME_MS = 10063; // 0x274f
field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f
field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712
field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714
- field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e
+ field public static final int MEASUREMENT_USER_CPU_TIME_MS = 10062; // 0x274e
field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d
field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720
field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f
@@ -48880,6 +48886,7 @@
public final class WebViewDelegate {
method public void addWebViewAssetPath(android.content.Context);
method public void callDrawGlFunction(android.graphics.Canvas, long);
+ method public void callDrawGlFunction(android.graphics.Canvas, long, java.lang.Runnable);
method public boolean canInvokeDrawGlFunctor(android.view.View);
method public void detachDrawGlFunctor(android.view.View, long);
method public android.app.Application getApplication();
diff --git a/api/test-current.txt b/api/test-current.txt
index 4e83278..d056f7d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5554,6 +5554,7 @@
method public boolean onUnbind(android.content.Intent);
method public final void startForeground(int, android.app.Notification);
method public final void stopForeground(boolean);
+ method public final void stopForeground(int);
method public final void stopSelf();
method public final void stopSelf(int);
method public final boolean stopSelfResult(int);
@@ -5564,6 +5565,8 @@
field public static final int START_REDELIVER_INTENT = 3; // 0x3
field public static final int START_STICKY = 1; // 0x1
field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
+ field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+ field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
}
public abstract class SharedElementCallback {
@@ -29593,7 +29596,7 @@
field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726
field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b
field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e
- field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750
+ field public static final int MEASUREMENT_CPU_POWER_MAMS = 10064; // 0x2750
field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728
field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b
field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740
@@ -29605,11 +29608,11 @@
field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d
field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711
field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713
- field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f
+ field public static final int MEASUREMENT_SYSTEM_CPU_TIME_MS = 10063; // 0x274f
field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f
field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712
field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714
- field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e
+ field public static final int MEASUREMENT_USER_CPU_TIME_MS = 10062; // 0x274e
field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d
field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720
field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index b83484d..31c7421 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -44,6 +44,7 @@
private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin";
private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
+ private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin";
private IDevicePolicyManager mDevicePolicyManager;
private int mUserId = UserHandle.USER_SYSTEM;
@@ -60,6 +61,8 @@
"[ --name <NAME> ] <COMPONENT>\n" +
"usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " +
"<COMPONENT>\n" +
+ "usage: dpm remove-active-admin [ --user <USER_ID> | current ] [ --name <NAME> ] " +
+ "<COMPONENT>\n" +
"\n" +
"dpm set-active-admin: Sets the given component as active admin" +
" for an existing user.\n" +
@@ -68,7 +71,11 @@
" package as device owner.\n" +
"\n" +
"dpm set-profile-owner: Sets the given component as active admin and profile" +
- " owner for an existing user.\n");
+ " owner for an existing user.\n" +
+ "\n" +
+ "dpm remove-active-admin: Disables an active admin, the admin must have declared" +
+ " android:testOnly in the application in its manifest. This will also remove" +
+ " device and profile owners\n");
}
@Override
@@ -91,6 +98,9 @@
case COMMAND_SET_PROFILE_OWNER:
runSetProfileOwner();
break;
+ case COMMAND_REMOVE_ACTIVE_ADMIN:
+ runRemoveActiveAdmin();
+ break;
default:
throw new IllegalArgumentException ("unknown command '" + command + "'");
}
@@ -152,6 +162,12 @@
System.out.println("Active admin set to component " + mComponent.toShortString());
}
+ private void runRemoveActiveAdmin() throws RemoteException {
+ parseArgs(/*canHaveName=*/ false);
+ mDevicePolicyManager.forceRemoveActiveAdmin(mComponent, mUserId);
+ System.out.println("Success: Admin removed " + mComponent);
+ }
+
private void runSetProfileOwner() throws RemoteException {
parseArgs(/*canHaveName=*/ true);
mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index e788d27..8ff38bb 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -559,7 +559,8 @@
boolean previouslyPaused = mPaused;
super.pause();
if (!previouslyPaused && mPaused) {
- if (mDelayAnim != null) {
+ if (mDelayAnim.isStarted()) {
+ // If delay hasn't passed, pause the start delay animator.
mDelayAnim.pause();
} else {
int size = mNodes.size();
@@ -578,7 +579,8 @@
boolean previouslyPaused = mPaused;
super.resume();
if (previouslyPaused && !mPaused) {
- if (mDelayAnim != null) {
+ if (mDelayAnim.isStarted()) {
+ // If start delay hasn't passed, resume the previously paused start delay animator
mDelayAnim.resume();
} else {
int size = mNodes.size();
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a82b950..ae2ca84 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1111,8 +1111,8 @@
if (data.readInt() != 0) {
notification = Notification.CREATOR.createFromParcel(data);
}
- boolean removeNotification = data.readInt() != 0;
- setServiceForeground(className, token, id, notification, removeNotification);
+ int sflags = data.readInt();
+ setServiceForeground(className, token, id, notification, sflags);
reply.writeNoException();
return true;
}
@@ -4300,7 +4300,7 @@
return res;
}
public void setServiceForeground(ComponentName className, IBinder token,
- int id, Notification notification, boolean removeNotification) throws RemoteException {
+ int id, Notification notification, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4313,7 +4313,7 @@
} else {
data.writeInt(0);
}
- data.writeInt(removeNotification ? 1 : 0);
+ data.writeInt(flags);
mRemote.transact(SET_SERVICE_FOREGROUND_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1a4e98c..b28b5e6 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -235,7 +235,7 @@
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) throws RemoteException;
public void setServiceForeground(ComponentName className, IBinder token,
- int id, Notification notification, boolean keepNotification) throws RemoteException;
+ int id, Notification notification, int flags) throws RemoteException;
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags,
String callingPackage, int userId) throws RemoteException;
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 21a3543..4fe4f98 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
@@ -30,6 +31,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* A Service is an application component representing either an application's desire
@@ -300,6 +303,32 @@
public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
private static final String TAG = "Service";
+ /**
+ * Flag for {@link #stopForeground(int)}: if set, the notification previously provided
+ * to {@link #startForeground} will be removed. Otherwise it will remain
+ * until a later call (to {@link #startForeground(int, Notification)} or
+ * {@link #stopForeground(int)} removes it, or the service is destroyed.
+ */
+ public static final int STOP_FOREGROUND_REMOVE = 1<<0;
+
+ /**
+ * Flag for {@link #stopForeground(int)}: if set, the notification previously provided
+ * to {@link #startForeground} will be detached from the service. Only makes sense
+ * when {@link #STOP_FOREGROUND_REMOVE} is <b>not</b> set -- in this case, the notification
+ * will remain shown, but be completely detached from the service and so no longer changed
+ * except through direct calls to the notification manager.
+ */
+ public static final int STOP_FOREGROUND_DETACH = 1<<1;
+
+ /** @hide */
+ @IntDef(flag = true,
+ value = {
+ STOP_FOREGROUND_REMOVE,
+ STOP_FOREGROUND_DETACH
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StopForegroundFlags {}
+
public Service() {
super(null);
}
@@ -377,7 +406,7 @@
* alarm goes off.
*/
public static final int START_NOT_STICKY = 2;
-
+
/**
* Constant to return from {@link #onStartCommand}: if this service's
* process is killed while it is started (after returning from
@@ -392,7 +421,18 @@
* pending events will be delivered at the point of restart).
*/
public static final int START_REDELIVER_INTENT = 3;
-
+
+ /** @hide */
+ @IntDef(flag = false,
+ value = {
+ START_STICKY_COMPATIBILITY,
+ START_STICKY,
+ START_NOT_STICKY,
+ START_REDELIVER_INTENT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StartResult {}
+
/**
* Special constant for reporting that we are done processing
* {@link #onTaskRemoved(Intent)}.
@@ -414,7 +454,17 @@
* {@link #onStartCommand(Intent, int, int)}.
*/
public static final int START_FLAG_RETRY = 0x0002;
-
+
+ /** @hide */
+ @IntDef(flag = true,
+ value = {
+ START_FLAG_REDELIVERY,
+ START_FLAG_RETRY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StartArgFlags {}
+
+
/**
* Called by the system every time a client explicitly starts the service by calling
* {@link android.content.Context#startService}, providing the arguments it supplied and a
@@ -455,7 +505,7 @@
*
* @see #stopSelfResult(int)
*/
- public int onStartCommand(Intent intent, int flags, int startId) {
+ public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
@@ -652,28 +702,37 @@
try {
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
- notification, true);
+ notification, 0);
} catch (RemoteException ex) {
}
}
/**
- * Remove this service from foreground state, allowing it to be killed if
- * more memory is needed.
- * @param removeNotification If true, the notification previously provided
- * to {@link #startForeground} will be removed. Otherwise it will remain
- * until a later call removes it (or the service is destroyed).
+ * Synonym for {@link #stopForeground(int)}.
+ * @param removeNotification If true, the {@link #STOP_FOREGROUND_REMOVE} flag
+ * will be supplied.
+ * @see #stopForeground(int)
* @see #startForeground(int, Notification)
*/
public final void stopForeground(boolean removeNotification) {
+ stopForeground(removeNotification ? STOP_FOREGROUND_REMOVE : 0);
+ }
+
+ /**
+ * Remove this service from foreground state, allowing it to be killed if
+ * more memory is needed.
+ * @param flags Additional behavior options: {@link #STOP_FOREGROUND_REMOVE},
+ * {@link #STOP_FOREGROUND_DETACH}.
+ * @see #startForeground(int, Notification)
+ */
+ public final void stopForeground(@StopForegroundFlags int flags) {
try {
mActivityManager.setServiceForeground(
- new ComponentName(this, mClassName), mToken, 0, null,
- removeNotification);
+ new ComponentName(this, mClassName), mToken, 0, null, flags);
} catch (RemoteException ex) {
}
}
-
+
/**
* Print the Service's state into the given stream. This gets invoked if
* you run "adb shell dumpsys activity service <yourservicename>"
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 7a18df6..0ca2e14 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6391,6 +6391,24 @@
}
}
+ /**
+ * @hide
+ * Remove a test admin synchronously without sending it a broadcast about being removed.
+ * If the admin is a profile owner or device owner it will still be removed.
+ *
+ * @param userHandle user id to remove the admin for.
+ * @param admin The administration compononent to remove.
+ * @throws SecurityException if the caller is not shell / root or the admin package
+ * isn't a test application see {@link ApplicationInfo#FLAG_TEST_APP}.
+ */
+ public void forceRemoveActiveAdmin(ComponentName adminReceiver, int userHandle) {
+ try {
+ mService.forceRemoveActiveAdmin(adminReceiver, userHandle);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
private void throwIfParentInstance(String functionName) {
if (mParentInstance) {
throw new SecurityException(functionName + " cannot be called on the parent instance");
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index cba64c2..989e613 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -111,6 +111,7 @@
boolean packageHasActiveAdmins(String packageName, int userHandle);
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result, int userHandle);
void removeActiveAdmin(in ComponentName policyReceiver, int userHandle);
+ void forceRemoveActiveAdmin(in ComponentName policyReceiver, int userHandle);
boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 15cc17d..8349d3d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2446,6 +2446,15 @@
* <p>This function will throw {@link SecurityException} if you do not
* have permission to start the given service.
*
+ * <p class="note"><strong>Note:</strong> Each call to startService()
+ * results in significant work done by the system to manage service
+ * lifecycle surrounding the processing of the intent, which can take
+ * multiple milliseconds of CPU time. Due to this cost, startService()
+ * should not be used for frequent intent delivery to a service, and only
+ * for scheduling significant work. Use {@link #bindService bound services}
+ * for high frequency calls.
+ * </p>
+ *
* @param service Identifies the service to be started. The Intent must be either
* fully explicit (supplying a component name) or specify a specific package
* name it is targetted to. Additional values
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4108f6d..bb8bca4 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -131,12 +131,6 @@
/** File name in an APK for the Android manifest. */
private static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
- /**
- * File name in an APK for bytecode. There may be additional bytecode files
- * but this one is always required for an APK that has code.
- */
- private static final String BYTECODE_FILENAME = "classes.dex";
-
/** Path prefix for apps on expanded storage */
private static final String MNT_EXPAND = "/mnt/expand/";
@@ -1137,13 +1131,11 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
- collectCertificates(
- pkg, new File(pkg.baseCodePath), pkg.applicationInfo.flags, parseFlags);
+ collectCertificates(pkg, new File(pkg.baseCodePath), parseFlags);
if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
for (int i = 0; i < pkg.splitCodePaths.length; i++) {
- collectCertificates(
- pkg, new File(pkg.splitCodePaths[i]), pkg.splitFlags[i], parseFlags);
+ collectCertificates(pkg, new File(pkg.splitCodePaths[i]), parseFlags);
}
}
} finally {
@@ -1151,10 +1143,8 @@
}
}
- private static void collectCertificates(Package pkg, File apkFile, int apkFlags, int parseFlags)
+ private static void collectCertificates(Package pkg, File apkFile, int parseFlags)
throws PackageParserException {
- final boolean hasCode = (apkFlags & ApplicationInfo.FLAG_HAS_CODE) != 0;
- final boolean requireCode = ((parseFlags & PARSE_ENFORCE_CODE) != 0) && hasCode;
final String apkPath = apkFile.getAbsolutePath();
// Try to verify the APK using APK Signature Scheme v2.
@@ -1202,7 +1192,6 @@
}
}
- boolean codeFound = false;
StrictJarFile jarFile = null;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
@@ -1226,10 +1215,6 @@
// Optimization: early termination when APK already verified
if (verified) {
- if ((requireCode) && (jarFile.findEntry(BYTECODE_FILENAME) == null)) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
- "Package " + apkPath + " code is missing");
- }
return;
}
@@ -1249,19 +1234,11 @@
final String entryName = entry.getName();
if (entryName.startsWith("META-INF/")) continue;
if (entryName.equals(ANDROID_MANIFEST_FILENAME)) continue;
- if (entryName.equals(BYTECODE_FILENAME)) {
- codeFound = true;
- }
toVerify.add(entry);
}
}
- if (!codeFound && requireCode) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
- "Package " + apkPath + " code is missing");
- }
-
// Verify that entries are signed consistently with the first entry
// we encountered. Note that for splits, certificates may have
// already been populated during an earlier parse of a base APK.
@@ -1349,7 +1326,7 @@
final Package tempPkg = new Package(null);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
- collectCertificates(tempPkg, apkFile, 0 /*apkFlags*/, 0 /*flags*/);
+ collectCertificates(tempPkg, apkFile, 0 /*parseFlags*/);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
diff --git a/core/java/android/net/ConnectivityMetricsLogger.java b/core/java/android/net/ConnectivityMetricsLogger.java
index b49cc2b..d8cdde9 100644
--- a/core/java/android/net/ConnectivityMetricsLogger.java
+++ b/core/java/android/net/ConnectivityMetricsLogger.java
@@ -16,6 +16,7 @@
package android.net;
import android.annotation.SystemApi;
+import android.app.PendingIntent;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -106,4 +107,46 @@
Log.e(TAG, "Error logging event " + e.getMessage());
}
}
+
+ /**
+ * Retrieve events
+ *
+ * @param reference of the last event previously returned. The function will return
+ * events following it.
+ * If 0 then all events will be returned.
+ * After the function call it will contain reference of the
+ * last returned event.
+ * @return events
+ */
+ public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) {
+ try {
+ return mService.getEvents(reference);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "IConnectivityMetricsLogger.getEvents: " + ex);
+ return null;
+ }
+ }
+
+ /**
+ * Register PendingIntent which will be sent when new events are ready to be retrieved.
+ */
+ public boolean register(PendingIntent newEventsIntent) {
+ try {
+ return mService.register(newEventsIntent);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "IConnectivityMetricsLogger.register: " + ex);
+ return false;
+ }
+ }
+
+ public boolean unregister(PendingIntent newEventsIntent) {
+ try {
+ mService.unregister(newEventsIntent);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "IConnectivityMetricsLogger.unregister: " + ex);
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/core/java/android/os/health/UidHealthStats.java b/core/java/android/os/health/UidHealthStats.java
index c7d257f..337235a 100644
--- a/core/java/android/os/health/UidHealthStats.java
+++ b/core/java/android/os/health/UidHealthStats.java
@@ -261,16 +261,16 @@
public static final int TIMER_MOBILE_RADIO_ACTIVE = HealthKeys.BASE_UID + 61;
@HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
- public static final int MEASUREMENT_USER_CPU_TIME_US = HealthKeys.BASE_UID + 62;
+ public static final int MEASUREMENT_USER_CPU_TIME_MS = HealthKeys.BASE_UID + 62;
@HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
- public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = HealthKeys.BASE_UID + 63;
+ public static final int MEASUREMENT_SYSTEM_CPU_TIME_MS = HealthKeys.BASE_UID + 63;
/**
* An estimate of the number of milliamp-microsends used by this uid.
*/
@HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
- public static final int MEASUREMENT_CPU_POWER_MAUS = HealthKeys.BASE_UID + 64;
+ public static final int MEASUREMENT_CPU_POWER_MAMS = HealthKeys.BASE_UID + 64;
/**
* @hide
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
index c0f0663..b62cc66 100644
--- a/core/java/android/text/Emoji.java
+++ b/core/java/android/text/Emoji.java
@@ -24,6 +24,122 @@
*/
public class Emoji {
// See http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
+ // TODO: Generate from external/unicode/emoji-data.txt
+ private static int[] EMOJI_LIST = {
+ 0x0023, 0x002A, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x00A9, 0x00AE, 0x203C, 0x2049, 0x2122, 0x2139, 0x2194, 0x2195, 0x2196, 0x2197,
+ 0x2198, 0x2199, 0x21A9, 0x21AA, 0x231A, 0x231B, 0x2328, 0x23CF, 0x23E9, 0x23EA, 0x23EB,
+ 0x23EC, 0x23ED, 0x23EE, 0x23EF, 0x23F0, 0x23F1, 0x23F2, 0x23F3, 0x23F8, 0x23F9, 0x23FA,
+ 0x24C2, 0x25AA, 0x25AB, 0x25B6, 0x25C0, 0x25FB, 0x25FC, 0x25FD, 0x25FE, 0x2600, 0x2601,
+ 0x2602, 0x2603, 0x2604, 0x260E, 0x2611, 0x2614, 0x2615, 0x2618, 0x261D, 0x2620, 0x2622,
+ 0x2623, 0x2626, 0x262A, 0x262E, 0x262F, 0x2638, 0x2639, 0x263A, 0x2648, 0x2649, 0x264A,
+ 0x264B, 0x264C, 0x264D, 0x264E, 0x264F, 0x2650, 0x2651, 0x2652, 0x2653, 0x2660, 0x2663,
+ 0x2665, 0x2666, 0x2668, 0x267B, 0x267F, 0x2692, 0x2693, 0x2694, 0x2696, 0x2697, 0x2699,
+ 0x269B, 0x269C, 0x26A0, 0x26A1, 0x26AA, 0x26AB, 0x26B0, 0x26B1, 0x26BD, 0x26BE, 0x26C4,
+ 0x26C5, 0x26C8, 0x26CE, 0x26CF, 0x26D1, 0x26D3, 0x26D4, 0x26E9, 0x26EA, 0x26F0, 0x26F1,
+ 0x26F2, 0x26F3, 0x26F4, 0x26F5, 0x26F7, 0x26F8, 0x26F9, 0x26FA, 0x26FD, 0x2702, 0x2705,
+ 0x2708, 0x2709, 0x270A, 0x270B, 0x270C, 0x270D, 0x270F, 0x2712, 0x2714, 0x2716, 0x271D,
+ 0x2721, 0x2728, 0x2733, 0x2734, 0x2744, 0x2747, 0x274C, 0x274E, 0x2753, 0x2754, 0x2755,
+ 0x2757, 0x2763, 0x2764, 0x2795, 0x2796, 0x2797, 0x27A1, 0x27B0, 0x27BF, 0x2934, 0x2935,
+ 0x2B05, 0x2B06, 0x2B07, 0x2B1B, 0x2B1C, 0x2B50, 0x2B55, 0x3030, 0x303D, 0x3297, 0x3299,
+ 0x1F004, 0x1F0CF, 0x1F170, 0x1F171, 0x1F17E, 0x1F17F, 0x1F18E, 0x1F191, 0x1F192, 0x1F193,
+ 0x1F194, 0x1F195, 0x1F196, 0x1F197, 0x1F198, 0x1F199, 0x1F19A, 0x1F1E6, 0x1F1E7, 0x1F1E8,
+ 0x1F1E9, 0x1F1EA, 0x1F1EB, 0x1F1EC, 0x1F1ED, 0x1F1EE, 0x1F1EF, 0x1F1F0, 0x1F1F1, 0x1F1F2,
+ 0x1F1F3, 0x1F1F4, 0x1F1F5, 0x1F1F6, 0x1F1F7, 0x1F1F8, 0x1F1F9, 0x1F1FA, 0x1F1FB, 0x1F1FC,
+ 0x1F1FD, 0x1F1FE, 0x1F1FF, 0x1F201, 0x1F202, 0x1F21A, 0x1F22F, 0x1F232, 0x1F233, 0x1F234,
+ 0x1F235, 0x1F236, 0x1F237, 0x1F238, 0x1F239, 0x1F23A, 0x1F250, 0x1F251, 0x1F300, 0x1F301,
+ 0x1F302, 0x1F303, 0x1F304, 0x1F305, 0x1F306, 0x1F307, 0x1F308, 0x1F309, 0x1F30A, 0x1F30B,
+ 0x1F30C, 0x1F30D, 0x1F30E, 0x1F30F, 0x1F310, 0x1F311, 0x1F312, 0x1F313, 0x1F314, 0x1F315,
+ 0x1F316, 0x1F317, 0x1F318, 0x1F319, 0x1F31A, 0x1F31B, 0x1F31C, 0x1F31D, 0x1F31E, 0x1F31F,
+ 0x1F320, 0x1F321, 0x1F324, 0x1F325, 0x1F326, 0x1F327, 0x1F328, 0x1F329, 0x1F32A, 0x1F32B,
+ 0x1F32C, 0x1F32D, 0x1F32E, 0x1F32F, 0x1F330, 0x1F331, 0x1F332, 0x1F333, 0x1F334, 0x1F335,
+ 0x1F336, 0x1F337, 0x1F338, 0x1F339, 0x1F33A, 0x1F33B, 0x1F33C, 0x1F33D, 0x1F33E, 0x1F33F,
+ 0x1F340, 0x1F341, 0x1F342, 0x1F343, 0x1F344, 0x1F345, 0x1F346, 0x1F347, 0x1F348, 0x1F349,
+ 0x1F34A, 0x1F34B, 0x1F34C, 0x1F34D, 0x1F34E, 0x1F34F, 0x1F350, 0x1F351, 0x1F352, 0x1F353,
+ 0x1F354, 0x1F355, 0x1F356, 0x1F357, 0x1F358, 0x1F359, 0x1F35A, 0x1F35B, 0x1F35C, 0x1F35D,
+ 0x1F35E, 0x1F35F, 0x1F360, 0x1F361, 0x1F362, 0x1F363, 0x1F364, 0x1F365, 0x1F366, 0x1F367,
+ 0x1F368, 0x1F369, 0x1F36A, 0x1F36B, 0x1F36C, 0x1F36D, 0x1F36E, 0x1F36F, 0x1F370, 0x1F371,
+ 0x1F372, 0x1F373, 0x1F374, 0x1F375, 0x1F376, 0x1F377, 0x1F378, 0x1F379, 0x1F37A, 0x1F37B,
+ 0x1F37C, 0x1F37D, 0x1F37E, 0x1F37F, 0x1F380, 0x1F381, 0x1F382, 0x1F383, 0x1F384, 0x1F385,
+ 0x1F386, 0x1F387, 0x1F388, 0x1F389, 0x1F38A, 0x1F38B, 0x1F38C, 0x1F38D, 0x1F38E, 0x1F38F,
+ 0x1F390, 0x1F391, 0x1F392, 0x1F393, 0x1F396, 0x1F397, 0x1F399, 0x1F39A, 0x1F39B, 0x1F39E,
+ 0x1F39F, 0x1F3A0, 0x1F3A1, 0x1F3A2, 0x1F3A3, 0x1F3A4, 0x1F3A5, 0x1F3A6, 0x1F3A7, 0x1F3A8,
+ 0x1F3A9, 0x1F3AA, 0x1F3AB, 0x1F3AC, 0x1F3AD, 0x1F3AE, 0x1F3AF, 0x1F3B0, 0x1F3B1, 0x1F3B2,
+ 0x1F3B3, 0x1F3B4, 0x1F3B5, 0x1F3B6, 0x1F3B7, 0x1F3B8, 0x1F3B9, 0x1F3BA, 0x1F3BB, 0x1F3BC,
+ 0x1F3BD, 0x1F3BE, 0x1F3BF, 0x1F3C0, 0x1F3C1, 0x1F3C2, 0x1F3C3, 0x1F3C4, 0x1F3C5, 0x1F3C6,
+ 0x1F3C7, 0x1F3C8, 0x1F3C9, 0x1F3CA, 0x1F3CB, 0x1F3CC, 0x1F3CD, 0x1F3CE, 0x1F3CF, 0x1F3D0,
+ 0x1F3D1, 0x1F3D2, 0x1F3D3, 0x1F3D4, 0x1F3D5, 0x1F3D6, 0x1F3D7, 0x1F3D8, 0x1F3D9, 0x1F3DA,
+ 0x1F3DB, 0x1F3DC, 0x1F3DD, 0x1F3DE, 0x1F3DF, 0x1F3E0, 0x1F3E1, 0x1F3E2, 0x1F3E3, 0x1F3E4,
+ 0x1F3E5, 0x1F3E6, 0x1F3E7, 0x1F3E8, 0x1F3E9, 0x1F3EA, 0x1F3EB, 0x1F3EC, 0x1F3ED, 0x1F3EE,
+ 0x1F3EF, 0x1F3F0, 0x1F3F3, 0x1F3F4, 0x1F3F5, 0x1F3F7, 0x1F3F8, 0x1F3F9, 0x1F3FA, 0x1F3FB,
+ 0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF, 0x1F400, 0x1F401, 0x1F402, 0x1F403, 0x1F404, 0x1F405,
+ 0x1F406, 0x1F407, 0x1F408, 0x1F409, 0x1F40A, 0x1F40B, 0x1F40C, 0x1F40D, 0x1F40E, 0x1F40F,
+ 0x1F410, 0x1F411, 0x1F412, 0x1F413, 0x1F414, 0x1F415, 0x1F416, 0x1F417, 0x1F418, 0x1F419,
+ 0x1F41A, 0x1F41B, 0x1F41C, 0x1F41D, 0x1F41E, 0x1F41F, 0x1F420, 0x1F421, 0x1F422, 0x1F423,
+ 0x1F424, 0x1F425, 0x1F426, 0x1F427, 0x1F428, 0x1F429, 0x1F42A, 0x1F42B, 0x1F42C, 0x1F42D,
+ 0x1F42E, 0x1F42F, 0x1F430, 0x1F431, 0x1F432, 0x1F433, 0x1F434, 0x1F435, 0x1F436, 0x1F437,
+ 0x1F438, 0x1F439, 0x1F43A, 0x1F43B, 0x1F43C, 0x1F43D, 0x1F43E, 0x1F43F, 0x1F440, 0x1F441,
+ 0x1F442, 0x1F443, 0x1F444, 0x1F445, 0x1F446, 0x1F447, 0x1F448, 0x1F449, 0x1F44A, 0x1F44B,
+ 0x1F44C, 0x1F44D, 0x1F44E, 0x1F44F, 0x1F450, 0x1F451, 0x1F452, 0x1F453, 0x1F454, 0x1F455,
+ 0x1F456, 0x1F457, 0x1F458, 0x1F459, 0x1F45A, 0x1F45B, 0x1F45C, 0x1F45D, 0x1F45E, 0x1F45F,
+ 0x1F460, 0x1F461, 0x1F462, 0x1F463, 0x1F464, 0x1F465, 0x1F466, 0x1F467, 0x1F468, 0x1F469,
+ 0x1F46A, 0x1F46B, 0x1F46C, 0x1F46D, 0x1F46E, 0x1F46F, 0x1F470, 0x1F471, 0x1F472, 0x1F473,
+ 0x1F474, 0x1F475, 0x1F476, 0x1F477, 0x1F478, 0x1F479, 0x1F47A, 0x1F47B, 0x1F47C, 0x1F47D,
+ 0x1F47E, 0x1F47F, 0x1F480, 0x1F481, 0x1F482, 0x1F483, 0x1F484, 0x1F485, 0x1F486, 0x1F487,
+ 0x1F488, 0x1F489, 0x1F48A, 0x1F48B, 0x1F48C, 0x1F48D, 0x1F48E, 0x1F48F, 0x1F490, 0x1F491,
+ 0x1F492, 0x1F493, 0x1F494, 0x1F495, 0x1F496, 0x1F497, 0x1F498, 0x1F499, 0x1F49A, 0x1F49B,
+ 0x1F49C, 0x1F49D, 0x1F49E, 0x1F49F, 0x1F4A0, 0x1F4A1, 0x1F4A2, 0x1F4A3, 0x1F4A4, 0x1F4A5,
+ 0x1F4A6, 0x1F4A7, 0x1F4A8, 0x1F4A9, 0x1F4AA, 0x1F4AB, 0x1F4AC, 0x1F4AD, 0x1F4AE, 0x1F4AF,
+ 0x1F4B0, 0x1F4B1, 0x1F4B2, 0x1F4B3, 0x1F4B4, 0x1F4B5, 0x1F4B6, 0x1F4B7, 0x1F4B8, 0x1F4B9,
+ 0x1F4BA, 0x1F4BB, 0x1F4BC, 0x1F4BD, 0x1F4BE, 0x1F4BF, 0x1F4C0, 0x1F4C1, 0x1F4C2, 0x1F4C3,
+ 0x1F4C4, 0x1F4C5, 0x1F4C6, 0x1F4C7, 0x1F4C8, 0x1F4C9, 0x1F4CA, 0x1F4CB, 0x1F4CC, 0x1F4CD,
+ 0x1F4CE, 0x1F4CF, 0x1F4D0, 0x1F4D1, 0x1F4D2, 0x1F4D3, 0x1F4D4, 0x1F4D5, 0x1F4D6, 0x1F4D7,
+ 0x1F4D8, 0x1F4D9, 0x1F4DA, 0x1F4DB, 0x1F4DC, 0x1F4DD, 0x1F4DE, 0x1F4DF, 0x1F4E0, 0x1F4E1,
+ 0x1F4E2, 0x1F4E3, 0x1F4E4, 0x1F4E5, 0x1F4E6, 0x1F4E7, 0x1F4E8, 0x1F4E9, 0x1F4EA, 0x1F4EB,
+ 0x1F4EC, 0x1F4ED, 0x1F4EE, 0x1F4EF, 0x1F4F0, 0x1F4F1, 0x1F4F2, 0x1F4F3, 0x1F4F4, 0x1F4F5,
+ 0x1F4F6, 0x1F4F7, 0x1F4F8, 0x1F4F9, 0x1F4FA, 0x1F4FB, 0x1F4FC, 0x1F4FD, 0x1F4FF, 0x1F500,
+ 0x1F501, 0x1F502, 0x1F503, 0x1F504, 0x1F505, 0x1F506, 0x1F507, 0x1F508, 0x1F509, 0x1F50A,
+ 0x1F50B, 0x1F50C, 0x1F50D, 0x1F50E, 0x1F50F, 0x1F510, 0x1F511, 0x1F512, 0x1F513, 0x1F514,
+ 0x1F515, 0x1F516, 0x1F517, 0x1F518, 0x1F519, 0x1F51A, 0x1F51B, 0x1F51C, 0x1F51D, 0x1F51E,
+ 0x1F51F, 0x1F520, 0x1F521, 0x1F522, 0x1F523, 0x1F524, 0x1F525, 0x1F526, 0x1F527, 0x1F528,
+ 0x1F529, 0x1F52A, 0x1F52B, 0x1F52C, 0x1F52D, 0x1F52E, 0x1F52F, 0x1F530, 0x1F531, 0x1F532,
+ 0x1F533, 0x1F534, 0x1F535, 0x1F536, 0x1F537, 0x1F538, 0x1F539, 0x1F53A, 0x1F53B, 0x1F53C,
+ 0x1F53D, 0x1F549, 0x1F54A, 0x1F54B, 0x1F54C, 0x1F54D, 0x1F54E, 0x1F550, 0x1F551, 0x1F552,
+ 0x1F553, 0x1F554, 0x1F555, 0x1F556, 0x1F557, 0x1F558, 0x1F559, 0x1F55A, 0x1F55B, 0x1F55C,
+ 0x1F55D, 0x1F55E, 0x1F55F, 0x1F560, 0x1F561, 0x1F562, 0x1F563, 0x1F564, 0x1F565, 0x1F566,
+ 0x1F567, 0x1F56F, 0x1F570, 0x1F573, 0x1F574, 0x1F575, 0x1F576, 0x1F577, 0x1F578, 0x1F579,
+ 0x1F57A, 0x1F587, 0x1F58A, 0x1F58B, 0x1F58C, 0x1F58D, 0x1F590, 0x1F595, 0x1F596, 0x1F5A4,
+ 0x1F5A5, 0x1F5A8, 0x1F5B1, 0x1F5B2, 0x1F5BC, 0x1F5C2, 0x1F5C3, 0x1F5C4, 0x1F5D1, 0x1F5D2,
+ 0x1F5D3, 0x1F5DC, 0x1F5DD, 0x1F5DE, 0x1F5E1, 0x1F5E3, 0x1F5E8, 0x1F5EF, 0x1F5F3, 0x1F5FA,
+ 0x1F5FB, 0x1F5FC, 0x1F5FD, 0x1F5FE, 0x1F5FF, 0x1F600, 0x1F601, 0x1F602, 0x1F603, 0x1F604,
+ 0x1F605, 0x1F606, 0x1F607, 0x1F608, 0x1F609, 0x1F60A, 0x1F60B, 0x1F60C, 0x1F60D, 0x1F60E,
+ 0x1F60F, 0x1F610, 0x1F611, 0x1F612, 0x1F613, 0x1F614, 0x1F615, 0x1F616, 0x1F617, 0x1F618,
+ 0x1F619, 0x1F61A, 0x1F61B, 0x1F61C, 0x1F61D, 0x1F61E, 0x1F61F, 0x1F620, 0x1F621, 0x1F622,
+ 0x1F623, 0x1F624, 0x1F625, 0x1F626, 0x1F627, 0x1F628, 0x1F629, 0x1F62A, 0x1F62B, 0x1F62C,
+ 0x1F62D, 0x1F62E, 0x1F62F, 0x1F630, 0x1F631, 0x1F632, 0x1F633, 0x1F634, 0x1F635, 0x1F636,
+ 0x1F637, 0x1F638, 0x1F639, 0x1F63A, 0x1F63B, 0x1F63C, 0x1F63D, 0x1F63E, 0x1F63F, 0x1F640,
+ 0x1F641, 0x1F642, 0x1F643, 0x1F644, 0x1F645, 0x1F646, 0x1F647, 0x1F648, 0x1F649, 0x1F64A,
+ 0x1F64B, 0x1F64C, 0x1F64D, 0x1F64E, 0x1F64F, 0x1F680, 0x1F681, 0x1F682, 0x1F683, 0x1F684,
+ 0x1F685, 0x1F686, 0x1F687, 0x1F688, 0x1F689, 0x1F68A, 0x1F68B, 0x1F68C, 0x1F68D, 0x1F68E,
+ 0x1F68F, 0x1F690, 0x1F691, 0x1F692, 0x1F693, 0x1F694, 0x1F695, 0x1F696, 0x1F697, 0x1F698,
+ 0x1F699, 0x1F69A, 0x1F69B, 0x1F69C, 0x1F69D, 0x1F69E, 0x1F69F, 0x1F6A0, 0x1F6A1, 0x1F6A2,
+ 0x1F6A3, 0x1F6A4, 0x1F6A5, 0x1F6A6, 0x1F6A7, 0x1F6A8, 0x1F6A9, 0x1F6AA, 0x1F6AB, 0x1F6AC,
+ 0x1F6AD, 0x1F6AE, 0x1F6AF, 0x1F6B0, 0x1F6B1, 0x1F6B2, 0x1F6B3, 0x1F6B4, 0x1F6B5, 0x1F6B6,
+ 0x1F6B7, 0x1F6B8, 0x1F6B9, 0x1F6BA, 0x1F6BB, 0x1F6BC, 0x1F6BD, 0x1F6BE, 0x1F6BF, 0x1F6C0,
+ 0x1F6C1, 0x1F6C2, 0x1F6C3, 0x1F6C4, 0x1F6C5, 0x1F6CB, 0x1F6CC, 0x1F6CD, 0x1F6CE, 0x1F6CF,
+ 0x1F6D0, 0x1F6D1, 0x1F6D2, 0x1F6E0, 0x1F6E1, 0x1F6E2, 0x1F6E3, 0x1F6E4, 0x1F6E5, 0x1F6E9,
+ 0x1F6EB, 0x1F6EC, 0x1F6F0, 0x1F6F3, 0x1F6F4, 0x1F6F5, 0x1F6F6, 0x1F910, 0x1F911, 0x1F912,
+ 0x1F913, 0x1F914, 0x1F915, 0x1F916, 0x1F917, 0x1F918, 0x1F919, 0x1F91A, 0x1F91B, 0x1F91C,
+ 0x1F91D, 0x1F91E, 0x1F920, 0x1F921, 0x1F922, 0x1F923, 0x1F924, 0x1F925, 0x1F926, 0x1F927,
+ 0x1F930, 0x1F933, 0x1F934, 0x1F935, 0x1F936, 0x1F937, 0x1F938, 0x1F939, 0x1F93A, 0x1F93B,
+ 0x1F93C, 0x1F93D, 0x1F93E, 0x1F940, 0x1F941, 0x1F942, 0x1F943, 0x1F944, 0x1F945, 0x1F946,
+ 0x1F947, 0x1F948, 0x1F949, 0x1F94A, 0x1F94B, 0x1F950, 0x1F951, 0x1F952, 0x1F953, 0x1F954,
+ 0x1F955, 0x1F956, 0x1F957, 0x1F958, 0x1F959, 0x1F95A, 0x1F95B, 0x1F95C, 0x1F95D, 0x1F95E,
+ 0x1F980, 0x1F981, 0x1F982, 0x1F983, 0x1F984, 0x1F985, 0x1F986, 0x1F987, 0x1F988, 0x1F989,
+ 0x1F98A, 0x1F98B, 0x1F98C, 0x1F98D, 0x1F98E, 0x1F98F, 0x1F990, 0x1F991, 0x1F9C0
+ };
+
+ // See http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
private static int[] EMOJI_MODIFIER_BASE = {
0x261D, 0x26F9, 0x270A, 0x270B, 0x270C, 0x270D, 0x1F385, 0x1F3C3, 0x1F3C4, 0x1F3CA,
0x1F3CB, 0x1F442, 0x1F443, 0x1F446, 0x1F447, 0x1F448, 0x1F449, 0x1F44A, 0x1F44B, 0x1F44C,
@@ -62,9 +178,9 @@
return Arrays.binarySearch(EMOJI_MODIFIER_BASE, codePoint) >= 0;
}
- // Returns true if the character appears before or after zwj in a zwj emoji sequence.
- public static boolean isZwjEmoji(int codePoint) {
- return Arrays.binarySearch(ZWJ_EMOJI, codePoint) >= 0;
+ // Returns true if the character has Emoji property.
+ public static boolean isEmoji(int codePoint) {
+ return Arrays.binarySearch(EMOJI_LIST, codePoint) >= 0;
}
// Returns true if the character can be a base character of COMBINING ENCLOSING KEYCAP.
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index e93e58d..3770a45 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -162,14 +162,14 @@
state = STATE_LF;
} else if (isVariationSelector(codePoint)) {
state = STATE_BEFORE_VS;
- } else if (Emoji.isZwjEmoji(codePoint)) {
- state = STATE_BEFORE_ZWJ_EMOJI;
} else if (Emoji.isRegionalIndicatorSymbol(codePoint)) {
state = STATE_ODD_NUMBERED_RIS;
} else if (Emoji.isEmojiModifier(codePoint)) {
state = STATE_BEFORE_EMOJI_MODIFIER;
} else if (codePoint == Emoji.COMBINING_ENCLOSING_KEYCAP) {
state = STATE_BEFORE_KEYCAP;
+ } else if (Emoji.isEmoji(codePoint)) {
+ state = STATE_BEFORE_ZWJ_EMOJI;
} else {
state = STATE_FINISHED;
}
@@ -230,7 +230,7 @@
state = STATE_FINISHED;
break;
case STATE_BEFORE_VS:
- if (Emoji.isZwjEmoji(codePoint)) {
+ if (Emoji.isEmoji(codePoint)) {
deleteCharCount += Character.charCount(codePoint);
state = STATE_BEFORE_ZWJ_EMOJI;
break;
@@ -250,7 +250,7 @@
}
break;
case STATE_BEFORE_ZWJ:
- if (Emoji.isZwjEmoji(codePoint)) {
+ if (Emoji.isEmoji(codePoint)) {
deleteCharCount += Character.charCount(codePoint) + 1; // +1 for ZWJ.
state = STATE_BEFORE_ZWJ_EMOJI;
} else if (isVariationSelector(codePoint)) {
@@ -261,7 +261,7 @@
}
break;
case STATE_BEFORE_VS_AND_ZWJ:
- if (Emoji.isZwjEmoji(codePoint)) {
+ if (Emoji.isEmoji(codePoint)) {
// +1 for ZWJ.
deleteCharCount += lastSeenVSCharCount + 1 + Character.charCount(codePoint);
lastSeenVSCharCount = 0;
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ef50fdc..7da849a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -102,13 +102,13 @@
public @interface ScalingMode {}
// From system/window.h
/** @hide */
- static final int SCALING_MODE_FREEZE = 0;
+ public static final int SCALING_MODE_FREEZE = 0;
/** @hide */
- static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
+ public static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
/** @hide */
- static final int SCALING_MODE_SCALE_CROP = 2;
+ public static final int SCALING_MODE_SCALE_CROP = 2;
/** @hide */
- static final int SCALING_MODE_NO_SCALE_CROP = 3;
+ public static final int SCALING_MODE_NO_SCALE_CROP = 3;
/** @hide */
@IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index c30ede3..dc9014b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -85,6 +85,8 @@
IBinder displayToken, int mode);
private static native void nativeDeferTransactionUntil(long nativeObject,
IBinder handle, long frame);
+ private static native void nativeSetOverrideScalingMode(long nativeObject,
+ int scalingMode);
private static native IBinder nativeGetHandle(long nativeObject);
@@ -376,6 +378,11 @@
nativeDeferTransactionUntil(mNativeObject, handle, frame);
}
+ public void setOverrideScalingMode(int scalingMode) {
+ checkNotReleased();
+ nativeSetOverrideScalingMode(mNativeObject, scalingMode);
+ }
+
public IBinder getHandle() {
return nativeGetHandle(mNativeObject);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e9ca623..9e4f26f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2716,11 +2716,11 @@
mAttachInfo.mHardwareRenderer.setStopped(false);
}
- mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
-
if (updated) {
requestDrawWindow();
}
+
+ mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index b6516c8..2b54875 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -107,7 +107,29 @@
throw new IllegalArgumentException(canvas.getClass().getName()
+ " is not a DisplayList canvas");
}
- ((DisplayListCanvas) canvas).callDrawGLFunction2(nativeDrawGLFunctor);
+ ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
+ }
+
+ /**
+ * Calls the function specified with the nativeDrawGLFunctor functor pointer. This
+ * functionality is used by the WebView for calling into their renderer from the
+ * framework display lists.
+ *
+ * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()})
+ * @param nativeDrawGLFunctor the pointer to the native functor that implements
+ * system/core/include/utils/Functor.h
+ * @param releasedRunnable Called when this nativeDrawGLFunctor is no longer referenced by this
+ * canvas, so is safe to be destroyed.
+ * @throws IllegalArgumentException if the canvas is not hardware accelerated
+ */
+ public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
+ @Nullable Runnable releasedRunnable) {
+ if (!(canvas instanceof DisplayListCanvas)) {
+ // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
+ throw new IllegalArgumentException(canvas.getClass().getName()
+ + " is not a DisplayList canvas");
+ }
+ ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
}
/**
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 10afdb8..250d9b7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -60,6 +60,7 @@
import android.util.Xml;
import android.view.Display;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
@@ -1092,7 +1093,7 @@
public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
+ computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
- out.writeInt(mCount);
+ out.writeInt(computeCurrentCountLocked());
out.writeInt(mLoadedCount);
out.writeInt(mUnpluggedCount);
out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
@@ -1109,7 +1110,7 @@
+ " old mUnpluggedCount=" + mUnpluggedCount);
}
mUnpluggedTime = computeRunTimeLocked(baseRealtime);
- mUnpluggedCount = mCount;
+ mUnpluggedCount = computeCurrentCountLocked();
if (DEBUG && mType < 0) {
Log.v(TAG, "unplug #" + mType
+ ": new mUnpluggedTime=" + mUnpluggedTime
@@ -1192,7 +1193,7 @@
public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
out.writeLong(runTime);
- out.writeInt(mCount);
+ out.writeInt(computeCurrentCountLocked());
}
public void readSummaryFromParcelLocked(Parcel in) {
@@ -1249,7 +1250,8 @@
*/
int mUpdateVersion;
- SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) {
+ @VisibleForTesting
+ public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) {
super(clocks, 0, timeBase, in);
mCurrentReportedCount = in.readInt();
mUnpluggedReportedCount = in.readInt();
@@ -1259,7 +1261,8 @@
mTimeBaseRunning = timeBase.isRunning();
}
- SamplingTimer(Clocks clocks, TimeBase timeBase, boolean trackReportedValues) {
+ @VisibleForTesting
+ public SamplingTimer(Clocks clocks, TimeBase timeBase, boolean trackReportedValues) {
super(clocks, 0, timeBase);
mTrackingReportedValues = trackReportedValues;
mTimeBaseRunning = timeBase.isRunning();
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index d831902..b7e5718 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -34,9 +34,11 @@
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Date;
import java.util.StringTokenizer;
public class ProcessCpuTracker {
@@ -147,6 +149,9 @@
private long mCurrentSampleRealTime;
private long mLastSampleRealTime;
+ private long mCurrentSampleWallTime;
+ private long mLastSampleWallTime;
+
private long mBaseUserTime;
private long mBaseSystemTime;
private long mBaseIoWaitTime;
@@ -305,6 +310,7 @@
final long nowUptime = SystemClock.uptimeMillis();
final long nowRealtime = SystemClock.elapsedRealtime();
+ final long nowWallTime = System.currentTimeMillis();
final long[] sysCpu = mSystemCpuData;
if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
@@ -367,6 +373,8 @@
mCurrentSampleTime = nowUptime;
mLastSampleRealTime = mCurrentSampleRealTime;
mCurrentSampleRealTime = nowRealtime;
+ mLastSampleWallTime = mCurrentSampleWallTime;
+ mCurrentSampleWallTime = nowWallTime;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
try {
@@ -710,6 +718,8 @@
}
final public String printCurrentState(long now) {
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
buildWorkingProcs();
StringWriter sw = new StringWriter();
@@ -727,6 +737,11 @@
pw.print(mCurrentSampleTime-now);
pw.print("ms later");
}
+ pw.print(" (");
+ pw.print(sdf.format(new Date(mLastSampleWallTime)));
+ pw.print(" to ");
+ pw.print(sdf.format(new Date(mCurrentSampleWallTime)));
+ pw.print(")");
long sampleTime = mCurrentSampleTime - mLastSampleTime;
long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index b1598e7..b781fd4 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,8 +16,6 @@
package com.android.internal.policy;
-import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
-
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -102,9 +100,6 @@
mOldSystemInsets.set(systemInsets);
mOldStableInsets.set(stableInsets);
mResizeMode = resizeMode;
- synchronized (this) {
- redrawLocked(initialBounds, fullscreen, mSystemInsets, mStableInsets);
- }
// Kick off our draw thread.
start();
@@ -160,7 +155,7 @@
mSystemInsets.set(systemInsets);
mStableInsets.set(stableInsets);
// Notify of a bounds change.
- pingRenderLocked();
+ pingRenderLocked(false /* drawImmediate */);
}
}
@@ -172,7 +167,7 @@
if (mRenderer != null) {
// Enforce a window redraw.
mOldTargetRect.set(0, 0, 0, 0);
- pingRenderLocked();
+ pingRenderLocked(false /* drawImmediate */);
}
}
}
@@ -197,7 +192,7 @@
mRenderer = null;
// Exit the renderer loop.
- pingRenderLocked();
+ pingRenderLocked(false /* drawImmediate */);
}
}
}
@@ -208,9 +203,6 @@
Looper.prepare();
synchronized (this) {
mChoreographer = Choreographer.getInstance();
-
- // Draw at least once.
- mChoreographer.postFrameCallback(this);
}
Looper.loop();
} finally {
@@ -236,18 +228,22 @@
Looper.myLooper().quit();
return;
}
- mNewTargetRect.set(mTargetRect);
- if (!mNewTargetRect.equals(mOldTargetRect)
- || mOldFullscreen != mFullscreen
- || !mStableInsets.equals(mOldStableInsets)
- || !mSystemInsets.equals(mOldSystemInsets)
- || mReportNextDraw) {
- mOldFullscreen = mFullscreen;
- mOldTargetRect.set(mNewTargetRect);
- mOldSystemInsets.set(mSystemInsets);
- mOldStableInsets.set(mStableInsets);
- redrawLocked(mNewTargetRect, mFullscreen, mSystemInsets, mStableInsets);
- }
+ doFrameUncheckedLocked();
+ }
+ }
+
+ private void doFrameUncheckedLocked() {
+ mNewTargetRect.set(mTargetRect);
+ if (!mNewTargetRect.equals(mOldTargetRect)
+ || mOldFullscreen != mFullscreen
+ || !mStableInsets.equals(mOldStableInsets)
+ || !mSystemInsets.equals(mOldSystemInsets)
+ || mReportNextDraw) {
+ mOldFullscreen = mFullscreen;
+ mOldTargetRect.set(mNewTargetRect);
+ mOldSystemInsets.set(mSystemInsets);
+ mOldStableInsets.set(mStableInsets);
+ redrawLocked(mNewTargetRect, mFullscreen, mSystemInsets, mStableInsets);
}
}
@@ -288,7 +284,7 @@
synchronized (this) {
mReportNextDraw = reportNextDraw;
mOldTargetRect.set(0, 0, 0, 0);
- pingRenderLocked();
+ pingRenderLocked(true /* drawImmediate */);
}
}
@@ -403,10 +399,14 @@
* Sends a message to the renderer to wake up and perform the next action which can be
* either the next rendering or the self destruction if mRenderer is null.
* Note: This call must be synchronized.
+ *
+ * @param drawImmediate if we should draw immediately instead of scheduling a frame
*/
- private void pingRenderLocked() {
- if (mChoreographer != null) {
+ private void pingRenderLocked(boolean drawImmediate) {
+ if (mChoreographer != null && !drawImmediate) {
mChoreographer.postFrameCallback(this);
+ } else {
+ doFrameUncheckedLocked();
}
}
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 669e1ef..b8bc161 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -330,6 +330,14 @@
return snapTarget;
}
+ public boolean isFirstSplitTargetAvailable() {
+ return mFirstSplitTarget != mMiddleTarget;
+ }
+
+ public boolean isLastSplitTargetAvailable() {
+ return mLastSplitTarget != mMiddleTarget;
+ }
+
/**
* Cycles through all non-dismiss targets with a stepping of {@param increment}. It moves left
* if {@param increment} is negative and moves right otherwise.
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 994bdeb..3d05422 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,7 +41,6 @@
void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
boolean showImeSwitcher);
void expandSettingsPanel(String subPanel);
- void setCurrentUser(int newUserId);
// ---- Methods below are for use by the status bar policy services ----
// You need the STATUS_BAR_SERVICE permission
@@ -63,48 +62,6 @@
in NotificationVisibility[] noLongerVisibleKeys);
void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded);
void setSystemUiVisibility(int vis, int mask, String cause);
- void setWindowState(int window, int state);
-
- void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
- void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
- void toggleRecentApps();
- void preloadRecentApps();
- void cancelPreloadRecentApps();
-
- void toggleKeyboardShortcutsMenu(int deviceId);
-
- /**
- * Notifies the status bar that an app transition is pending to delay applying some flags with
- * visual impact until {@link #appTransitionReady} is called.
- */
- void appTransitionPending();
-
- /**
- * Notifies the status bar that a pending app transition has been cancelled.
- */
- void appTransitionCancelled();
-
- /**
- * Notifies the status bar that an app transition is now being executed.
- *
- * @param statusBarAnimationsStartTime the desired start time for all visual animations in the
- * status bar caused by this app transition in uptime millis
- * @param statusBarAnimationsDuration the duration for all visual animations in the status
- * bar caused by this app transition in millis
- */
- void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
-
- void startAssist(in Bundle args);
-
- /**
- * Request picture-in-picture.
- *
- * <p>
- * This is called when an user presses picture-in-picture key or equivalent.
- * TV device may start picture-in-picture from foreground activity if there's none.
- * Picture-in-picture overlay menu will be shown instead otherwise.
- */
- void requestTvPictureInPicture();
void addTile(in ComponentName tile);
void remTile(in ComponentName tile);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index d8233a0..0590134 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -597,6 +597,13 @@
ctrl->deferTransactionUntil(handle, frameNumber);
}
+static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
+ jint scalingMode) {
+ auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+
+ ctrl->setOverrideScalingMode(scalingMode);
+}
+
static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -676,6 +683,8 @@
(void*)nativeSetDisplayPowerMode },
{"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
(void*)nativeDeferTransactionUntil },
+ {"nativeSetOverrideScalingMode", "(JI)V",
+ (void*)nativeSetOverrideScalingMode },
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
(void*)nativeGetHandle }
};
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index e1b305f..a9fa4dd 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -420,10 +420,6 @@
// Regional indicator symbol + ZERO WIDTH JOINER
state.setByString("U+1F1FA U+200D U+1F469 |");
backspace(state, 0);
- state.assertEquals("U+1F1FA U+200D |");
- backspace(state, 0);
- state.assertEquals("U+1F1FA |");
- backspace(state, 0);
state.assertEquals("|");
// Start with ZERO WIDTH JOINER + emoji modifier
@@ -452,9 +448,7 @@
// Emoji modifier + ZERO WIDTH JOINER
state.setByString("U+1F466 U+1F3FB U+200D U+1F469 |");
backspace(state, 0);
- state.assertEquals("U+1F466 U+1F3FB U+200D |");
- backspace(state, 0);
- state.assertEquals("U+1F466 U+1F3FB |");
+ state.assertEquals("U+1F466 |");
backspace(state, 0);
state.assertEquals("|");
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
new file mode 100644
index 0000000..51d41a4
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.internal.os;
+
+import android.os.BatteryStats;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+
+import junit.framework.TestCase;
+
+public class BatteryStatsSamplingTimerTest extends TestCase {
+
+ @SmallTest
+ public void testSampleTimerSummaryParceling() throws Exception {
+ final MockClocks clocks = new MockClocks();
+ clocks.realtime = 0;
+ clocks.uptime = 0;
+
+ final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
+ timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+ BatteryStatsImpl.SamplingTimer timer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase,
+ true);
+
+ // Start running on battery.
+ timeBase.setRunning(true, clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+ // The first update on battery consumes the values as a way of starting cleanly.
+ timer.addCurrentReportedTotalTime(10);
+ timer.addCurrentReportedCount(1);
+
+ timer.addCurrentReportedTotalTime(10);
+ timer.addCurrentReportedCount(1);
+
+ clocks.realtime = 20;
+ clocks.uptime = 20;
+
+ assertEquals(10, timer.getTotalTimeLocked(clocks.elapsedRealtime(),
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+
+ // Grab a summary parcel while on battery.
+ final Parcel onBatterySummaryParcel = Parcel.obtain();
+ timer.writeSummaryFromParcelLocked(onBatterySummaryParcel, clocks.elapsedRealtime() * 1000);
+ onBatterySummaryParcel.setDataPosition(0);
+
+ // Stop running on battery.
+ timeBase.setRunning(false, clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+ assertEquals(10, timer.getTotalTimeLocked(clocks.elapsedRealtime(),
+ BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+
+ // Grab a summary parcel while not on battery.
+ final Parcel offBatterySummaryParcel = Parcel.obtain();
+ timer.writeSummaryFromParcelLocked(offBatterySummaryParcel,
+ clocks.elapsedRealtime() * 1000);
+ offBatterySummaryParcel.setDataPosition(0);
+
+ // Read the on battery summary from the parcel.
+ BatteryStatsImpl.SamplingTimer unparceledTimer = new BatteryStatsImpl.SamplingTimer(
+ clocks, timeBase, true);
+ unparceledTimer.readSummaryFromParcelLocked(onBatterySummaryParcel);
+
+ assertEquals(10, unparceledTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+
+ // Read the off battery summary from the parcel.
+ unparceledTimer = new BatteryStatsImpl.SamplingTimer(clocks, timeBase, true);
+ unparceledTimer.readSummaryFromParcelLocked(offBatterySummaryParcel);
+
+ assertEquals(10, unparceledTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, unparceledTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
index 1c3cd38..5fd8225 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
@@ -16,20 +16,13 @@
package com.android.internal.os;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-
import android.os.BatteryStats;
import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
+import android.support.test.filters.SmallTest;
import junit.framework.Assert;
import junit.framework.TestCase;
-import com.android.internal.os.BatteryStatsImpl;
-
/**
* Provides test cases for android.os.BatteryStats.
*/
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 05aa53c..78bcbbc 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -5,6 +5,7 @@
@RunWith(Suite.class)
@Suite.SuiteClasses({
+ BatteryStatsSamplingTimerTest.class,
BatteryStatsServTest.class,
BatteryStatsTimeBaseTest.class,
BatteryStatsTimerTest.class,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
index ab92f15..3190d9e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
@@ -18,11 +18,10 @@
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
import android.os.BatteryStats;
import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
import android.util.Log;
import junit.framework.Assert;
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
index 3e17fcb..98d0f7f 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
@@ -18,8 +18,7 @@
import android.os.BatteryStats;
import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
+import android.support.test.filters.SmallTest;
import android.util.StringBuilderPrinter;
import junit.framework.Assert;
@@ -148,7 +147,7 @@
timer.onTimeStarted(10, 20, 50);
Assert.assertEquals(50, timer.lastComputeRunTimeRealtime);
Assert.assertEquals(4, timer.getUnpluggedTime());
- Assert.assertEquals(0, timer.getUnpluggedCount());
+ Assert.assertEquals(3000, timer.getUnpluggedCount());
// Test that stopping the timer updates mTotalTime and mCount
timer.nextComputeRunTime = 17;
@@ -168,15 +167,16 @@
// Test write then read
TestTimer timer1 = new TestTimer(clocks, 0, timeBase);
timer1.setCount(1);
- timer1.setLoadedCount(2);
- timer1.setLastCount(3);
- timer1.setUnpluggedCount(4);
+ timer1.setLoadedCount(3);
+ timer1.setLastCount(4);
+ timer1.setUnpluggedCount(5);
timer1.setTotalTime(9223372036854775807L);
timer1.setLoadedTime(9223372036854775806L);
timer1.setLastTime(9223372036854775805L);
timer1.setUnpluggedTime(9223372036854775804L);
timer1.setTimeBeforeMark(9223372036854775803L);
timer1.nextComputeRunTime = 201;
+ timer1.nextComputeCurrentCount = 2;
Parcel parcel = Parcel.obtain();
Timer.writeTimerToParcel(parcel, timer1, 77);
@@ -185,10 +185,10 @@
Assert.assertTrue("parcel null object", parcel.readInt() != 0);
TestTimer timer2 = new TestTimer(clocks, 0, timeBase, parcel);
- Assert.assertEquals(1, timer2.getCount());
- Assert.assertEquals(2, timer2.getLoadedCount());
+ Assert.assertEquals(2, timer2.getCount()); // from computeTotalCountLocked()
+ Assert.assertEquals(3, timer2.getLoadedCount());
Assert.assertEquals(0, timer2.getLastCount()); // NOT saved
- Assert.assertEquals(4, timer2.getUnpluggedCount());
+ Assert.assertEquals(5, timer2.getUnpluggedCount());
Assert.assertEquals(201, timer2.getTotalTime()); // from computeRunTimeLocked()
Assert.assertEquals(9223372036854775806L, timer2.getLoadedTime());
Assert.assertEquals(0, timer2.getLastTime()); // NOT saved
@@ -309,6 +309,7 @@
Parcel parcel = Parcel.obtain();
timer1.nextComputeRunTime = 9223372036854775800L;
+ timer1.nextComputeCurrentCount = 1;
timer1.writeSummaryFromParcelLocked(parcel, 201);
Assert.assertEquals(40, timer1.lastComputeRunTimeRealtime);
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 35385eb..6762bea 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -310,6 +310,15 @@
@Override
public boolean setVisible(boolean visible, boolean restart) {
+ if (mAnimatorSet.isInfinite() && mAnimatorSet.isStarted()) {
+ if (visible) {
+ // Resume the infinite animation when the drawable becomes visible again.
+ mAnimatorSet.resume();
+ } else {
+ // Pause the infinite animation once the drawable is no longer visible.
+ mAnimatorSet.pause();
+ }
+ }
mAnimatedVectorState.mVectorDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
}
@@ -815,6 +824,9 @@
void onDraw(Canvas canvas);
boolean isStarted();
boolean isRunning();
+ boolean isInfinite();
+ void pause();
+ void resume();
}
private static class VectorDrawableAnimatorUI implements VectorDrawableAnimator {
@@ -825,6 +837,7 @@
// Caching the listener in the case when listener operation is called before the mSet is
// setup by init().
private ArrayList<AnimatorListener> mListenerArray = null;
+ private boolean mIsInfinite = false;
VectorDrawableAnimatorUI(@NonNull AnimatedVectorDrawable drawable) {
mDrawable = drawable;
@@ -840,6 +853,7 @@
// Keep a deep copy of the set, such that set can be still be constantly representing
// the static content from XML file.
mSet = set.clone();
+ mIsInfinite = mSet.getTotalDuration() == Animator.DURATION_INFINITE;
// If there are listeners added before calling init(), now they should be setup.
if (mListenerArray != null && !mListenerArray.isEmpty()) {
@@ -934,6 +948,27 @@
return mSet != null && mSet.isRunning();
}
+ @Override
+ public boolean isInfinite() {
+ return mIsInfinite;
+ }
+
+ @Override
+ public void pause() {
+ if (mSet == null) {
+ return;
+ }
+ mSet.pause();
+ }
+
+ @Override
+ public void resume() {
+ if (mSet == null) {
+ return;
+ }
+ mSet.resume();
+ }
+
private void invalidateOwningView() {
mDrawable.invalidateSelf();
}
@@ -956,6 +991,7 @@
private boolean mStarted = false;
private boolean mInitialized = false;
private boolean mIsReversible = false;
+ private boolean mIsInfinite = false;
// This needs to be set before parsing starts.
private boolean mShouldIgnoreInvalidAnim;
// TODO: Consider using NativeAllocationRegistery to track native allocation
@@ -983,6 +1019,7 @@
mShouldIgnoreInvalidAnim = shouldIgnoreInvalidAnimation();
parseAnimatorSet(set, 0);
mInitialized = true;
+ mIsInfinite = set.getTotalDuration() == Animator.DURATION_INFINITE;
// Check reversible.
mIsReversible = true;
@@ -1408,6 +1445,21 @@
}
}
+ @Override
+ public boolean isInfinite() {
+ return mIsInfinite;
+ }
+
+ @Override
+ public void pause() {
+ // TODO: Implement pause for Animator On RT.
+ }
+
+ @Override
+ public void resume() {
+ // TODO: Implement resume for Animator On RT.
+ }
+
private void onAnimationEnd(int listenerId) {
if (listenerId != mLastListenerId) {
return;
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b557dc4..4e9b59f 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -111,6 +111,8 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <!-- Permission needed to rename bugreport notifications (so they're not shown as Shell) -->
+ <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 346ae20..ec39998 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -62,6 +62,7 @@
import android.content.res.Configuration;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -204,6 +205,8 @@
*/
private boolean mTakingScreenshot;
+ private static final Bundle sNotificationBundle = new Bundle();
+
@Override
public void onCreate() {
mContext = getApplicationContext();
@@ -979,7 +982,13 @@
}
private static Notification.Builder newBaseNotification(Context context) {
+ if (sNotificationBundle.isEmpty()) {
+ // Rename notifcations from "Shell" to "Android System"
+ sNotificationBundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+ context.getString(com.android.internal.R.string.android_system_label));
+ }
return new Notification.Builder(context)
+ .addExtras(sNotificationBundle)
.setCategory(Notification.CATEGORY_SYSTEM)
.setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
.setLocalOnly(true)
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index 55d7fab..68129ce 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -45,7 +45,7 @@
android:layout_gravity="end"
android:minWidth="88dp"
android:textAppearance="@style/TextAppearance.QS.DetailButton"
- android:textColor="#4DFFFFFF"
+ android:textColor="#64FFFFFF"
android:focusable="true"
android:text="@string/qs_edit" />
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 9697ea6..94d79f2 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -63,9 +63,10 @@
<item type="id" name="is_clicked_heads_up_tag" />
<!-- Accessibility actions for the docked stack divider -->
- <item type="id" name="action_move_left" />
- <item type="id" name="action_move_right" />
- <item type="id" name="action_move_up" />
- <item type="id" name="action_move_down" />
+ <item type="id" name="action_move_tl_full" />
+ <item type="id" name="action_move_tl_70" />
+ <item type="id" name="action_move_tl_50" />
+ <item type="id" name="action_move_tl_30" />
+ <item type="id" name="action_move_rb_full" />
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a03aa28..8e3ea4c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1580,17 +1580,27 @@
<!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
<string name="accessibility_divider">Split-screen divider</string>
- <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_move_down">Move down</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_full">Left full screen</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 70% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_70">Left 70%</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 50% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_50">Left 50%</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 30% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_30">Left 30%</string>
+ <!-- Accessibility action for moving docked stack divider to make the right screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_right_full">Right full screen</string>
- <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_move_up">Move up</string>
-
- <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_move_left">Move left</string>
-
- <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_move_right">Move right</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_full">Top full screen</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 70% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_70">Top 70%</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 50% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_50">Top 50%</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 30% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_30">Top 30%</string>
+ <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_bottom_full">Bottom full screen</string>
<!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_tile_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>, <xliff:g id="tile_name" example="Wi-Fi">%2$s</xliff:g>. Double tap to edit.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index d12ab29..cecbfcb 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -317,8 +317,8 @@
mResizedView = null;
mWatchingForPull = false;
}
- mInitialTouchY = ev.getY();
- mInitialTouchX = ev.getX();
+ mInitialTouchY = ev.getRawY();
+ mInitialTouchX = ev.getRawX();
break;
case MotionEvent.ACTION_CANCEL:
@@ -412,8 +412,8 @@
mWatchingForPull = mScrollAdapter != null &&
isInside(mScrollAdapter.getHostView(), x, y);
mResizedView = findView(x, y);
- mInitialTouchX = ev.getX();
- mInitialTouchY = ev.getY();
+ mInitialTouchX = ev.getRawX();
+ mInitialTouchY = ev.getRawY();
break;
case MotionEvent.ACTION_MOVE: {
if (mWatchingForPull) {
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 1306284..c72f5d2 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -29,6 +29,7 @@
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.opengl.GLUtils;
+import android.os.AsyncTask;
import android.os.SystemProperties;
import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
@@ -155,6 +156,8 @@
private int mLastRequestedWidth = -1;
private int mLastRequestedHeight = -1;
+ private AsyncTask<Void, Void, Bitmap> mLoader;
+ private boolean mNeedsDrawAfterLoadingWallpaper;
public DrawableEngine() {
super();
@@ -184,10 +187,9 @@
super.onCreate(surfaceHolder);
mDefaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay();
-
- updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo());
-
setOffsetNotificationsEnabled(false);
+
+ updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo(), false /* forDraw */);
}
@Override
@@ -197,17 +199,19 @@
mWallpaperManager.forgetLoadedWallpaper();
}
- void updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo) {
+ boolean updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo,
+ boolean forDraw) {
+ boolean hasWallpaper = true;
+
// Load background image dimensions, if we haven't saved them yet
if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
// Need to load the image to get dimensions
mWallpaperManager.forgetLoadedWallpaper();
- updateWallpaperLocked();
- if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
- // Default to the display size if we can't find the dimensions
- mBackgroundWidth = displayInfo.logicalWidth;
- mBackgroundHeight = displayInfo.logicalHeight;
+ loadWallpaper(forDraw);
+ if (DEBUG) {
+ Log.d(TAG, "Reloading, redoing updateSurfaceSize later.");
}
+ hasWallpaper = false;
}
// Force the wallpaper to cover the screen in both dimensions
@@ -224,6 +228,7 @@
} else {
surfaceHolder.setSizeFromLayout();
}
+ return hasWallpaper;
}
@Override
@@ -299,6 +304,7 @@
}
super.onSurfaceRedrawNeeded(holder);
+ mLastSurfaceHeight = mLastSurfaceWidth = -1;
drawFrame();
}
@@ -317,7 +323,9 @@
// should change
if (newRotation != mLastRotation) {
// Update surface size (if necessary)
- updateSurfaceSize(getSurfaceHolder(), displayInfo);
+ if (!updateSurfaceSize(getSurfaceHolder(), displayInfo, true /* forDraw */)) {
+ return; // had to reload wallpaper, will retry later
+ }
mRotationAtLastSurfaceSizeUpdate = newRotation;
mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth;
mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight;
@@ -339,8 +347,8 @@
}
mLastRotation = newRotation;
- // Load bitmap if it is not yet loaded or if it was loaded at a different size
- if (mBackground == null || surfaceDimensionsChanged) {
+ // Load bitmap if it is not yet loaded
+ if (mBackground == null) {
if (DEBUG) {
Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " +
mBackground + ", " +
@@ -349,20 +357,11 @@
dw + ", " + dh);
}
mWallpaperManager.forgetLoadedWallpaper();
- updateWallpaperLocked();
- if (mBackground == null) {
- if (DEBUG) {
- Log.d(TAG, "Unable to load bitmap");
- }
- return;
- }
+ loadWallpaper(true /* needDraw */);
if (DEBUG) {
- if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) {
- Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " +
- dw + ", " + dh + ", " + mBackground.getWidth() + ", " +
- mBackground.getHeight());
- }
+ Log.d(TAG, "Reloading, resuming draw later");
}
+ return;
}
// Center the scaled image
@@ -422,36 +421,77 @@
}
}
- private void updateWallpaperLocked() {
- Throwable exception = null;
- try {
- mBackground = null;
- mBackgroundWidth = -1;
- mBackgroundHeight = -1;
- mBackground = mWallpaperManager.getBitmap();
- mBackgroundWidth = mBackground.getWidth();
- mBackgroundHeight = mBackground.getHeight();
- } catch (RuntimeException e) {
- exception = e;
- } catch (OutOfMemoryError e) {
- exception = e;
- }
-
- if (exception != null) {
- mBackground = null;
- mBackgroundWidth = -1;
- mBackgroundHeight = -1;
- // Note that if we do fail at this, and the default wallpaper can't
- // be loaded, we will go into a cycle. Don't do a build where the
- // default wallpaper can't be loaded.
- Log.w(TAG, "Unable to load wallpaper!", exception);
- try {
- mWallpaperManager.clear();
- } catch (IOException ex) {
- // now we're really screwed.
- Log.w(TAG, "Unable reset to default wallpaper!", ex);
+ /**
+ * Loads the wallpaper on background thread and schedules updating the surface frame,
+ * and if {@param needsDraw} is set also draws a frame.
+ *
+ * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to
+ * the active request).
+ */
+ private void loadWallpaper(boolean needsDraw) {
+ mNeedsDrawAfterLoadingWallpaper |= needsDraw;
+ if (mLoader != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Skipping loadWallpaper, already in flight ");
}
+ return;
}
+ mLoader = new AsyncTask<Void, Void, Bitmap>() {
+ @Override
+ protected Bitmap doInBackground(Void... params) {
+ Throwable exception;
+ try {
+ return mWallpaperManager.getBitmap();
+ } catch (RuntimeException | OutOfMemoryError e) {
+ exception = e;
+ }
+
+ if (exception != null) {
+ // Note that if we do fail at this, and the default wallpaper can't
+ // be loaded, we will go into a cycle. Don't do a build where the
+ // default wallpaper can't be loaded.
+ Log.w(TAG, "Unable to load wallpaper!", exception);
+ try {
+ mWallpaperManager.clear();
+ } catch (IOException ex) {
+ // now we're really screwed.
+ Log.w(TAG, "Unable reset to default wallpaper!", ex);
+ }
+
+ try {
+ return mWallpaperManager.getBitmap();
+ } catch (RuntimeException | OutOfMemoryError e) {
+ Log.w(TAG, "Unable to load default wallpaper!", e);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap b) {
+ mBackground = null;
+ mBackgroundWidth = -1;
+ mBackgroundHeight = -1;
+
+ if (b != null) {
+ mBackground = b;
+ mBackgroundWidth = mBackground.getWidth();
+ mBackgroundHeight = mBackground.getHeight();
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "Wallpaper loaded: " + mBackground);
+ }
+ updateSurfaceSize(getSurfaceHolder(), getDefaultDisplayInfo(),
+ false /* forDraw */);
+ if (mNeedsDrawAfterLoadingWallpaper) {
+ drawFrame();
+ }
+
+ mLoader = null;
+ mNeedsDrawAfterLoadingWallpaper = false;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index eaafafa..94b2fdb 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -21,9 +21,9 @@
import android.view.View;
public interface RecentsComponent {
- void showRecents(boolean triggeredFromAltTab, boolean fromHome, View statusBarView);
+ void showRecents(boolean triggeredFromAltTab, boolean fromHome);
void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
- void toggleRecents(Display display, int layoutDirection, View statusBarView);
+ void toggleRecents(Display display);
void preloadRecents();
void cancelPreloadingRecents();
void showNextAffiliatedTask();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
index f619bfb..c8a2e17 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
@@ -16,11 +16,9 @@
package com.android.systemui;
-import android.app.ActivityManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
-import android.os.Process;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -43,15 +41,19 @@
SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
if (args == null || args.length == 0) {
for (SystemUI ui: services) {
- pw.println("dumping service: " + ui.getClass().getName());
- ui.dump(fd, pw, args);
+ if (ui != null) {
+ pw.println("dumping service: " + ui.getClass().getName());
+ ui.dump(fd, pw, args);
+ }
}
} else {
String svc = args[0];
for (SystemUI ui: services) {
- String name = ui.getClass().getName();
- if (name.endsWith(svc)) {
- ui.dump(fd, pw, args);
+ if (ui != null) {
+ String name = ui.getClass().getName();
+ if (name.endsWith(svc)) {
+ ui.dump(fd, pw, args);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 0798590..1ac5992 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -27,6 +27,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityManager;
import com.android.systemui.analytics.DataCollector;
import com.android.systemui.statusbar.StatusBarState;
@@ -60,6 +61,7 @@
private final SensorManager mSensorManager;
private final DataCollector mDataCollector;
private final HumanInteractionClassifier mHumanInteractionClassifier;
+ private final AccessibilityManager mAccessibilityManager;
private static FalsingManager sInstance = null;
@@ -78,7 +80,8 @@
private FalsingManager(Context context) {
mContext = context;
- mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+ mSensorManager = mContext.getSystemService(SensorManager.class);
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mDataCollector = DataCollector.getInstance(mContext);
mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
mScreenOn = context.getSystemService(PowerManager.class).isInteractive();
@@ -177,6 +180,11 @@
.toString());
}
}
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
+ // Touch exploration triggers false positives in the classifier and
+ // already sufficiently prevents false unlocks.
+ return false;
+ }
return mHumanInteractionClassifier.isFalseTouch();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
index 7ce9384..9403664 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
@@ -27,9 +27,9 @@
void preloadRecents();
void cancelPreloadingRecents();
void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate,
- boolean reloadTasks, boolean fromHome);
+ boolean reloadTasks, boolean fromHome, int recentsGrowTarget);
void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
- void toggleRecents();
+ void toggleRecents(int recentsGrowTarget);
void onConfigurationChanged();
void dockTopTask(int topTaskId, int dragMode, int stackCreateMode,
in Rect initialBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index bb709c5..630cb66 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -37,9 +37,7 @@
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
-import android.util.MutableBoolean;
import android.view.Display;
-import android.view.View;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
@@ -59,6 +57,7 @@
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.tv.RecentsTvImpl;
+import com.android.systemui.stackdivider.Divider;
import java.util.ArrayList;
@@ -75,6 +74,7 @@
public final static int EVENT_BUS_PRIORITY = 1;
public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
+ public final static int RECENTS_GROW_TARGET_INVALID = -1;
// Purely for experimentation
private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
@@ -238,7 +238,7 @@
* Shows the Recents.
*/
@Override
- public void showRecents(boolean triggeredFromAltTab, boolean fromHome, View statusBarView) {
+ public void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
@@ -249,10 +249,12 @@
return;
}
+ int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
+
int currentUser = sSystemServicesProxy.getCurrentUser();
if (sSystemServicesProxy.isSystemUser(currentUser)) {
mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
- true /* animate */, false /* reloadTasks */, fromHome);
+ true /* animate */, false /* reloadTasks */, fromHome, recentsGrowTarget);
} else {
if (mSystemToUserCallbacks != null) {
IRecentsNonSystemUserCallbacks callbacks =
@@ -260,7 +262,8 @@
if (callbacks != null) {
try {
callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
- true /* animate */, false /* reloadTasks */, fromHome);
+ true /* animate */, false /* reloadTasks */, fromHome,
+ recentsGrowTarget);
} catch (RemoteException e) {
Log.e(TAG, "Callback failed", e);
}
@@ -310,7 +313,7 @@
* Toggles the Recents activity.
*/
@Override
- public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
+ public void toggleRecents(Display display) {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
@@ -321,16 +324,18 @@
return;
}
+ int growTarget = getComponent(Divider.class).getView().growsRecents();
+
int currentUser = sSystemServicesProxy.getCurrentUser();
if (sSystemServicesProxy.isSystemUser(currentUser)) {
- mImpl.toggleRecents();
+ mImpl.toggleRecents(growTarget);
} else {
if (mSystemToUserCallbacks != null) {
IRecentsNonSystemUserCallbacks callbacks =
mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
if (callbacks != null) {
try {
- callbacks.toggleRecents();
+ callbacks.toggleRecents(growTarget);
} catch (RemoteException e) {
Log.e(TAG, "Callback failed", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3ecada9..f961390 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -38,8 +38,10 @@
import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
import android.view.ViewConfiguration;
+import android.view.WindowManager;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.policy.DockedDividerUtils;
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.recents.events.EventBus;
@@ -68,6 +70,7 @@
import com.android.systemui.recents.views.TaskStackViewScroller;
import com.android.systemui.recents.views.TaskViewHeader;
import com.android.systemui.recents.views.TaskViewTransform;
+import com.android.systemui.stackdivider.DividerView;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
@@ -156,7 +159,8 @@
// When this fires, then the user has not released alt-tab for at least
// FAST_ALT_TAB_DELAY_MS milliseconds
showRecents(mTriggeredFromAltTab, false /* draggingInRecents */, true /* animate */,
- false /* reloadTasks */, false /* fromHome */);
+ false /* reloadTasks */, false /* fromHome */,
+ DividerView.INVALID_RECENTS_GROW_TARGET);
}
});
@@ -230,7 +234,8 @@
}
public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents,
- boolean animate, boolean launchedWhileDockingTask, boolean fromHome) {
+ boolean animate, boolean launchedWhileDockingTask, boolean fromHome,
+ int growTarget) {
mTriggeredFromAltTab = triggeredFromAltTab;
mDraggingInRecents = draggingInRecents;
mLaunchedWhileDocking = launchedWhileDockingTask;
@@ -260,7 +265,7 @@
ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
MutableBoolean isTopTaskHome = new MutableBoolean(true);
if (topTask == null || !ssp.isRecentsTopMost(topTask, isTopTaskHome)) {
- startRecentsActivity(topTask, isTopTaskHome.value || fromHome, animate);
+ startRecentsActivity(topTask, isTopTaskHome.value || fromHome, animate, growTarget);
}
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Failed to launch RecentsActivity", e);
@@ -284,7 +289,7 @@
triggeredFromHomeKey));
}
- public void toggleRecents() {
+ public void toggleRecents(int growTarget) {
// Skip this toggle if we are already waiting to trigger recents via alt-tab
if (mFastAltTabTrigger.isDozing()) {
return;
@@ -338,7 +343,7 @@
}
// Otherwise, start the recents activity
- startRecentsActivity(topTask, isTopTaskHome.value, true /* animate */);
+ startRecentsActivity(topTask, isTopTaskHome.value, true /* animate */, growTarget);
// Only close the other system windows if we are actually showing recents
ssp.sendCloseSystemWindows(BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
@@ -369,7 +374,7 @@
// At this point, we don't know anything about the stack state. So only calculate
// the dimensions of the thumbnail that we need for the transition into Recents, but
// do not draw it until we construct the activity options when we start Recents
- updateHeaderBarLayout(stack);
+ updateHeaderBarLayout(stack, null /* window rect override*/);
}
}
}
@@ -535,7 +540,8 @@
dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS,
false /* animate */,
true /* launchedWhileDockingTask*/,
- false /* fromHome */);
+ false /* fromHome */,
+ DividerView.INVALID_RECENTS_GROW_TARGET);
}
}
@@ -574,12 +580,17 @@
* since the last call, it will attempt to re-measure and layout the header bar to the new size.
*
* @param stack the stack to initialize the stack layout with
+ * @param windowRectOverride the rectangle to use when calculating the stack state which can
+ * be different from the current window rect if recents is resizing
+ * while being launched
*/
- private void updateHeaderBarLayout(TaskStack stack) {
+ private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) {
SystemServicesProxy ssp = Recents.getSystemServices();
Rect systemInsets = new Rect();
ssp.getStableInsets(systemInsets);
- Rect windowRect = ssp.getWindowRect();
+ Rect windowRect = windowRectOverride != null
+ ? new Rect(windowRectOverride)
+ : ssp.getWindowRect();
// When docked, the nav bar insets are consumed and the activity is measured without insets.
// However, the window bounds include the insets, so we need to subtract them here to make
// them identical.
@@ -682,7 +693,8 @@
* Creates the activity options for an app->recents transition.
*/
private ActivityOptions getThumbnailTransitionActivityOptions(
- ActivityManager.RunningTaskInfo topTask, TaskStackView stackView) {
+ ActivityManager.RunningTaskInfo topTask, TaskStackView stackView,
+ Rect windowOverrideRect) {
if (topTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
ArrayList<Task> tasks = stackView.getStack().getStackTasks();
@@ -696,7 +708,8 @@
Task task = tasks.get(i);
if (task.isFreeformTask()) {
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
- stackScroller.getStackScroll(), mTmpTransform, null);
+ stackScroller.getStackScroll(), mTmpTransform, null,
+ windowOverrideRect);
Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
mThumbTransitionBitmapCache);
Rect toTaskRect = new Rect();
@@ -711,7 +724,8 @@
} else {
// Update the destination rect
Task toTask = new Task();
- TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask);
+ TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask,
+ windowOverrideRect);
Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
mThumbTransitionBitmapCache);
if (thumbnail != null) {
@@ -729,7 +743,7 @@
* Returns the transition rect for the given task id.
*/
private TaskViewTransform getThumbnailTransitionTransform(TaskStackView stackView,
- Task runningTaskOut) {
+ Task runningTaskOut, Rect windowOverrideRect) {
// Find the running task in the TaskStack
TaskStack stack = stackView.getStack();
Task launchTask = stack.getLaunchTarget();
@@ -745,7 +759,7 @@
stackView.updateLayoutAlgorithm(true /* boundScroll */);
stackView.updateToInitialState();
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
- stackView.getScroller().getStackScroll(), mTmpTransform, null);
+ stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect);
return mTmpTransform;
}
@@ -788,7 +802,7 @@
* Shows the recents activity
*/
protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
- boolean isTopTaskHome, boolean animate) {
+ boolean isTopTaskHome, boolean animate, int growTarget) {
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
@@ -820,7 +834,8 @@
preloadIcon(topTask);
// Update the header bar if necessary
- updateHeaderBarLayout(stack);
+ Rect windowOverrideRect = getWindowRectOverride(growTarget);
+ updateHeaderBarLayout(stack, windowOverrideRect);
// Prepare the dummy stack for the transition
TaskStackLayoutAlgorithm.VisibilityReport stackVr =
@@ -838,7 +853,8 @@
ActivityOptions opts;
if (useThumbnailTransition) {
// Try starting with a thumbnail transition
- opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView);
+ opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView,
+ windowOverrideRect);
} else {
// If there is no thumbnail transition, but is launching from home into recents, then
// use a quick home transition
@@ -850,6 +866,18 @@
mLastToggleTime = SystemClock.elapsedRealtime();
}
+ private Rect getWindowRectOverride(int growTarget) {
+ if (growTarget == DividerView.INVALID_RECENTS_GROW_TARGET) {
+ return null;
+ }
+ Rect result = new Rect();
+ Rect displayRect = Recents.getSystemServices().getDisplayRect();
+ DockedDividerUtils.calculateBoundsForPosition(growTarget, WindowManager.DOCKED_BOTTOM,
+ result, displayRect.width(), displayRect.height(),
+ Recents.getSystemServices().getDockedDividerSize(mContext));
+ return result;
+ }
+
/**
* Starts the recents activity.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
index 257bda2..defc6ed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
@@ -57,13 +57,15 @@
@Override
public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate,
- boolean reloadTasks, boolean fromHome) throws RemoteException {
+ boolean reloadTasks, boolean fromHome, int growTarget)
+ throws RemoteException {
SomeArgs args = SomeArgs.obtain();
args.argi1 = triggeredFromAltTab ? 1 : 0;
args.argi2 = draggingInRecents ? 1 : 0;
args.argi3 = animate ? 1 : 0;
args.argi4 = reloadTasks ? 1 : 0;
args.argi5 = fromHome ? 1 : 0;
+ args.argi6 = growTarget;
mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_RECENTS, args));
}
@@ -75,8 +77,8 @@
}
@Override
- public void toggleRecents() throws RemoteException {
- mHandler.sendEmptyMessage(MSG_TOGGLE_RECENTS);
+ public void toggleRecents(int growTarget) throws RemoteException {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_TOGGLE_RECENTS, growTarget));
}
@Override
@@ -119,13 +121,13 @@
case MSG_SHOW_RECENTS:
SomeArgs args = (SomeArgs) msg.obj;
mImpl.showRecents(args.argi1 != 0, args.argi2 != 0, args.argi3 != 0,
- args.argi4 != 0, args.argi5 != 0);
+ args.argi4 != 0, args.argi5 != 0, args.argi6);
break;
case MSG_HIDE_RECENTS:
mImpl.hideRecents(msg.arg1 != 0, msg.arg2 != 0);
break;
case MSG_TOGGLE_RECENTS:
- mImpl.toggleRecents();
+ mImpl.toggleRecents(msg.arg1);
break;
case MSG_ON_CONFIGURATION_CHANGED:
mImpl.onConfigurationChanged();
diff --git a/core/java/android/net/UidRange.aidl b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java
similarity index 61%
rename from core/java/android/net/UidRange.aidl
rename to packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java
index f9be628..d9b0027 100644
--- a/core/java/android/net/UidRange.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -11,14 +11,16 @@
* 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.
+ * limitations under the License
*/
-package android.net;
+package com.android.systemui.recents.events.ui;
+
+import com.android.systemui.recents.events.EventBus;
/**
- * An inclusive range of UIDs.
- *
- * {@hide}
+ * Sent when recents is about to grow in multi-window mode when entering recents.
*/
-parcelable UidRange;
+public class RecentsGrowingEvent extends EventBus.Event {
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index dc0d1f1..18b9263 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -49,7 +49,7 @@
@Override
protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
- boolean isTopTaskHome, boolean animate) {
+ boolean isTopTaskHome, boolean animate, int growTarget) {
RecentsTaskLoader loader = Recents.getTaskLoader();
// In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 04f10ef8..1238c63 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -302,7 +302,8 @@
specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
} else {
mTmpTransform.fillIn(taskView);
- stackLayout.transformToScreenCoordinates(mTmpTransform);
+ stackLayout.transformToScreenCoordinates(mTmpTransform,
+ null /* windowOverrideRect */);
specs.add(composeAnimationSpec(stackView, taskView, mTmpTransform,
true /* addHeaderBitmap */));
}
@@ -324,7 +325,8 @@
specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect));
} else {
mTmpTransform.fillIn(taskView);
- stackLayout.transformToScreenCoordinates(mTmpTransform);
+ stackLayout.transformToScreenCoordinates(mTmpTransform,
+ null /* windowOverrideRect */);
specs.add(composeAnimationSpec(stackView, tv, mTmpTransform,
true /* addHeaderBitmap */));
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 774e4e9..0022d66 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -830,18 +830,23 @@
* Like {@link #getStackTransform}, but in screen coordinates
*/
public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
- TaskViewTransform transformOut, TaskViewTransform frontTransform) {
+ TaskViewTransform transformOut, TaskViewTransform frontTransform,
+ Rect windowOverrideRect) {
TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
transformOut, frontTransform, true /* forceUpdate */,
false /* ignoreTaskOverrides */);
- return transformToScreenCoordinates(transform);
+ return transformToScreenCoordinates(transform, windowOverrideRect);
}
/**
- * Transforms the given {@param transformOut} to the screen coordinates.
+ * Transforms the given {@param transformOut} to the screen coordinates, overriding the current
+ * window rectangle with {@param windowOverrideRect} if non-null.
*/
- public TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut) {
- Rect windowRect = Recents.getSystemServices().getWindowRect();
+ public TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut,
+ Rect windowOverrideRect) {
+ Rect windowRect = windowOverrideRect != null
+ ? windowOverrideRect
+ : Recents.getSystemServices().getWindowRect();
transformOut.rect.offset(windowRect.left, windowRect.top);
return transformOut;
}
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 6176d99..610b4e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -72,6 +72,7 @@
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
+import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
import com.android.systemui.recents.events.ui.UserInteractionEvent;
@@ -189,6 +190,9 @@
private TaskViewTransform mTmpTransform = new TaskViewTransform();
private ArrayList<TaskViewTransform> mTmpTaskTransforms = new ArrayList<>();
private int[] mTmpIntPair = new int[2];
+ private boolean mResetToInitialStateWhenResized;
+ private int mLastWidth;
+ private int mLastHeight;
// A convenience update listener to request updating clipping of tasks
private ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener =
@@ -1164,9 +1168,13 @@
// If this is the first layout, then scroll to the front of the stack, then update the
// TaskViews with the stack so that we can lay them out
- if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE) {
- if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY) {
+ boolean resetToInitialState = (width != mLastWidth || height != mLastHeight)
+ && mResetToInitialStateWhenResized;
+ if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE
+ || resetToInitialState) {
+ if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY || resetToInitialState) {
updateToInitialState();
+ mResetToInitialStateWhenResized = false;
}
if (!mAwaitingFirstLayout) {
mInitialState = INITIAL_STATE_UPDATE_NONE;
@@ -1186,6 +1194,8 @@
}
setMeasuredDimension(width, height);
+ mLastWidth = width;
+ mLastHeight = height;
mInMeasureLayout = false;
}
@@ -1765,6 +1775,7 @@
mTmpTransform, null);
mTmpTransform.scale = finalScale;
mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
+ mTmpTransform.dimAlpha = 0f;
updateTaskViewToTransform(event.taskView, mTmpTransform,
new AnimationProps(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN));
}
@@ -1972,6 +1983,10 @@
}
}
+ public final void onBusEvent(RecentsGrowingEvent event) {
+ mResetToInitialStateWhenResized = true;
+ }
+
public void reloadOnConfigurationChange() {
mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 67c4008..44a167b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -32,6 +32,7 @@
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.MutableInt;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.GestureDetector;
@@ -66,6 +67,7 @@
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.activity.UndockingTaskEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
+import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.stackdivider.events.StartedDragingEvent;
import com.android.systemui.stackdivider.events.StoppedDragingEvent;
@@ -81,6 +83,8 @@
static final long TOUCH_ANIMATION_DURATION = 150;
static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
+ public static final int INVALID_RECENTS_GROW_TARGET = -1;
+
private static final int LOG_VALUE_RESIZE_50_50 = 0;
private static final int LOG_VALUE_RESIZE_DOCKED_SMALLER = 1;
private static final int LOG_VALUE_RESIZE_DOCKED_LARGER = 2;
@@ -88,7 +92,6 @@
private static final int LOG_VALUE_UNDOCK_MAX_DOCKED = 0;
private static final int LOG_VALUE_UNDOCK_MAX_OTHER = 1;
-
private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
private static final boolean SWAPPING_ENABLED = false;
@@ -154,31 +157,62 @@
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
if (isHorizontalDivision()) {
- info.addAction(new AccessibilityAction(R.id.action_move_up,
- mContext.getString(R.string.accessibility_action_divider_move_up)));
- info.addAction(new AccessibilityAction(R.id.action_move_down,
- mContext.getString(R.string.accessibility_action_divider_move_down)));
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
+ mContext.getString(R.string.accessibility_action_divider_top_full)));
+ if (mSnapAlgorithm.isFirstSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
+ mContext.getString(R.string.accessibility_action_divider_top_70)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
+ mContext.getString(R.string.accessibility_action_divider_top_50)));
+ if (mSnapAlgorithm.isLastSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
+ mContext.getString(R.string.accessibility_action_divider_top_30)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
+ mContext.getString(R.string.accessibility_action_divider_bottom_full)));
} else {
- info.addAction(new AccessibilityAction(R.id.action_move_left,
- mContext.getString(R.string.accessibility_action_divider_move_left)));
- info.addAction(new AccessibilityAction(R.id.action_move_right,
- mContext.getString(R.string.accessibility_action_divider_move_right)));
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
+ mContext.getString(R.string.accessibility_action_divider_left_full)));
+ if (mSnapAlgorithm.isFirstSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
+ mContext.getString(R.string.accessibility_action_divider_left_70)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
+ mContext.getString(R.string.accessibility_action_divider_left_50)));
+ if (mSnapAlgorithm.isLastSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
+ mContext.getString(R.string.accessibility_action_divider_left_30)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
+ mContext.getString(R.string.accessibility_action_divider_right_full)));
}
}
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
- if (action == R.id.action_move_up || action == R.id.action_move_down
- || action == R.id.action_move_left || action == R.id.action_move_right) {
- int position = getCurrentPosition();
- SnapTarget currentTarget = mSnapAlgorithm.calculateSnapTarget(
- position, 0 /* velocity */);
- SnapTarget nextTarget =
- action == R.id.action_move_up || action == R.id.action_move_left
- ? mSnapAlgorithm.getPreviousTarget(currentTarget)
- : mSnapAlgorithm.getNextTarget(currentTarget);
+ int currentPosition = getCurrentPosition();
+ SnapTarget nextTarget = null;
+ switch (action) {
+ case R.id.action_move_tl_full:
+ nextTarget = mSnapAlgorithm.getDismissEndTarget();
+ break;
+ case R.id.action_move_tl_70:
+ nextTarget = mSnapAlgorithm.getLastSplitTarget();
+ break;
+ case R.id.action_move_tl_50:
+ nextTarget = mSnapAlgorithm.getMiddleTarget();
+ break;
+ case R.id.action_move_tl_30:
+ nextTarget = mSnapAlgorithm.getFirstSplitTarget();
+ break;
+ case R.id.action_move_rb_full:
+ nextTarget = mSnapAlgorithm.getDismissStartTarget();
+ break;
+ }
+ if (nextTarget != null) {
startDragging(true /* animate */, false /* touching */);
- stopDragging(getCurrentPosition(), nextTarget, 250, Interpolators.FAST_OUT_SLOW_IN);
+ stopDragging(currentPosition, nextTarget, 250, Interpolators.FAST_OUT_SLOW_IN);
return true;
}
return super.performAccessibilityAction(host, action, args);
@@ -997,6 +1031,24 @@
mBackground.getRight(), mBackground.getBottom(), Op.UNION);
}
+ /**
+ * Checks whether recents will grow when invoked. This happens in multi-window when recents is
+ * very small. When invoking recents, we shrink the docked stack so recents has more space.
+ *
+ * @return the position of the divider when recents grows, or
+ * {@link #INVALID_RECENTS_GROW_TARGET} if recents won't grow
+ */
+ public int growsRecents() {
+ boolean result = mGrowRecents
+ && mWindowManagerProxy.getDockSide() == WindowManager.DOCKED_TOP
+ && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position;
+ if (result) {
+ return getSnapAlgorithm().getMiddleTarget().position;
+ } else {
+ return INVALID_RECENTS_GROW_TARGET;
+ }
+ }
+
public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) {
if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP
&& getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
@@ -1036,7 +1088,8 @@
if (mGrowAfterRecentsDrawn) {
mGrowAfterRecentsDrawn = false;
updateDockSide();
- stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
+ EventBus.getDefault().send(new RecentsGrowingEvent());
+ stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336,
Interpolators.FAST_OUT_SLOW_IN);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
index 177296b..18834ed 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.app.Activity;
+import android.app.ActivityManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -75,4 +76,9 @@
finish();
return true;
}
+
+ @Override
+ public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
+ // Do nothing
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index cb1128b..2d5b6d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1318,7 +1318,7 @@
protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
if (mRecents != null) {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
- mRecents.showRecents(triggeredFromAltTab, fromHome, getStatusBarView());
+ mRecents.showRecents(triggeredFromAltTab, fromHome);
}
}
@@ -1330,7 +1330,7 @@
protected void toggleRecents() {
if (mRecents != null) {
- mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView());
+ mRecents.toggleRecents(mDisplay);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
index 32c26ba..0c1891e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
@@ -25,6 +25,7 @@
import android.view.ViewOutlineProvider;
import android.widget.LinearLayout;
+import com.android.systemui.R;
import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
/**
@@ -32,6 +33,7 @@
*/
public class FakeShadowView extends AlphaOptimizedFrameLayout {
public static final float SHADOW_SIBLING_TRESHOLD = 0.1f;
+ private final int mShadowMinHeight;
private View mFakeShadow;
private float mOutlineAlpha;
@@ -64,6 +66,8 @@
}
});
addView(mFakeShadow);
+ mShadowMinHeight = Math.max(1, context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_divider_height));
}
public void setFakeShadowTranslationZ(float fakeShadowTranslationZ, float outlineAlpha,
@@ -72,6 +76,7 @@
mFakeShadow.setVisibility(INVISIBLE);
} else {
mFakeShadow.setVisibility(VISIBLE);
+ fakeShadowTranslationZ = Math.max(mShadowMinHeight, fakeShadowTranslationZ);
mFakeShadow.setTranslationZ(fakeShadowTranslationZ);
mFakeShadow.setTranslationX(outlineTranslation);
mFakeShadow.setTranslationY(shadowYEnd - mFakeShadow.getHeight());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 915b565..1a9a40b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -43,9 +43,9 @@
private static final int HINT_CIRCLE_OPEN_DURATION = 500;
private final Context mContext;
+ private final Callback mCallback;
private FlingAnimationUtils mFlingAnimationUtils;
- private Callback mCallback;
private VelocityTracker mVelocityTracker;
private boolean mSwipingInProgress;
private float mInitialTouchX;
@@ -318,12 +318,11 @@
float vel = getCurrentVelocity(lastX, lastY);
// We snap back if the current translation is not far enough
- boolean snapBack;
- if (mFalsingManager.isFalseTouch()) {
- snapBack = mFalsingManager.isFalseTouch();
- } else {
- snapBack = isBelowFalsingThreshold();
+ boolean snapBack = false;
+ if (mCallback.needsAntiFalsing()) {
+ snapBack = snapBack || mFalsingManager.isFalseTouch();
}
+ snapBack = snapBack || isBelowFalsingThreshold();
// or if the velocity is in the opposite direction.
boolean velIsInWrongDirection = vel * mTranslation < 0;
@@ -582,5 +581,7 @@
* @return The factor the minimum swipe amount should be multiplied with.
*/
float getAffordanceFalsingFactor();
+
+ boolean needsAntiFalsing();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 92f3585..ef19d95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IWallpaperManager;
import android.app.IWallpaperManagerCallback;
@@ -26,8 +27,9 @@
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableWrapper;
-import android.os.Bundle;
+import android.os.AsyncTask;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -46,9 +48,7 @@
private static final String TAG = "LockscreenWallpaper";
- private final Context mContext;
private final PhoneStatusBar mBar;
- private final IWallpaperManager mService;
private final WallpaperManager mWallpaperManager;
private final Handler mH;
@@ -58,69 +58,75 @@
// The user selected in the UI, or null if no user is selected or UI doesn't support selecting
// users.
private UserHandle mSelectedUser;
+ private AsyncTask<Void, Void, LoaderResult> mLoader;
public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) {
- mContext = ctx;
mBar = bar;
mH = h;
- mService = IWallpaperManager.Stub.asInterface(
- ServiceManager.getService(Context.WALLPAPER_SERVICE));
mWallpaperManager = (WallpaperManager) ctx.getSystemService(Context.WALLPAPER_SERVICE);
mCurrentUserId = ActivityManager.getCurrentUser();
+ IWallpaperManager service = IWallpaperManager.Stub.asInterface(
+ ServiceManager.getService(Context.WALLPAPER_SERVICE));
try {
- mService.setLockWallpaperCallback(this);
+ service.setLockWallpaperCallback(this);
} catch (RemoteException e) {
Log.e(TAG, "System dead?" + e);
}
}
public Bitmap getBitmap() {
- try {
- if (mCached) {
- return mCache;
- }
- if (!mService.isWallpaperSupported(mContext.getOpPackageName())) {
- mCached = true;
- mCache = null;
- return null;
- }
- // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK
- // wallpaper.
- final int lockWallpaperUserId =
- mSelectedUser != null ? mSelectedUser.getIdentifier() : mCurrentUserId;
- ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_LOCK,
- new Bundle(), lockWallpaperUserId);
- if (fd != null) {
- try {
- BitmapFactory.Options options = new BitmapFactory.Options();
- mCache = BitmapFactory.decodeFileDescriptor(
- fd.getFileDescriptor(), null, options);
- mCached = true;
- return mCache;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Can't decode file", e);
- return null;
- } finally {
- IoUtils.closeQuietly(fd);
- }
- } else {
- mCached = true;
- if (mSelectedUser != null && mSelectedUser.getIdentifier() != mCurrentUserId) {
- // When selected user is different from the current user, show the selected
- // user's static wallpaper.
- mCache = mWallpaperManager.getBitmapAsUser(mSelectedUser.getIdentifier());
- } else {
- // When there is no selected user, or it's same as the current user, show the
- // system (possibly dynamic) wallpaper for the selected user.
- mCache = null;
- }
- return mCache;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "System dead?" + e);
+ if (mCached) {
+ return mCache;
+ }
+ if (!mWallpaperManager.isWallpaperSupported()) {
+ mCached = true;
+ mCache = null;
return null;
}
+
+ LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser);
+ if (result.success) {
+ mCached = true;
+ mCache = result.bitmap;
+ }
+ return mCache;
+ }
+
+ public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) {
+ // May be called on any thread - only use thread safe operations.
+
+ // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK
+ // wallpaper.
+ final int lockWallpaperUserId =
+ selectedUser != null ? selectedUser.getIdentifier() : currentUserId;
+ ParcelFileDescriptor fd = mWallpaperManager.getWallpaperFile(
+ WallpaperManager.FLAG_LOCK, lockWallpaperUserId);
+
+ if (fd != null) {
+ try {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ return LoaderResult.success(BitmapFactory.decodeFileDescriptor(
+ fd.getFileDescriptor(), null, options));
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "Can't decode file", e);
+ return LoaderResult.fail();
+ } finally {
+ IoUtils.closeQuietly(fd);
+ }
+ } else {
+ if (selectedUser != null && selectedUser.getIdentifier() != currentUserId) {
+ // When selected user is different from the current user, show the selected
+ // user's static wallpaper.
+ return LoaderResult.success(
+ mWallpaperManager.getBitmapAsUser(selectedUser.getIdentifier()));
+
+ } else {
+ // When there is no selected user, or it's same as the current user, show the
+ // system (possibly dynamic) wallpaper for the selected user.
+ return LoaderResult.success(null);
+ }
+ }
}
public void setCurrentUser(int user) {
@@ -135,14 +141,16 @@
return;
}
mSelectedUser = selectedUser;
-
- mH.removeCallbacks(this);
- mH.post(this);
+ postUpdateWallpaper();
}
@Override
public void onWallpaperChanged() {
// Called on Binder thread.
+ postUpdateWallpaper();
+ }
+
+ private void postUpdateWallpaper() {
mH.removeCallbacks(this);
mH.post(this);
}
@@ -150,10 +158,52 @@
@Override
public void run() {
// Called in response to onWallpaperChanged on the main thread.
- mCached = false;
- mCache = null;
- getBitmap();
- mBar.updateMediaMetaData(true /* metaDataChanged */, true /* allowEnterAnimation */);
+
+ if (mLoader != null) {
+ mLoader.cancel(false /* interrupt */);
+ }
+
+ final int currentUser = mCurrentUserId;
+ final UserHandle selectedUser = mSelectedUser;
+ mLoader = new AsyncTask<Void, Void, LoaderResult>() {
+ @Override
+ protected LoaderResult doInBackground(Void... params) {
+ return loadBitmap(currentUser, selectedUser);
+ }
+
+ @Override
+ protected void onPostExecute(LoaderResult result) {
+ super.onPostExecute(result);
+ if (isCancelled()) {
+ return;
+ }
+ if (result.success) {
+ mCached = true;
+ mCache = result.bitmap;
+ mBar.updateMediaMetaData(
+ true /* metaDataChanged */, true /* allowEnterAnimation */);
+ }
+ mLoader = null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private static class LoaderResult {
+ public final boolean success;
+ public final Bitmap bitmap;
+
+ LoaderResult(boolean success, Bitmap bitmap) {
+ this.success = success;
+ this.bitmap = bitmap;
+ }
+
+ static LoaderResult success(Bitmap b) {
+ return new LoaderResult(true, b);
+ }
+
+ static LoaderResult fail() {
+ return new LoaderResult(false, null);
+ }
}
/**
@@ -161,12 +211,16 @@
*/
public static class WallpaperDrawable extends DrawableWrapper {
- private Bitmap mBackground;
- private Rect mTmpRect = new Rect();
+ private final ConstantState mState;
+ private final Rect mTmpRect = new Rect();
public WallpaperDrawable(Resources r, Bitmap b) {
- super(new BitmapDrawable(r, b));
- mBackground = b;
+ this(r, new ConstantState(b));
+ }
+
+ private WallpaperDrawable(Resources r, ConstantState state) {
+ super(new BitmapDrawable(r, state.mBackground));
+ mState = state;
}
@Override
@@ -183,8 +237,8 @@
protected void onBoundsChange(Rect bounds) {
int vwidth = getBounds().width();
int vheight = getBounds().height();
- int dwidth = mBackground.getWidth();
- int dheight = mBackground.getHeight();
+ int dwidth = mState.mBackground.getWidth();
+ int dheight = mState.mBackground.getHeight();
float scale;
float dx = 0, dy = 0;
@@ -207,5 +261,35 @@
super.onBoundsChange(mTmpRect);
}
+
+ @Override
+ public ConstantState getConstantState() {
+ return mState;
+ }
+
+ static class ConstantState extends Drawable.ConstantState {
+
+ private final Bitmap mBackground;
+
+ ConstantState(Bitmap background) {
+ mBackground = background;
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return newDrawable(null);
+ }
+
+ @Override
+ public Drawable newDrawable(@Nullable Resources res) {
+ return new WallpaperDrawable(res, this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ // DrawableWrapper already handles this for us.
+ return 0;
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 62c0fa9..48cf631 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -701,7 +701,7 @@
}
private boolean isFalseTouch() {
- if (mStatusBarState != StatusBarState.KEYGUARD) {
+ if (!needsAntiFalsing()) {
return false;
}
if (mFalsingManager.isClassiferEnabled()) {
@@ -1941,6 +1941,11 @@
}
@Override
+ public boolean needsAntiFalsing() {
+ return mStatusBarState == StatusBarState.KEYGUARD;
+ }
+
+ @Override
protected float getPeekHeight() {
if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
return mNotificationStackScroller.getPeekHeight();
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 d3f3b2d..712f814 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2021,7 +2021,8 @@
if (metaDataChanged) {
if (mBackdropBack.getDrawable() != null) {
Drawable drawable =
- mBackdropBack.getDrawable().getConstantState().newDrawable().mutate();
+ mBackdropBack.getDrawable().getConstantState()
+ .newDrawable(mBackdropFront.getResources()).mutate();
mBackdropFront.setImageDrawable(drawable);
if (mScrimSrcModeEnabled) {
mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
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 40eb71d..40dacd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -791,7 +791,7 @@
private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
- null, 0, 0, "");
+ null, 0, 0, "", SubscriptionManager.SIM_PROVISIONED);
mMobileSignalControllers.put(id, new MobileSignalController(mContext,
mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info,
mSubDefaults, mReceiverHandler.getLooper()));
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index d900b37..2b29c6b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -60,7 +60,6 @@
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
@@ -92,7 +91,6 @@
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -3315,13 +3313,9 @@
private void openRecents() {
final long token = Binder.clearCallingIdentity();
- IStatusBarService statusBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService("statusbar"));
- try {
- statusBarService.toggleRecentApps();
- } catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error toggling recent apps.");
- }
+ StatusBarManagerInternal statusBarService = LocalServices.getService(
+ StatusBarManagerInternal.class);
+ statusBarService.toggleRecentApps();
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/Android.mk b/services/core/Android.mk
index a248aa3..860f60a 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -13,6 +13,9 @@
../../../../system/netd/server/binder/android/net/INetd.aidl \
../../../../system/netd/server/binder/android/net/metrics/IDnsEventListener.aidl \
+LOCAL_AIDL_INCLUDES += \
+ system/netd/server/binder
+
LOCAL_JAVA_LIBRARIES := services.net telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index d61b561..6c05173 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -690,17 +690,17 @@
final IProgressListener listener = new IProgressListener.Stub() {
@Override
public void onStarted(int id, Bundle extras) throws RemoteException {
- // Ignored
+ Log.d(TAG, "unlockUser started");
}
@Override
public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
- // Ignored
+ Log.d(TAG, "unlockUser progress " + progress);
}
@Override
public void onFinished(int id, Bundle extras) throws RemoteException {
- Log.d(TAG, "unlockUser finished!");
+ Log.d(TAG, "unlockUser finished");
latch.countDown();
}
};
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5d1cb8a..5b8d98c 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -689,7 +689,7 @@
}
public void setServiceForegroundLocked(ComponentName className, IBinder token,
- int id, Notification notification, boolean removeNotification) {
+ int id, Notification notification, int flags) {
final int userId = UserHandle.getCallingUserId();
final long origId = Binder.clearCallingIdentity();
try {
@@ -719,12 +719,16 @@
updateServiceForegroundLocked(r.app, true);
}
}
- if (removeNotification) {
+ if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
r.cancelNotification();
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
r.stripForegroundServiceFlagFromNotification();
+ if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
+ r.foregroundId = 0;
+ r.foregroundNoti = null;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d9e5c775..60653d5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1945,6 +1945,9 @@
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
}
installEncryptionUnawareProviders(userId);
+ if (msg.obj instanceof ProgressReporter) {
+ ((ProgressReporter) msg.obj).finish();
+ }
break;
}
case SYSTEM_USER_CURRENT_MSG: {
@@ -14280,8 +14283,8 @@
+ " mNumServiceProcs=" + mNumServiceProcs
+ " mNewNumServiceProcs=" + mNewNumServiceProcs);
pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
- + " mLastMemoryLevel" + mLastMemoryLevel
- + " mLastNumProcesses" + mLastNumProcesses);
+ + " mLastMemoryLevel=" + mLastMemoryLevel
+ + " mLastNumProcesses=" + mLastNumProcesses);
long now = SystemClock.uptimeMillis();
pw.print(" mLastIdleTime=");
TimeUtils.formatDuration(now, mLastIdleTime, pw);
@@ -16470,10 +16473,9 @@
@Override
public void setServiceForeground(ComponentName className, IBinder token,
- int id, Notification notification, boolean removeNotification) {
+ int id, Notification notification, int flags) {
synchronized(this) {
- mServices.setServiceForegroundLocked(className, token, id, notification,
- removeNotification);
+ mServices.setServiceForegroundLocked(className, token, id, notification, flags);
}
}
@@ -20104,6 +20106,9 @@
if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
}
}
+ if (memFactor != mLastMemoryLevel) {
+ EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
+ }
mLastMemoryLevel = memFactor;
mLastNumProcesses = mLruProcesses.size();
boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 6cd6ff4..2516f5d 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -58,8 +58,8 @@
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
-import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import java.io.File;
import java.io.FileDescriptor;
@@ -176,7 +176,10 @@
BatteryStatsService(File systemDir, Handler handler) {
// Our handler here will be accessing the disk, use a different thread than
// what the ActivityManagerService gave us (no I/O on that one!).
- mHandler = new BatteryStatsHandler(FgThread.getHandler().getLooper());
+ final ServiceThread thread = new ServiceThread("batterystats-sync",
+ Process.THREAD_PRIORITY_DEFAULT, true);
+ thread.start();
+ mHandler = new BatteryStatsHandler(thread.getLooper());
// BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
mStats = new BatteryStatsImpl(systemDir, handler, mHandler);
@@ -209,6 +212,9 @@
synchronized (mStats) {
mStats.shutdownLocked();
}
+
+ // Shutdown the thread we made.
+ mHandler.getLooper().quit();
}
public static IBatteryStats getService() {
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 2329b2f..2762df6 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -108,3 +108,7 @@
30048 am_stop_activity (User|1|5),(Token|1|5),(Component Name|3)
# The activity's onStop has been called.
30049 am_on_stop_called (User|1|5),(Component Name|3),(Reason|3)
+
+# Report changing memory conditions (Values are ProcessStats.ADJ_MEM_FACTOR* constants)
+30050 am_mem_factor (Current|1|5),(Previous|1|5)
+
diff --git a/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
index 9fb51c1..4a87941 100644
--- a/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
+++ b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
@@ -35,12 +35,12 @@
public class HealthStatsBatteryStatsWriter {
- private final long mNowRealtime;
- private final long mNowUptime;
+ private final long mNowRealtimeMs;
+ private final long mNowUptimeMs;
public HealthStatsBatteryStatsWriter() {
- mNowRealtime = SystemClock.elapsedRealtime();
- mNowUptime = SystemClock.uptimeMillis();
+ mNowRealtimeMs = SystemClock.elapsedRealtime();
+ mNowUptimeMs = SystemClock.uptimeMillis();
}
/**
@@ -62,19 +62,20 @@
// MEASUREMENT_REALTIME_BATTERY_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_BATTERY_MS,
- bs.computeBatteryRealtime(mNowRealtime*1000, STATS_SINCE_UNPLUGGED)/1000);
+ bs.computeBatteryRealtime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// MEASUREMENT_UPTIME_BATTERY_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_BATTERY_MS,
- bs.computeBatteryUptime(mNowUptime*1000, STATS_SINCE_UNPLUGGED)/1000);
+ bs.computeBatteryUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS,
- bs.computeBatteryScreenOffRealtime(mNowRealtime*1000, STATS_SINCE_UNPLUGGED)/1000);
+ bs.computeBatteryScreenOffRealtime(
+ mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS,
- bs.computeBatteryScreenOffUptime(mNowUptime*1000, STATS_SINCE_UNPLUGGED)/1000);
+ bs.computeBatteryScreenOffUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
//
// Now on to the real per-uid stats...
@@ -214,20 +215,20 @@
// MEASUREMENT_WIFI_RUNNING_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RUNNING_MS,
- uid.getWifiRunningTime(mNowRealtime, STATS_SINCE_UNPLUGGED));
+ uid.getWifiRunningTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// MEASUREMENT_WIFI_FULL_LOCK_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_FULL_LOCK_MS,
- uid.getFullWifiLockTime(mNowRealtime, STATS_SINCE_UNPLUGGED));
+ uid.getFullWifiLockTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// TIMER_WIFI_SCAN
uidWriter.addTimer(UidHealthStats.TIMER_WIFI_SCAN,
uid.getWifiScanCount(STATS_SINCE_UNPLUGGED),
- uid.getWifiScanTime(mNowRealtime, STATS_SINCE_UNPLUGGED));
+ uid.getWifiScanTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// MEASUREMENT_WIFI_MULTICAST_MS
uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_MULTICAST_MS,
- uid.getWifiMulticastTime(mNowRealtime, STATS_SINCE_UNPLUGGED));
+ uid.getWifiMulticastTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
// TIMER_AUDIO
addTimer(uidWriter, UidHealthStats.TIMER_AUDIO, uid.getAudioTurnedOnTimer());
@@ -355,17 +356,17 @@
uid.getMobileRadioActiveCount(STATS_SINCE_UNPLUGGED),
uid.getMobileRadioActiveTime(STATS_SINCE_UNPLUGGED));
- // MEASUREMENT_USER_CPU_TIME_US
- uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_US,
- uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED));
+ // MEASUREMENT_USER_CPU_TIME_MS
+ uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_MS,
+ uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
- // MEASUREMENT_SYSTEM_CPU_TIME_US
- uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_US,
- uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED));
+ // MEASUREMENT_SYSTEM_CPU_TIME_MS
+ uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_MS,
+ uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
- // MEASUREMENT_CPU_POWER_MAUS
- uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAUS,
- uid.getCpuPowerMaUs(STATS_SINCE_UNPLUGGED));
+ // MEASUREMENT_CPU_POWER_MAMS
+ uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAMS,
+ uid.getCpuPowerMaUs(STATS_SINCE_UNPLUGGED)/1000);
}
/**
@@ -457,7 +458,7 @@
private void addTimer(HealthStatsWriter writer, int key, BatteryStats.Timer timer) {
if (timer != null) {
writer.addTimer(key, timer.getCountLocked(STATS_SINCE_UNPLUGGED),
- timer.getTotalTimeLocked(mNowRealtime, STATS_SINCE_UNPLUGGED));
+ timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000);
}
}
@@ -468,7 +469,7 @@
BatteryStats.Timer timer) {
if (timer != null) {
writer.addTimers(key, name, new TimerStat(timer.getCountLocked(STATS_SINCE_UNPLUGGED),
- timer.getTotalTimeLocked(mNowRealtime, STATS_SINCE_UNPLUGGED)));
+ timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000));
}
}
}
diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java
index 0e192ea..1f3ccf5 100644
--- a/services/core/java/com/android/server/am/PreBootBroadcaster.java
+++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java
@@ -78,9 +78,12 @@
final ResolveInfo ri = mTargets.get(mIndex++);
final ComponentName componentName = ri.activityInfo.getComponentName();
- final CharSequence label = ri.activityInfo.loadLabel(mService.mContext.getPackageManager());
- mProgress.setProgress(mIndex, mTargets.size(),
- mService.mContext.getString(R.string.android_preparing_apk, label));
+ if (mProgress != null) {
+ final CharSequence label = ri.activityInfo
+ .loadLabel(mService.mContext.getPackageManager());
+ mProgress.setProgress(mIndex, mTargets.size(),
+ mService.mContext.getString(R.string.android_preparing_apk, label));
+ }
Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 5075c3a..bc297de 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -516,7 +516,7 @@
// If it gave us a garbage notification, it doesn't
// get to be foreground.
ams.setServiceForeground(name, ServiceRecord.this,
- 0, null, true);
+ 0, null, 0);
ams.crashApplication(appUid, appPid, localPackageName,
"Bad notification for startForeground: " + e);
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 4c050c4..75d49c3 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -101,6 +101,7 @@
*/
final class UserController {
private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
+
// Maximum number of users we allow to be running at a time.
static final int MAX_RUNNING_USERS = 3;
@@ -279,7 +280,8 @@
uss.mUnlockProgress.setProgress(20);
// Dispatch unlocked to system services
- mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
+ mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss.mUnlockProgress)
+ .sendToTarget();
// Dispatch unlocked to external apps
final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
@@ -309,8 +311,7 @@
// Send PRE_BOOT broadcasts if fingerprint changed
final UserInfo info = getUserInfo(userId);
if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
- uss.mUnlockProgress.startSegment(80);
- new PreBootBroadcaster(mService, userId, uss.mUnlockProgress) {
+ new PreBootBroadcaster(mService, userId, null) {
@Override
public void onFinished() {
finishUserUnlocked(uss);
@@ -328,14 +329,6 @@
* {@link UserState#STATE_RUNNING_UNLOCKED}.
*/
private void finishUserUnlocked(UserState uss) {
- try {
- finishUserUnlockedInternal(uss);
- } finally {
- uss.mUnlockProgress.finish();
- }
- }
-
- private void finishUserUnlockedInternal(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
synchronized (mService) {
// Bail if we ended up with a stale user
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index d2f015f..10284bb 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -39,9 +39,9 @@
public abstract void resetFailedAttempts();
public AuthenticationClient(Context context, long halDeviceId, IBinder token,
- IFingerprintServiceReceiver receiver, int userId, int groupId, long opId,
+ IFingerprintServiceReceiver receiver, int callingUserId, int groupId, long opId,
boolean restricted, String owner) {
- super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner);
+ super(context, halDeviceId, token, receiver, callingUserId, groupId, restricted, owner);
mOpId = opId;
}
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 90998ed..45b6d3e 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -38,7 +38,7 @@
protected static final boolean DEBUG = FingerprintService.DEBUG;
private IBinder mToken;
private IFingerprintServiceReceiver mReceiver;
- private int mUserId;
+ private int mCallingUserId;
private int mGroupId;
private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
private String mOwner;
@@ -50,20 +50,20 @@
* @param halDeviceId the HAL device ID of the associated fingerprint hardware
* @param token a unique token for the client
* @param receiver recipient of related events (e.g. authentication)
- * @param userId userId for the fingerprint set
+ * @param callingUserId user id of calling user
* @param groupId groupId for the fingerprint set
* @param restricted whether or not client has the {@link Manifest#MANAGE_FINGERPRINT}
* permission
* @param owner name of the client that owns this
*/
public ClientMonitor(Context context, long halDeviceId, IBinder token,
- IFingerprintServiceReceiver receiver, int userId, int groupId,boolean restricted,
+ IFingerprintServiceReceiver receiver, int callingUserId, int groupId,boolean restricted,
String owner) {
mContext = context;
mHalDeviceId = halDeviceId;
mToken = token;
mReceiver = receiver;
- mUserId = userId;
+ mCallingUserId = callingUserId;
mGroupId = groupId;
mIsRestricted = restricted;
mOwner = owner;
@@ -197,8 +197,8 @@
return mIsRestricted;
}
- public final int getUserId() {
- return mUserId;
+ public final int getCallingUserId() {
+ return mCallingUserId;
}
public final int getGroupId() {
diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java
index ce5b890..b636ce5 100644
--- a/services/core/java/com/android/server/fingerprint/EnrollClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java
@@ -46,9 +46,12 @@
@Override
public boolean onEnrollResult(int fingerId, int groupId, int remaining) {
+ if (groupId != getGroupId()) {
+ Slog.w(TAG, "groupId != getGroupId(), groupId: " + groupId +
+ " getGroupId():" + getGroupId());
+ }
if (remaining == 0) {
- FingerprintUtils.getInstance().addFingerprintForUser(getContext(), fingerId,
- getUserId());
+ FingerprintUtils.getInstance().addFingerprintForUser(getContext(), fingerId, groupId);
}
return sendEnrollResult(fingerId, groupId, remaining);
}
diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
index b2e4099..e826fee 100644
--- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
@@ -41,7 +41,7 @@
try {
final int result = daemon.enumerate();
if (result != 0) {
- Slog.w(TAG, "start enumerate for user " + getUserId()
+ Slog.w(TAG, "start enumerate for user " + getCallingUserId()
+ " failed, result=" + result);
onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
return result;
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c770620..fcf7bf5 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -356,7 +356,7 @@
}
}
- void startRemove(IBinder token, int fingerId, int userId, int groupId,
+ void startRemove(IBinder token, int fingerId, int callingUserId, int groupId,
IFingerprintServiceReceiver receiver, boolean restricted) {
IFingerprintDaemon daemon = getFingerprintDaemon();
if (daemon == null) {
@@ -364,7 +364,7 @@
return;
}
RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token,
- receiver, userId, groupId, fingerId, restricted, token.toString()) {
+ receiver, callingUserId, groupId, fingerId, restricted, token.toString()) {
@Override
public void notifyUserActivity() {
FingerprintService.this.userActivity();
@@ -372,8 +372,7 @@
@Override
public IFingerprintDaemon getFingerprintDaemon() {
- FingerprintService.this.getFingerprintDaemon();
- return null;
+ return FingerprintService.this.getFingerprintDaemon();
}
};
startClient(client, true);
@@ -494,7 +493,7 @@
}
}
- private void startAuthentication(IBinder token, long opId, int realUserId, int groupId,
+ private void startAuthentication(IBinder token, long opId, int callingUserId, int groupId,
IFingerprintServiceReceiver receiver, int flags, boolean restricted,
String opPackageName) {
updateActiveGroup(groupId, opPackageName);
@@ -502,7 +501,7 @@
if (DEBUG) Slog.v(TAG, "startAuthentication(" + opPackageName + ")");
AuthenticationClient client = new AuthenticationClient(getContext(), mHalDeviceId, token,
- receiver, realUserId, groupId, opId, restricted, opPackageName) {
+ receiver, callingUserId, groupId, opId, restricted, opPackageName) {
@Override
public boolean handleFailedAttempt() {
mFailedAttempts++;
@@ -541,13 +540,13 @@
startClient(client, true /* initiatedByClient */);
}
- private void startEnrollment(IBinder token, byte [] cryptoToken, int userId, int groupId,
+ private void startEnrollment(IBinder token, byte [] cryptoToken, int callingUserId, int groupId,
IFingerprintServiceReceiver receiver, int flags, boolean restricted,
String opPackageName) {
updateActiveGroup(groupId, opPackageName);
EnrollClient client = new EnrollClient(getContext(), mHalDeviceId, token, receiver,
- userId, groupId, cryptoToken, restricted, opPackageName) {
+ callingUserId, groupId, cryptoToken, restricted, opPackageName) {
@Override
public IFingerprintDaemon getFingerprintDaemon() {
@@ -687,9 +686,9 @@
checkPermission(MANAGE_FINGERPRINT);
final int limit = mContext.getResources().getInteger(
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
- final int callingUid = Binder.getCallingUid();
- final int userId = UserHandle.getUserId(callingUid);
- final int enrolled = FingerprintService.this.getEnrolledFingerprints(userId).size();
+ final int callingUserId = UserHandle.getCallingUserId();
+ final int enrolled = FingerprintService.this.
+ getEnrolledFingerprints(callingUserId).size();
if (enrolled >= limit) {
Slog.w(TAG, "Too many fingerprints registered");
return;
@@ -705,7 +704,7 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- startEnrollment(token, cryptoToken, userId, groupId, receiver, flags,
+ startEnrollment(token, cryptoToken, callingUserId, groupId, receiver, flags,
restricted, opPackageName);
}
});
@@ -735,7 +734,8 @@
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
- final int realUserId = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getCallingUserId();
final int pid = Binder.getCallingPid();
final boolean restricted = isRestricted();
mHandler.post(new Runnable() {
@@ -743,11 +743,11 @@
public void run() {
MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
if (!canUseFingerprint(opPackageName, true /* foregroundOnly */,
- realUserId, pid)) {
+ callingUid, pid)) {
if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
- startAuthentication(token, opId, realUserId, groupId, receiver,
+ startAuthentication(token, opId, callingUserId, groupId, receiver,
flags, restricted, opPackageName);
}
});
@@ -797,11 +797,11 @@
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
final boolean restricted = isRestricted();
- final int realUserId = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getCallingUserId();
mHandler.post(new Runnable() {
@Override
public void run() {
- startRemove(token, fingerId, realUserId, groupId, receiver, restricted);
+ startRemove(token, fingerId, callingUserId, groupId, receiver, restricted);
}
});
diff --git a/services/core/java/com/android/server/fingerprint/RemovalClient.java b/services/core/java/com/android/server/fingerprint/RemovalClient.java
index 69a96e1..ffa3c3f 100644
--- a/services/core/java/com/android/server/fingerprint/RemovalClient.java
+++ b/services/core/java/com/android/server/fingerprint/RemovalClient.java
@@ -45,7 +45,7 @@
IFingerprintDaemon daemon = getFingerprintDaemon();
// The fingerprint template ids will be removed when we get confirmation from the HAL
try {
- final int result = daemon.remove(mFingerId, getUserId());
+ final int result = daemon.remove(mFingerId, getGroupId());
if (result != 0) {
Slog.w(TAG, "startRemove with id = " + mFingerId + " failed, result=" + result);
onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4819de5..0633625 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -216,6 +216,7 @@
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.Xml;
+import android.util.jar.StrictJarFile;
import android.view.Display;
import com.android.internal.R;
@@ -7643,6 +7644,52 @@
}
}
+ /**
+ * Returns {@code true} if the given file contains code. Otherwise {@code false}.
+ */
+ private static boolean apkHasCode(String fileName) {
+ StrictJarFile jarFile = null;
+ try {
+ jarFile = new StrictJarFile(fileName,
+ false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
+ return jarFile.findEntry("classes.dex") != null;
+ } catch (IOException ignore) {
+ } finally {
+ try {
+ jarFile.close();
+ } catch (IOException ignore) {}
+ }
+ return false;
+ }
+
+ /**
+ * Enforces code policy for the package. This ensures that if an APK has
+ * declared hasCode="true" in its manifest that the APK actually contains
+ * code.
+ *
+ * @throws PackageManagerException If bytecode could not be found when it should exist
+ */
+ private static void enforceCodePolicy(PackageParser.Package pkg)
+ throws PackageManagerException {
+ final boolean shouldHaveCode =
+ (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package " + pkg.baseCodePath + " code is missing");
+ }
+
+ if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
+ for (int i = 0; i < pkg.splitCodePaths.length; i++) {
+ final boolean splitShouldHaveCode =
+ (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package " + pkg.splitCodePaths[i] + " code is missing");
+ }
+ }
+ }
+ }
+
private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
throws PackageManagerException {
@@ -7687,6 +7734,10 @@
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
}
+ if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
+ enforceCodePolicy(pkg);
+ }
+
if (mCustomResolverComponentName != null &&
mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
setUpCustomResolverActivity(pkg);
@@ -18679,11 +18730,11 @@
try {
storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
- if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
+ if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
UserManagerService.enforceSerialNumber(
Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
}
- if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
+ if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
UserManagerService.enforceSerialNumber(
Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
}
@@ -18771,7 +18822,7 @@
logCriticalInfo(Log.WARN, "Destroying user directory " + file
+ " because no matching user was found");
destroyUser = true;
- } else {
+ } else if (!mOnlyCore) {
try {
UserManagerService.enforceSerialNumber(file, info.serialNumber);
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 42f7166..1297343 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2359,11 +2359,13 @@
public void setApplicationRestrictions(String packageName, Bundle restrictions,
int userId) {
checkSystemOrRoot("set application restrictions");
+ if (restrictions != null) {
+ restrictions.setDefusable(true);
+ }
synchronized (mPackagesLock) {
if (restrictions == null || restrictions.isEmpty()) {
cleanAppRestrictionsForPackage(packageName, userId);
} else {
- restrictions.setDefusable(true);
// Write the restrictions to XML
writeApplicationRestrictionsLP(packageName, restrictions, userId);
}
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index 0c80ffa..5878709 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -18,15 +18,14 @@
import android.app.StatusBarManager;
import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Slog;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerPolicy.WindowState;
-import com.android.internal.statusbar.IStatusBarService;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
@@ -52,7 +51,7 @@
private final int mTranslucentWmFlag;
protected final Handler mHandler;
private final Object mServiceAquireLock = new Object();
- protected IStatusBarService mStatusBarService;
+ protected StatusBarManagerInternal mStatusBarInternal;
private WindowState mWin;
private int mState = StatusBarManager.WINDOW_STATE_SHOWING;
@@ -182,15 +181,9 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.setWindowState(mStatusBarManagerId, state);
- }
- } catch (RemoteException e) {
- if (DEBUG) Slog.w(mTag, "Error posting window state", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarInternal();
+ if (statusbar != null) {
+ statusbar.setWindowState(mStatusBarManagerId, state);
}
}
});
@@ -276,13 +269,12 @@
}
}
- protected IStatusBarService getStatusBarService() {
+ protected StatusBarManagerInternal getStatusBarInternal() {
synchronized (mServiceAquireLock) {
- if (mStatusBarService == null) {
- mStatusBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService("statusbar"));
+ if (mStatusBarInternal == null) {
+ mStatusBarInternal = LocalServices.getService(StatusBarManagerInternal.class);
}
- return mStatusBarService;
+ return mStatusBarInternal;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 1686f14..007190d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1467,14 +1467,12 @@
private void requestTvPictureInPictureInternal() {
try {
- IStatusBarService statusbar = getStatusBarService();
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
statusbar.requestTvPictureInPicture();
}
- } catch (RemoteException|IllegalArgumentException e) {
+ } catch (IllegalArgumentException e) {
Slog.e(TAG, "Cannot handle picture-in-picture key", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
}
}
@@ -3562,21 +3560,15 @@
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.launchLegacyAssist(hint, UserHandle.myUserId(), args);
} else {
- try {
- if (hint != null) {
- if (args == null) {
- args = new Bundle();
- }
- args.putBoolean(hint, true);
+ if (hint != null) {
+ if (args == null) {
+ args = new Bundle();
}
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.startAssist(args);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when starting assist", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ args.putBoolean(hint, true);
+ }
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.startAssist(args);
}
}
}
@@ -3598,45 +3590,27 @@
private void preloadRecentApps() {
mPreloadedRecentApps = true;
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.preloadRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when preloading recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.preloadRecentApps();
}
}
private void cancelPreloadRecentApps() {
if (mPreloadedRecentApps) {
mPreloadedRecentApps = false;
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.cancelPreloadRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when cancelling recent apps preload", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.cancelPreloadRecentApps();
}
}
}
private void toggleRecentApps() {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.toggleRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when toggling recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.toggleRecentApps();
}
}
@@ -3648,40 +3622,24 @@
private void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.showRecentApps(triggeredFromAltTab, fromHome);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.showRecentApps(triggeredFromAltTab, fromHome);
}
}
private void toggleKeyboardShortcutsMenu(int deviceId) {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.toggleKeyboardShortcutsMenu(deviceId);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing keyboard shortcuts menu", e);
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.toggleKeyboardShortcutsMenu(deviceId);
}
}
private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when closing recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+ if (statusbar != null) {
+ statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome);
}
}
@@ -7483,13 +7441,9 @@
if (mKeyguardDelegate != null) {
mKeyguardDelegate.setCurrentUser(newUserId);
}
- IStatusBarService statusBar = getStatusBarService();
+ StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
if (statusBar != null) {
- try {
- statusBar.setCurrentUser(newUserId);
- } catch (RemoteException e) {
- // oh well
- }
+ statusBar.setCurrentUser(newUserId);
}
setLastInputMethodWindowLw(null, null);
}
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index 86d0468..245518c 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -18,9 +18,7 @@
import android.app.StatusBarManager;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.SystemClock;
-import android.util.Slog;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
@@ -28,7 +26,6 @@
import android.view.animation.Interpolator;
import android.view.animation.TranslateAnimation;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -49,15 +46,9 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.appTransitionPending();
- }
- } catch (RemoteException e) {
- Slog.e(mTag, "RemoteException when app transition is pending", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarInternal();
+ if (statusbar != null) {
+ statusbar.appTransitionPending();
}
}
});
@@ -69,19 +60,13 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- long startTime = calculateStatusBarTransitionStartTime(openAnimation,
- closeAnimation);
- long duration = closeAnimation != null || openAnimation != null
- ? TRANSITION_DURATION : 0;
- statusbar.appTransitionStarting(startTime, duration);
- }
- } catch (RemoteException e) {
- Slog.e(mTag, "RemoteException when app transition is starting", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarInternal();
+ if (statusbar != null) {
+ long startTime = calculateStatusBarTransitionStartTime(openAnimation,
+ closeAnimation);
+ long duration = closeAnimation != null || openAnimation != null
+ ? TRANSITION_DURATION : 0;
+ statusbar.appTransitionStarting(startTime, duration);
}
}
});
@@ -92,15 +77,9 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.appTransitionCancelled();
- }
- } catch (RemoteException e) {
- Slog.e(mTag, "RemoteException when app transition is cancelled", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ StatusBarManagerInternal statusbar = getStatusBarInternal();
+ if (statusbar != null) {
+ statusbar.appTransitionCancelled();
}
}
});
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 95923fe..38a3d01 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -28,6 +28,50 @@
void notificationLightOff();
void showScreenPinningRequest(int taskId);
void showAssistDisclosure();
+
+ void preloadRecentApps();
+
+ void cancelPreloadRecentApps();
+
+ void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
+
+ void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
+
+ void toggleKeyboardShortcutsMenu(int deviceId);
+
+ /**
+ * Request picture-in-picture.
+ *
+ * <p>
+ * This is called when an user presses picture-in-picture key or equivalent.
+ * TV device may start picture-in-picture from foreground activity if there's none.
+ * Picture-in-picture overlay menu will be shown instead otherwise.
+ */
+ void requestTvPictureInPicture();
+
+ void setWindowState(int window, int state);
+
+ /**
+ * Notifies the status bar that an app transition is pending to delay applying some flags with
+ * visual impact until {@link #appTransitionReady} is called.
+ */
+ void appTransitionPending();
+
+ /**
+ * Notifies the status bar that a pending app transition has been cancelled.
+ */
+ void appTransitionCancelled();
+
+ /**
+ * Notifies the status bar that an app transition is now being executed.
+ *
+ * @param statusBarAnimationsStartTime the desired start time for all visual animations in the
+ * status bar caused by this app transition in uptime millis
+ * @param statusBarAnimationsDuration the duration for all visual animations in the status
+ * bar caused by this app transition in millis
+ */
+ void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
+
void startAssist(Bundle args);
void onCameraLaunchGestureDetected(int source);
void topAppWindowChanged(boolean menuVisible);
@@ -35,4 +79,8 @@
Rect fullscreenBounds, Rect dockedBounds, String cause);
void toggleSplitScreen();
void appTransitionFinished();
+
+ void toggleRecentApps();
+
+ void setCurrentUser(int newUserId);
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 981b75a..9020677 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -223,6 +223,114 @@
} catch (RemoteException ex) {}
}
}
+
+ @Override
+ public void toggleRecentApps() {
+ if (mBar != null) {
+ try {
+ mBar.toggleRecentApps();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void setCurrentUser(int newUserId) {
+ if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
+ mCurrentUserId = newUserId;
+ }
+
+
+ @Override
+ public void preloadRecentApps() {
+ if (mBar != null) {
+ try {
+ mBar.preloadRecentApps();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void cancelPreloadRecentApps() {
+ if (mBar != null) {
+ try {
+ mBar.cancelPreloadRecentApps();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
+ if (mBar != null) {
+ try {
+ mBar.showRecentApps(triggeredFromAltTab, fromHome);
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ if (mBar != null) {
+ try {
+ mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void toggleKeyboardShortcutsMenu(int deviceId) {
+ if (mBar != null) {
+ try {
+ mBar.toggleKeyboardShortcutsMenu(deviceId);
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void requestTvPictureInPicture() {
+ if (mBar != null) {
+ try {
+ mBar.requestTvPictureInPicture();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void setWindowState(int window, int state) {
+ if (mBar != null) {
+ try {
+ mBar.setWindowState(window, state);
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void appTransitionPending() {
+ if (mBar != null) {
+ try {
+ mBar.appTransitionPending();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void appTransitionCancelled() {
+ if (mBar != null) {
+ try {
+ mBar.appTransitionCancelled();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
+ public void appTransitionStarting(long statusBarAnimationsStartTime,
+ long statusBarAnimationsDuration) {
+ if (mBar != null) {
+ try {
+ mBar.appTransitionStarting(
+ statusBarAnimationsStartTime, statusBarAnimationsDuration);
+ } catch (RemoteException ex) {}
+ }
+ }
};
// ================================================================================
@@ -527,122 +635,6 @@
}
}
- @Override
- public void toggleRecentApps() {
- if (mBar != null) {
- try {
- mBar.toggleRecentApps();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void preloadRecentApps() {
- if (mBar != null) {
- try {
- mBar.preloadRecentApps();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void cancelPreloadRecentApps() {
- if (mBar != null) {
- try {
- mBar.cancelPreloadRecentApps();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
- if (mBar != null) {
- try {
- mBar.showRecentApps(triggeredFromAltTab, fromHome);
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mBar != null) {
- try {
- mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void toggleKeyboardShortcutsMenu(int deviceId) {
- if (mBar != null) {
- try {
- mBar.toggleKeyboardShortcutsMenu(deviceId);
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void requestTvPictureInPicture() {
- if (mBar != null) {
- try {
- mBar.requestTvPictureInPicture();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void setCurrentUser(int newUserId) {
- if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
- mCurrentUserId = newUserId;
- }
-
- @Override
- public void setWindowState(int window, int state) {
- if (mBar != null) {
- try {
- mBar.setWindowState(window, state);
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void appTransitionPending() {
- if (mBar != null) {
- try {
- mBar.appTransitionPending();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void appTransitionCancelled() {
- if (mBar != null) {
- try {
- mBar.appTransitionCancelled();
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void appTransitionStarting(long statusBarAnimationsStartTime,
- long statusBarAnimationsDuration) {
- if (mBar != null) {
- try {
- mBar.appTransitionStarting(
- statusBarAnimationsStartTime, statusBarAnimationsDuration);
- } catch (RemoteException ex) {}
- }
- }
-
- @Override
- public void startAssist(Bundle args) {
- if (mBar != null) {
- try {
- mBar.startAssist(args);
- } catch (RemoteException ex) {}
- }
- }
-
private void enforceStatusBarOrShell() {
if (Binder.getCallingUid() == Process.SHELL_UID) {
return;
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index b7d6062..eacdd81 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -129,13 +129,16 @@
public void onAnimationStart(Animator animation) {
if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
+ " mReplacement=" + mReplacement);
- if (animatingToLargerSize()) {
- mTarget.setPinnedStackSize(mFrom, mTo);
- }
-
if (!mReplacement) {
mTarget.onAnimationStart();
}
+
+ // Ensure that we have prepared the target for animation before
+ // we trigger any size changes, so it can swap surfaces
+ // in to appropriate modes, or do as it wishes otherwise.
+ if (animatingToLargerSize()) {
+ mTarget.setPinnedStackSize(mFrom, mTo);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 0039c0a..b90d0d1 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -663,4 +663,8 @@
public String toShortString() {
return TAG;
}
-}
\ No newline at end of file
+
+ WindowState getWindow() {
+ return mWindow;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 46a8dff..4f49eed 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -600,7 +600,8 @@
//
// Anyway we don't need to synchronize position and content updates for these
// windows since they aren't at the base layer and could be moved around anyway.
- if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION) {
+ if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
+ !mStack.getBoundsAnimating()) {
win.mResizedWhileNotDragResizing = true;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 872bc6d..1fd2b1f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -42,6 +42,7 @@
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.animation.PathInterpolator;
+import android.view.SurfaceControl;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
@@ -127,10 +128,12 @@
private float mAdjustImeAmount;
private final int mDockedStackMinimizeThickness;
- // If this is true, the task will be down or upscaled
- // to perfectly fit the region it would have been cropped
- // to.
- private boolean mForceScaleToCrop = false;
+ // If this is true, we are in the bounds animating mode.
+ // The task will be down or upscaled to perfectly fit the
+ // region it would have been cropped to. We may also avoid
+ // certain logic we would otherwise apply while resizing,
+ // while resizing in the bounds animating mode.
+ private boolean mBoundsAnimating = false;
// By default, movement animations are applied to all
// window movement. If this is true, animations will not
// be applied within this stack. This is useful for example
@@ -1269,11 +1272,36 @@
return true;
}
+ void forceWindowsScaleable(boolean force) {
+ SurfaceControl.openTransaction();
+ try {
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
+ for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
+ if (winAnimator == null || !winAnimator.hasSurface()) {
+ continue;
+ }
+ winAnimator.mSurfaceController.forceScaleableInTransaction(force);
+ }
+ }
+ }
+ } finally {
+ SurfaceControl.closeTransaction();
+ }
+ }
+
@Override // AnimatesBounds
public void onAnimationStart() {
synchronized (mService.mWindowMap) {
+ // We force windows out of SCALING_MODE_FREEZE
+ // so that we can continue to animate them
+ // while a resize is pending.
+ forceWindowsScaleable(true);
mFreezeMovementAnimations = true;
- mForceScaleToCrop = true;
+ mBoundsAnimating = true;
}
}
@@ -1281,7 +1309,8 @@
public void onAnimationEnd() {
synchronized (mService.mWindowMap) {
mFreezeMovementAnimations = false;
- mForceScaleToCrop = false;
+ mBoundsAnimating = false;
+ forceWindowsScaleable(false);
mService.requestTraversal();
}
if (mStackId == PINNED_STACK_ID) {
@@ -1312,6 +1341,10 @@
}
public boolean getForceScaleToCrop() {
- return mForceScaleToCrop;
+ return mBoundsAnimating;
+ }
+
+ public boolean getBoundsAnimating() {
+ return mBoundsAnimating;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 79ff78e..38f12a1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1563,6 +1563,16 @@
mLayersController.setInputMethodAnimLayerAdjustment(0);
}
}
+
+ // If the docked divider is visible, we still need to go through this whole
+ // excercise to find the appropriate input method target (used for animations
+ // and dialog adjustments), but for purposes of Z ordering we simply wish to
+ // place it above the docked divider.
+ WindowState dockedDivider = w.mDisplayContent.mDividerControllerLocked.getWindow();
+ if (dockedDivider != null && dockedDivider.isVisibleLw()) {
+ int dividerIndex = windows.indexOf(dockedDivider);
+ return dividerIndex > 0 ? dividerIndex + 1 : i + 1;
+ }
return i+1;
}
if (willMove) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5077f32..76fdda01 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2382,6 +2382,9 @@
if (stack != null) {
pw.print(" stackId="); pw.print(stack.mStackId);
}
+ if (mNotOnAppsDisplay) {
+ pw.print(" mNotOnAppsDisplay="); pw.print(mNotOnAppsDisplay);
+ }
pw.print(" mSession="); pw.print(mSession);
pw.print(" mClient="); pw.println(mClient.asBinder());
pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1f76f31..8c29c9b 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -562,6 +562,7 @@
Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
+ drawStateToString());
}
+
if (mWin.mAppToken != null && mWin.mAppToken.mAnimatingWithSavedSurface) {
// App has drawn something to its windows, we're no longer animating with
// the saved surfaces. If the user exits now, we only want to save again
@@ -1290,6 +1291,17 @@
}
private void adjustCropToStackBounds(WindowState w, Rect clipRect, Rect finalClipRect,
boolean isFreeformResizing) {
+
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (displayContent != null && !displayContent.isDefaultDisplay) {
+ // There are some windows that live on other displays while their app and main window
+ // live on the default display (e.g. casting...). We don't want to crop this windows
+ // to the stack bounds which is only currently supported on the default display.
+ // TODO(multi-display): Need to support cropping to stack bounds on other displays
+ // when we have stacks on other displays.
+ return;
+ }
+
final Task task = w.getTask();
if (task == null || !task.cropWindowsToStackBounds()) {
return;
@@ -1352,7 +1364,7 @@
final Task task = w.getTask();
// We got resized, so block all updates until we got the new surface.
- if (w.mResizedWhileNotDragResizing) {
+ if (w.mResizedWhileNotDragResizing && !w.isGoneForLayoutLw()) {
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 8799c61..6eed5e7 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -23,6 +23,8 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static android.view.Surface.SCALING_MODE_FREEZE;
+import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW;
import android.graphics.Point;
import android.graphics.PointF;
@@ -392,6 +394,13 @@
mSurfaceControl.deferTransactionUntil(handle, frame);
}
+ void forceScaleableInTransaction(boolean force) {
+ // -1 means we don't override the default or client specified
+ // scaling mode.
+ int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
+ mSurfaceControl.setOverrideScalingMode(scalingMode);
+ }
+
boolean clearWindowContentFrameStats() {
if (mSurfaceControl == null) {
return false;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d3d05f3..45a7311 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2909,6 +2909,54 @@
}
}
+ public void forceRemoveActiveAdmin(ComponentName adminReceiver, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(adminReceiver, "ComponentName is null");
+ enforceShell("forceRemoveActiveAdmin");
+ long ident = mInjector.binderClearCallingIdentity();
+ try {
+ final ApplicationInfo ai;
+ try {
+ ai = mIPackageManager.getApplicationInfo(adminReceiver.getPackageName(),
+ 0, userHandle);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ if (ai == null) {
+ throw new IllegalStateException("Couldn't find package to remove admin "
+ + adminReceiver.getPackageName() + " " + userHandle);
+ }
+ if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
+ throw new SecurityException("Attempt to remove non-test admin " + adminReceiver
+ + adminReceiver + " " + userHandle);
+ }
+ // If admin is a device or profile owner tidy that up first.
+ synchronized (this) {
+ if (isDeviceOwner(adminReceiver, userHandle)) {
+ clearDeviceOwnerLocked(getDeviceOwnerAdminLocked(), userHandle);
+ }
+ if (isProfileOwner(adminReceiver, userHandle)) {
+ final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver,
+ userHandle, /* parent */ false);
+ clearProfileOwnerLocked(admin, userHandle);
+ }
+ }
+ // Remove the admin skipping sending the broadcast.
+ removeAdminArtifacts(adminReceiver, userHandle);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+
+ private void enforceShell(String method) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) {
+ throw new SecurityException("Non-shell user attempted to call " + method);
+ }
+ }
+
@Override
public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
if (!mHasFeature) {
@@ -5732,32 +5780,37 @@
enforceUserUnlocked(deviceOwnerUserId);
final ActiveAdmin admin = getDeviceOwnerAdminLocked();
- if (admin != null) {
- admin.disableCamera = false;
- admin.userRestrictions = null;
- admin.forceEphemeralUsers = false;
- mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
- }
- clearUserPoliciesLocked(deviceOwnerUserId);
-
- mOwners.clearDeviceOwner();
- mOwners.writeDeviceOwner();
- updateDeviceOwnerLocked();
- disableSecurityLoggingIfNotCompliant();
- // Reactivate backup service.
long ident = mInjector.binderClearCallingIdentity();
try {
- mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
-
+ clearDeviceOwnerLocked(admin, deviceOwnerUserId);
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
- } catch (RemoteException e) {
- throw new IllegalStateException("Failed reactivating backup service.", e);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
}
}
+ private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) {
+ if (admin != null) {
+ admin.disableCamera = false;
+ admin.userRestrictions = null;
+ admin.forceEphemeralUsers = false;
+ mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
+ }
+ clearUserPoliciesLocked(userId);
+
+ mOwners.clearDeviceOwner();
+ mOwners.writeDeviceOwner();
+ updateDeviceOwnerLocked();
+ disableSecurityLoggingIfNotCompliant();
+ try {
+ // Reactivate backup service.
+ mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Failed reactivating backup service.", e);
+ }
+ }
+
@Override
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
if (!mHasFeature) {
@@ -5794,14 +5847,9 @@
final ActiveAdmin admin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
synchronized (this) {
- admin.disableCamera = false;
- admin.userRestrictions = null;
- clearUserPoliciesLocked(userId);
- mOwners.removeProfileOwner(userId);
- mOwners.writeProfileOwner(userId);
-
final long ident = mInjector.binderClearCallingIdentity();
try {
+ clearProfileOwnerLocked(admin, userId);
removeActiveAdminLocked(who, userId);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
@@ -5809,6 +5857,16 @@
}
}
+ public void clearProfileOwnerLocked(ActiveAdmin admin, int userId) {
+ if (admin != null) {
+ admin.disableCamera = false;
+ admin.userRestrictions = null;
+ }
+ clearUserPoliciesLocked(userId);
+ mOwners.removeProfileOwner(userId);
+ mOwners.writeProfileOwner(userId);
+ }
+
@Override
public void setDeviceOwnerLockScreenInfo(ComponentName who, CharSequence info) {
Preconditions.checkNotNull(who, "ComponentName is null");
@@ -5842,15 +5900,13 @@
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
saveSettingsLocked(userId);
- final long ident = mInjector.binderClearCallingIdentity();
try {
mIPackageManager.updatePermissionFlagsForAllApps(
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
0 /* flagValues */, userId);
pushUserRestrictions(userId);
} catch (RemoteException re) {
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
+ // Shouldn't happen.
}
}
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index c6d5a7e..723be24 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -126,8 +126,8 @@
// This client's PID
private final int mPid;
// List of all receivers for this client
- private final ArrayList<IMidiDeviceListener> mListeners
- = new ArrayList<IMidiDeviceListener>();
+ private final HashMap<IBinder, IMidiDeviceListener> mListeners
+ = new HashMap<IBinder, IMidiDeviceListener>();
// List of all device connections for this client
private final HashMap<IBinder, DeviceConnection> mDeviceConnections
= new HashMap<IBinder, DeviceConnection>();
@@ -143,11 +143,13 @@
}
public void addListener(IMidiDeviceListener listener) {
- mListeners.add(listener);
+ // Use asBinder() so that we can match it in removeListener().
+ // The listener proxy objects themselves do not match.
+ mListeners.put(listener.asBinder(), listener);
}
public void removeListener(IMidiDeviceListener listener) {
- mListeners.remove(listener);
+ mListeners.remove(listener.asBinder());
if (mListeners.size() == 0 && mDeviceConnections.size() == 0) {
close();
}
@@ -184,7 +186,7 @@
MidiDeviceInfo deviceInfo = device.getDeviceInfo();
try {
- for (IMidiDeviceListener listener : mListeners) {
+ for (IMidiDeviceListener listener : mListeners.values()) {
listener.onDeviceAdded(deviceInfo);
}
} catch (RemoteException e) {
@@ -198,7 +200,7 @@
MidiDeviceInfo deviceInfo = device.getDeviceInfo();
try {
- for (IMidiDeviceListener listener : mListeners) {
+ for (IMidiDeviceListener listener : mListeners.values()) {
listener.onDeviceRemoved(deviceInfo);
}
} catch (RemoteException e) {
@@ -211,7 +213,7 @@
if (!device.isUidAllowed(mUid)) return;
try {
- for (IMidiDeviceListener listener : mListeners) {
+ for (IMidiDeviceListener listener : mListeners.values()) {
listener.onDeviceStatusChanged(status);
}
} catch (RemoteException e) {
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 7ffdb35..59c6970 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -28,10 +28,22 @@
LOCAL_CERTIFICATE := platform
-LOCAL_JNI_SHARED_LIBRARIES := \
- libapfjni \
+# These are not normally accessible from apps so they must be explicitly included.
+LOCAL_JNI_SHARED_LIBRARIES := libservicestestsjni \
+ libbacktrace \
+ libbase \
+ libbinder \
libc++ \
- libnativehelper
+ libcutils \
+ liblog \
+ liblzma \
+ libnativehelper \
+ libnetdaidl \
+ libui \
+ libunwind \
+ libutils
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_PACKAGE)
@@ -45,22 +57,24 @@
LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS := -Wall -Werror
+LOCAL_CFLAGS := -Wall -Wextra -Werror
LOCAL_C_INCLUDES := \
libpcap \
hardware/google/apf
-LOCAL_SRC_FILES := apf_jni.cpp
+LOCAL_SRC_FILES := $(call all-cpp-files-under)
LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libcutils \
libnativehelper \
- liblog
+ libnetdaidl
LOCAL_STATIC_LIBRARIES := \
libpcap \
libapf
-LOCAL_MODULE := libapfjni
+LOCAL_MODULE := libservicestestsjni
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/tests/servicestests/jni/UidRangeTest.cpp b/services/tests/servicestests/jni/UidRangeTest.cpp
new file mode 100644
index 0000000..7941731
--- /dev/null
+++ b/services/tests/servicestests/jni/UidRangeTest.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+
+#include <binder/Parcel.h>
+
+#include "UidRangeTest.h"
+
+using android::net::UidRange;
+
+extern "C"
+JNIEXPORT jbyteArray Java_android_net_UidRangeTest_readAndWriteNative(JNIEnv* env, jclass,
+ jbyteArray inParcel) {
+ const UidRange range = unmarshall(env, inParcel);
+ return marshall(env, range);
+}
+
+extern "C"
+JNIEXPORT jint Java_android_net_UidRangeTest_getStart(JNIEnv* env, jclass, jbyteArray inParcel) {
+ const UidRange range = unmarshall(env, inParcel);
+ return range.getStart();
+}
+
+extern "C"
+JNIEXPORT jint Java_android_net_UidRangeTest_getStop(JNIEnv* env, jclass, jbyteArray inParcel) {
+ const UidRange range = unmarshall(env, inParcel);
+ return range.getStop();
+}
+
+
+/**
+ * Reads exactly one UidRange from 'parcelData' assuming that it is a Parcel. Any bytes afterward
+ * are ignored.
+ */
+UidRange unmarshall(JNIEnv* env, jbyteArray parcelData) {
+ const int length = env->GetArrayLength(parcelData);
+
+ std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
+ env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
+
+ android::Parcel p;
+ p.setData(bytes.get(), length);
+
+ UidRange range;
+ range.readFromParcel(&p);
+ return range;
+}
+
+/**
+ * Creates a Java byte[] array and writes the contents of 'range' to it as a Parcel containing
+ * exactly one object.
+ *
+ * Every UidRange maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
+ * 'unmarshall(e, marshall(e, x))' should be fixed points.
+ */
+jbyteArray marshall(JNIEnv* env, const UidRange& range) {
+ android::Parcel p;
+ range.writeToParcel(&p);
+ const int length = p.dataSize();
+
+ jbyteArray parcelData = env->NewByteArray(length);
+ env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
+
+ return parcelData;
+}
diff --git a/services/tests/servicestests/jni/UidRangeTest.h b/services/tests/servicestests/jni/UidRangeTest.h
new file mode 100644
index 0000000..b7e7453
--- /dev/null
+++ b/services/tests/servicestests/jni/UidRangeTest.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_NET_UIDRANGETEST_H_
+#define _ANDROID_NET_UIDRANGETEST_H_
+
+#include <jni.h>
+
+#include "android/net/UidRange.h"
+
+android::net::UidRange unmarshall(JNIEnv* env, jbyteArray parcelData);
+
+jbyteArray marshall(JNIEnv* env, const android::net::UidRange& range);
+
+extern "C"
+JNIEXPORT jbyteArray Java_android_net_UidRangeTest_readAndWriteNative(JNIEnv* env, jclass,
+ jbyteArray inParcel);
+
+extern "C"
+JNIEXPORT jint Java_android_net_UidRangeTest_getStart(JNIEnv* env, jclass, jbyteArray inParcel);
+
+extern "C"
+JNIEXPORT jint Java_android_net_UidRangeTest_getStop(JNIEnv* env, jclass, jbyteArray inParcel);
+
+#endif // _ANDROID_NET_UIDRANGETEST_H_
diff --git a/services/tests/servicestests/src/android/net/UidRangeTest.java b/services/tests/servicestests/src/android/net/UidRangeTest.java
new file mode 100644
index 0000000..221fe0f
--- /dev/null
+++ b/services/tests/servicestests/src/android/net/UidRangeTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 android.net;
+
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class UidRangeTest extends TestCase {
+
+ static {
+ System.loadLibrary("servicestestsjni");
+ }
+
+ private static native byte[] readAndWriteNative(byte[] inParcel);
+ private static native int getStart(byte[] inParcel);
+ private static native int getStop(byte[] inParcel);
+
+ @SmallTest
+ public void testNativeParcelUnparcel() {
+ UidRange original = new UidRange(1234, Integer.MAX_VALUE);
+
+ byte[] inParcel = marshall(original);
+ byte[] outParcel = readAndWriteNative(inParcel);
+ UidRange roundTrip = unmarshall(outParcel);
+
+ assertEquals(original, roundTrip);
+ assertArrayEquals(inParcel, outParcel);
+ }
+
+ @SmallTest
+ public void testIndividualNativeFields() {
+ UidRange original = new UidRange(0x11115678, 0x22224321);
+ byte[] originalBytes = marshall(original);
+
+ assertEquals(original.start, getStart(originalBytes));
+ assertEquals(original.stop, getStop(originalBytes));
+ }
+
+ @SmallTest
+ public void testSingleItemUidRangeAllowed() {
+ new UidRange(123, 123);
+ new UidRange(0, 0);
+ new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ @SmallTest
+ public void testNegativeUidsDisallowed() {
+ try {
+ new UidRange(-2, 100);
+ fail("Exception not thrown for negative start UID");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ new UidRange(-200, -100);
+ fail("Exception not thrown for negative stop UID");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @SmallTest
+ public void testStopLessThanStartDisallowed() {
+ final int x = 4195000;
+ try {
+ new UidRange(x, x - 1);
+ fail("Exception not thrown for negative-length UID range");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * Write a {@link UidRange} into an empty parcel and return the underlying data.
+ *
+ * @see unmarshall(byte[])
+ */
+ private static byte[] marshall(UidRange range) {
+ Parcel p = Parcel.obtain();
+ range.writeToParcel(p, /* flags */ 0);
+ p.setDataPosition(0);
+ return p.marshall();
+ }
+
+ /**
+ * Read raw bytes into a parcel, and read a {@link UidRange} back out of them.
+ *
+ * @see marshall(UidRange)
+ */
+ private static UidRange unmarshall(byte[] data) {
+ Parcel p = Parcel.obtain();
+ p.unmarshall(data, 0, data.length);
+ p.setDataPosition(0);
+ return UidRange.CREATOR.createFromParcel(p);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/ApfTest.java b/services/tests/servicestests/src/com/android/server/ApfTest.java
index 640a6c9..9ba27cb 100644
--- a/services/tests/servicestests/src/com/android/server/ApfTest.java
+++ b/services/tests/servicestests/src/com/android/server/ApfTest.java
@@ -43,7 +43,7 @@
public void setUp() throws Exception {
super.setUp();
// Load up native shared library containing APF interpreter exposed via JNI.
- System.loadLibrary("apfjni");
+ System.loadLibrary("servicestestsjni");
}
// Expected return codes from APF interpreter.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5ac697f..15d76fd 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -630,6 +630,20 @@
public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
/**
+ * If carriers require differentiate un-provisioned status: cold sim or out of credit sim
+ * a package name and activity name can be provided to launch a supported carrier application
+ * that check the sim provisioning status
+ * The first element is the package name and the second element is the activity name
+ * of the provisioning app
+ * example:
+ * <item>com.google.android.carrierPackageName</item>
+ * <item>com.google.android.carrierPackageName.CarrierActivityName</item>
+ * @hide
+ */
+ public static final String KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY =
+ "sim_state_detection_carrier_app_string_array";
+
+ /**
* Determines whether the carrier supports making non-emergency phone calls while the phone is
* in emergency callback mode. Default value is {@code true}, meaning that non-emergency calls
* are allowed in emergency callback mode.
@@ -798,6 +812,10 @@
sDefaults.putString(KEY_MMS_USER_AGENT_STRING, "");
sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true);
sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false);
+
+ // Used for Sim card State detection app
+ sDefaults.putStringArray(KEY_SIM_PROVISIONING_STATUS_DETECTION_CARRIER_APP_STRING_ARRAY,
+ null);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 6229ed9..b5cf212e 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -90,6 +90,14 @@
private int mDataRoaming;
/**
+ * Sim Provisioning Status:
+ * {@See SubscriptionManager#SIM_PROVISIONED}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
+ */
+ private int mSimProvisioningStatus;
+
+ /**
* SIM Icon bitmap
*/
private Bitmap mIconBitmap;
@@ -114,7 +122,7 @@
*/
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
- Bitmap icon, int mcc, int mnc, String countryIso) {
+ Bitmap icon, int mcc, int mnc, String countryIso, int simProvisioningStatus) {
this.mId = id;
this.mIccId = iccId;
this.mSimSlotIndex = simSlotIndex;
@@ -128,6 +136,7 @@
this.mMcc = mcc;
this.mMnc = mnc;
this.mCountryIso = countryIso;
+ this.mSimProvisioningStatus = simProvisioningStatus;
}
/**
@@ -264,6 +273,17 @@
}
/**
+ * @return Sim Provisioning Status
+ * {@See SubscriptionManager#SIM_PROVISIONED}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
+ * @hide
+ */
+ public int getSimProvisioningStatus() {
+ return this.mSimProvisioningStatus;
+ }
+
+ /**
* @return the MCC.
*/
public int getMcc() {
@@ -299,10 +319,12 @@
int mcc = source.readInt();
int mnc = source.readInt();
String countryIso = source.readString();
+ int simProvisioningStatus = source.readInt();
Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
- nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso);
+ nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
+ simProvisioningStatus);
}
@Override
@@ -325,6 +347,7 @@
dest.writeInt(mMcc);
dest.writeInt(mMnc);
dest.writeString(mCountryIso);
+ dest.writeInt(mSimProvisioningStatus);
mIconBitmap.writeToParcel(dest, flags);
}
@@ -355,6 +378,6 @@
+ " displayName=" + mDisplayName + " carrierName=" + mCarrierName
+ " nameSource=" + mNameSource + " iconTint=" + mIconTint
+ " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
- + " mnc " + mMnc + "}";
+ + " mnc " + mMnc + " SimProvisioningStatus " + mSimProvisioningStatus +"}";
}
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index f3b0ce2..c49966a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -232,6 +232,22 @@
/** Indicates that data roaming is disabled for a subscription */
public static final int DATA_ROAMING_DISABLE = 0;
+ /** Sim provisioning status: provisioned */
+ /** @hide */
+ public static final int SIM_PROVISIONED = 0;
+
+ /** Sim provisioning status: un-provisioned due to cold sim */
+ /** @hide */
+ public static final int SIM_UNPROVISIONED_COLD = 1;
+
+ /** Sim provisioning status: un-provisioned due to out of credit */
+ /** @hide */
+ public static final int SIM_UNPROVISIONED_OUT_OF_CREDIT = 2;
+
+ /** Maximum possible sim provisioning status */
+ /** @hide */
+ public static final int MAX_SIM_PROVISIONING_STATUS = SIM_UNPROVISIONED_OUT_OF_CREDIT;
+
/** @hide */
public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE;
@@ -250,6 +266,13 @@
public static final String MNC = "mnc";
/**
+ * TelephonyProvider column name for the sim provisioning status associated with a SIM.
+ * <P>Type: INTEGER (int)</P>
+ * @hide
+ */
+ public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status";
+
+ /**
* TelephonyProvider column name for extreme threat in CB settings
* @hide
*/
@@ -820,6 +843,40 @@
}
/**
+ * Set Sim Provisioning Status by subscription ID
+ * @param simProvisioningStatus with the subscription
+ * {@See SubscriptionManager#SIM_PROVISIONED}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
+ * @param subId the unique SubInfoRecord index in database
+ * @return the number of records updated
+ * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * @hide
+ */
+ public int setSimProvisioningStatus(int simProvisioningStatus, int subId) {
+ if (VDBG) {
+ logd("[setSimProvisioningStatus]+ status:" + simProvisioningStatus + " subId:" + subId);
+ }
+ if (simProvisioningStatus < 0 || simProvisioningStatus > MAX_SIM_PROVISIONING_STATUS ||
+ !isValidSubscriptionId(subId)) {
+ logd("[setSimProvisioningStatus]- fail");
+ return -1;
+ }
+
+ int result = 0;
+
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ result = iSub.setSimProvisioningStatus(simProvisioningStatus, subId);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ return result;
+ }
+
+ /**
* Get slotId associated with the subscription.
* @return slotId as a positive integer or a negative value if an error either
* SIM_NOT_INSERTED or < 0 if an invalid slot index
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index ccabace..e4981ce 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -103,6 +103,7 @@
public static final int EVENT_DATA_RAT_CHANGED = BASE + 41;
public static final int CMD_CLEAR_PROVISIONING_SPINNER = BASE + 42;
public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 43;
+ public static final int EVENT_REDIRECTION_DETECTED = BASE + 44;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index f6aef08..c61ed2a 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -118,6 +118,17 @@
int setDisplayName(String displayName, int subId);
/**
+ * Set Sim Provisioning Status by subscription ID
+ * @param simProvisionStatus with the subscription:
+ * {@See SubscriptionManager#SIM_PROVISIONED}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
+ * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
+ * @param subId the unique SubInfoRecord index in database
+ * @return the number of records updated
+ */
+ int setSimProvisioningStatus(int simProvisioningStatus, int subId);
+
+ /**
* Set display name by simInfo index with name source
* @param displayName the display name of SIM card
* @param subId the unique SubscriptionInfo index in database
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index c70f8cf..eafb3d4 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -395,4 +395,32 @@
*/
public static final String ACTION_SET_RADIO_CAPABILITY_FAILED =
"android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED";
+
+ /**
+ * <p>Broadcast Action: when data connections get redirected with validation failure.
+ * intended for sim/account status checks and only sent to the specified carrier app
+ * feedback is via carrier/system APIs to report cold-sim, out-of-credit-sim, etc
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li>redirectUrl</li><dd>A string with the redirection url info.</dd>
+ * <li>subId</li><dd>Sub Id which associated the data redirection.</dd>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system.</p>
+ */
+ public static final String ACTION_DATA_CONNECTION_REDIRECTED =
+ "android.intent.action.REDIRECTION_DETECTED";
+ /**
+ * <p>Broadcast Action: when data connections setup fails.
+ * intended for sim/account status checks and only sent to the specified carrier app
+ * feedback is via carrier/system APIs to report cold-sim, out-of-credit-sim, etc
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li>apnType</li><dd>A string with the apn type.</dd>
+ * <li>errorCode</li><dd>A integer with dataFailCause.</dd>
+ * <li>subId</dt><li>Sub Id which associated the data redirection.</dd>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system. </p>
+ */
+ public static final String ACTION_REQUEST_NETWORK_FAILED =
+ "android.intent.action.REQUEST_NETWORK_FAILED";
}