diff options
116 files changed, 2529 insertions, 1233 deletions
diff --git a/api/current.txt b/api/current.txt index d5f36bdb081f..d3ee682370b9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -19652,6 +19652,7 @@ package android.media { field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR; field public static final int ENCODING_AC3 = 5; // 0x5 field public static final int ENCODING_DEFAULT = 1; // 0x1 + field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe field public static final int ENCODING_DTS = 7; // 0x7 field public static final int ENCODING_DTS_HD = 8; // 0x8 field public static final int ENCODING_E_AC3 = 6; // 0x6 diff --git a/api/system-current.txt b/api/system-current.txt index 16c75cc5d747..13ad2d666dcb 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -21160,6 +21160,7 @@ package android.media { field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR; field public static final int ENCODING_AC3 = 5; // 0x5 field public static final int ENCODING_DEFAULT = 1; // 0x1 + field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe field public static final int ENCODING_DTS = 7; // 0x7 field public static final int ENCODING_DTS_HD = 8; // 0x8 field public static final int ENCODING_E_AC3 = 6; // 0x6 diff --git a/api/test-current.txt b/api/test-current.txt index 7fdbb6411ef4..c6359dd4d1e9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -19722,6 +19722,7 @@ package android.media { field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR; field public static final int ENCODING_AC3 = 5; // 0x5 field public static final int ENCODING_DEFAULT = 1; // 0x1 + field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe field public static final int ENCODING_DTS = 7; // 0x7 field public static final int ENCODING_DTS_HD = 8; // 0x8 field public static final int ENCODING_E_AC3 = 6; // 0x6 diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 23fea7133015..af981f69d3b6 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -93,7 +93,8 @@ public class ActivityManager { @IntDef({ BUGREPORT_OPTION_FULL, BUGREPORT_OPTION_INTERACTIVE, - BUGREPORT_OPTION_REMOTE + BUGREPORT_OPTION_REMOTE, + BUGREPORT_OPTION_WEAR }) public @interface BugreportMode {} /** @@ -114,6 +115,11 @@ public class ActivityManager { * @hide */ public static final int BUGREPORT_OPTION_REMOTE = 2; + /** + * Takes a bugreport on a wearable device. + * @hide + */ + public static final int BUGREPORT_OPTION_WEAR = 3; /** * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java index 8692336439f9..9fa8a5d2faee 100644 --- a/core/java/android/app/ApplicationErrorReport.java +++ b/core/java/android/app/ApplicationErrorReport.java @@ -345,7 +345,7 @@ public class ApplicationErrorReport implements Parcelable { PrintWriter pw = new FastPrintWriter(sw, false, 256); tr.printStackTrace(pw); pw.flush(); - stackTrace = sw.toString(); + stackTrace = sanitizeString(sw.toString()); exceptionMessage = tr.getMessage(); // Populate fields with the "root cause" exception @@ -374,6 +374,29 @@ public class ApplicationErrorReport implements Parcelable { throwMethodName = "unknown"; throwLineNumber = 0; } + + exceptionMessage = sanitizeString(exceptionMessage); + } + + /** + * Ensure that the string is of reasonable size, truncating from the middle if needed. + */ + private String sanitizeString(String s) { + int prefixLength = 10 * 1024; + int suffixLength = 10 * 1024; + int acceptableLength = prefixLength + suffixLength; + + if (s != null && s.length() > acceptableLength) { + String replacement = + "\n[TRUNCATED " + (s.length() - acceptableLength) + " CHARS]\n"; + + StringBuilder sb = new StringBuilder(acceptableLength + replacement.length()); + sb.append(s.substring(0, prefixLength)); + sb.append(replacement); + sb.append(s.substring(s.length() - suffixLength)); + return sb.toString(); + } + return s; } /** diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index fa943f203a6e..2e37db2fef24 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3519,6 +3519,8 @@ public class Notification implements Parcelable boolean validRemoteInput = false; int N = mActions.size(); + boolean emphazisedMode = mN.fullScreenIntent != null; + big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode); if (N > 0) { big.setViewVisibility(R.id.actions_container, View.VISIBLE); big.setViewVisibility(R.id.actions, View.VISIBLE); @@ -3529,7 +3531,8 @@ public class Notification implements Parcelable Action action = mActions.get(i); validRemoteInput |= hasValidRemoteInput(action); - final RemoteViews button = generateActionButton(action); + final RemoteViews button = generateActionButton(action, emphazisedMode, + i % 2 != 0); big.addView(R.id.actions, button); } } else { @@ -3694,11 +3697,13 @@ public class Notification implements Parcelable - private RemoteViews generateActionButton(Action action) { + private RemoteViews generateActionButton(Action action, boolean emphazisedMode, + boolean oddAction) { final boolean tombstone = (action.actionIntent == null); RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), - tombstone ? getActionTombstoneLayoutResource() - : getActionLayoutResource()); + emphazisedMode ? getEmphasizedActionLayoutResource() + : tombstone ? getActionTombstoneLayoutResource() + : getActionLayoutResource()); final Icon ai = action.getIcon(); button.setTextViewText(R.id.action0, processLegacyText(action.title)); if (!tombstone) { @@ -3708,8 +3713,18 @@ public class Notification implements Parcelable if (action.mRemoteInputs != null) { button.setRemoteInputs(R.id.action0, action.mRemoteInputs); } - if (mN.color != COLOR_DEFAULT) { - button.setTextColor(R.id.action0, resolveContrastColor()); + if (emphazisedMode) { + // change the background color + int color = resolveContrastColor(); + if (oddAction) { + color = NotificationColorUtil.lightenColor(color, 10); + } + button.setDrawableParameters(R.id.button_holder, true, -1, color, + PorterDuff.Mode.SRC_ATOP, -1); + } else { + if (mN.color != COLOR_DEFAULT) { + button.setTextColor(R.id.action0, resolveContrastColor()); + } } return button; } @@ -3979,6 +3994,10 @@ public class Notification implements Parcelable return R.layout.notification_material_action; } + private int getEmphasizedActionLayoutResource() { + return R.layout.notification_material_action_emphasized; + } + private int getActionTombstoneLayoutResource() { return R.layout.notification_material_action_tombstone; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 97f936afee99..2a12ac8f0567 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1315,7 +1315,7 @@ public class DevicePolicyManager { /** * Retrieve the current minimum password quality for a particular admin or all admins that set - * retrictions on this user and its participating profiles. Restrictions on profiles that have + * restrictions on this user and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * * <p>This method can be called on the {@link DevicePolicyManager} instance @@ -1379,7 +1379,7 @@ public class DevicePolicyManager { /** * Retrieve the current minimum password length for a particular admin or all admins that set - * retrictions on this user and its participating profiles. Restrictions on profiles that have + * restrictions on this user and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * * <p>This method can be called on the {@link DevicePolicyManager} instance @@ -1442,7 +1442,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of upper case letters required in the password - * for a particular admin or all admins that set retrictions on this user and + * for a particular admin or all admins that set restrictions on this user and * its participating profiles. Restrictions on profiles that have a separate challenge * are not taken into account. * This is the same value as set by @@ -1511,7 +1511,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of lower case letters required in the password - * for a particular admin or all admins that set retrictions on this user + * for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * This is the same value as set by @@ -1580,7 +1580,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of letters required in the password - * for a particular admin or all admins that set retrictions on this user + * for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * This is the same value as set by @@ -1648,7 +1648,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of numerical digits required in the password - * for a particular admin or all admins that set retrictions on this user + * for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * This is the same value as set by @@ -1716,7 +1716,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of symbols required in the password - * for a particular admin or all admins that set retrictions on this user + * for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. This is the same value as * set by {@link #setPasswordMinimumSymbols(ComponentName, int)} @@ -1783,7 +1783,7 @@ public class DevicePolicyManager { /** * Retrieve the current number of non-letter characters required in the password - * for a particular admin or all admins that set retrictions on this user + * for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * This is the same value as set by @@ -1915,7 +1915,7 @@ public class DevicePolicyManager { /** * Get the current password expiration time for a particular admin or all admins that set - * retrictions on this user and its participating profiles. Restrictions on profiles that have + * restrictions on this user and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. If admin is {@code null}, then a composite * of all expiration times is returned - which will be the minimum of all of them. * @@ -1939,7 +1939,7 @@ public class DevicePolicyManager { /** * Retrieve the current password history length for a particular admin or all admins that - * set retrictions on this user and its participating profiles. Restrictions on profiles that + * set restrictions on this user and its participating profiles. Restrictions on profiles that * have a separate challenge are not taken into account. * * <p>This method can be called on the {@link DevicePolicyManager} instance @@ -2121,7 +2121,7 @@ public class DevicePolicyManager { /** * Retrieve the current maximum number of login attempts that are allowed before the device - * or profile is wiped, for a particular admin or all admins that set retrictions on this user + * or profile is wiped, for a particular admin or all admins that set restrictions on this user * and its participating profiles. Restrictions on profiles that have a separate challenge are * not taken into account. * @@ -2262,7 +2262,7 @@ public class DevicePolicyManager { /** * Retrieve the current maximum time to unlock for a particular admin or all admins that set - * retrictions on this user and its participating profiles. Restrictions on profiles that have + * restrictions on this user and its participating profiles. Restrictions on profiles that have * a separate challenge are not taken into account. * * <p>This method can be called on the {@link DevicePolicyManager} instance @@ -3348,7 +3348,7 @@ public class DevicePolicyManager { /** * Determine whether or not features have been disabled in keyguard either by the calling - * admin, if specified, or all admins that set retrictions on this user and its participating + * admin, if specified, or all admins that set restrictions on this user and its participating * profiles. Restrictions on profiles that have a separate challenge are not taken into account. * * <p>This method can be called on the {@link DevicePolicyManager} instance @@ -6436,6 +6436,30 @@ public class DevicePolicyManager { } } + /** + * @hide + * Writes that the provisioning configuration has been applied. + */ + public void setDeviceProvisioningConfigApplied() { + try { + mService.setDeviceProvisioningConfigApplied(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * @hide + * @return whether the provisioning configuration has been applied. + */ + public boolean isDeviceProvisioningConfigApplied() { + try { + return mService.isDeviceProvisioningConfigApplied(); + } 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 4b793d15753a..1036f0499a54 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -303,4 +303,6 @@ interface IDevicePolicyManager { void uninstallPackageWithActiveAdmins(String packageName); boolean isDeviceProvisioned(); + boolean isDeviceProvisioningConfigApplied(); + void setDeviceProvisioningConfigApplied(); } diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java index de52f73fc213..3f8bad15035b 100644 --- a/core/java/android/content/pm/ShortcutServiceInternal.java +++ b/core/java/android/content/pm/ShortcutServiceInternal.java @@ -73,11 +73,4 @@ public abstract class ShortcutServiceInternal { * any locks in this method. */ public abstract void onSystemLocaleChangedNoLock(); - - /** - * Called by PM before sending package broadcasts to other components. PM doesn't hold the PM - * lock, but do not take any locks in here anyway, and don't do any heavy tasks, as doing so - * would slow down all the package broadcasts. - */ - public abstract void onPackageBroadcast(Intent intent); } diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 92134ee01de8..1e44a5ccafc9 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -49,6 +49,10 @@ public class TypedArray { attrs.mLength = len; attrs.mRecycled = false; + // Reset the assets, which may have changed due to configuration changes + // or further resource loading. + attrs.mAssets = res.getAssets(); + final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES; if (attrs.mData.length >= fullLen) { return attrs; @@ -66,7 +70,7 @@ public class TypedArray { private final Resources mResources; private final DisplayMetrics mMetrics; - private final AssetManager mAssets; + private AssetManager mAssets; private boolean mRecycled; @@ -1086,6 +1090,7 @@ public class TypedArray { // These may have been set by the client. mXml = null; mTheme = null; + mAssets = null; mResources.mTypedArrayPool.release(this); } diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java index 43e596fe5566..fcbc962f0743 100644 --- a/core/java/android/hardware/location/ContextHubService.java +++ b/core/java/android/hardware/location/ContextHubService.java @@ -16,6 +16,11 @@ package android.hardware.location; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; + import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; @@ -53,10 +58,14 @@ public class ContextHubService extends IContextHubService.Stub { private static final int PRE_LOADED_APP_MEM_REQ = 0; private static final int MSG_HEADER_SIZE = 4; - private static final int MSG_FIELD_TYPE = 0; - private static final int MSG_FIELD_VERSION = 1; - private static final int MSG_FIELD_HUB_HANDLE = 2; - private static final int MSG_FIELD_APP_INSTANCE = 3; + private static final int HEADER_FIELD_MSG_TYPE = 0; + private static final int HEADER_FIELD_MSG_VERSION = 1; + private static final int HEADER_FIELD_HUB_HANDLE = 2; + private static final int HEADER_FIELD_APP_INSTANCE = 3; + + private static final int HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE; + private static final int HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1; + private static final int MSG_LOAD_APP_HEADER_SIZE = MSG_HEADER_SIZE + 2; private static final int OS_APP_INSTANCE = -1; @@ -146,11 +155,16 @@ public class ContextHubService extends IContextHubService.Stub { return -1; } - int[] msgHeader = new int[MSG_HEADER_SIZE]; - msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle; - msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE; - msgHeader[MSG_FIELD_VERSION] = 0; - msgHeader[MSG_FIELD_TYPE] = MSG_LOAD_NANO_APP; + int[] msgHeader = new int[MSG_LOAD_APP_HEADER_SIZE]; + msgHeader[HEADER_FIELD_HUB_HANDLE] = contextHubHandle; + msgHeader[HEADER_FIELD_APP_INSTANCE] = OS_APP_INSTANCE; + msgHeader[HEADER_FIELD_MSG_VERSION] = 0; + msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_LOAD_NANO_APP; + + long appId = app.getAppId(); + + msgHeader[HEADER_FIELD_LOAD_APP_ID_LO] = (int)(appId & 0xFFFFFFFF); + msgHeader[HEADER_FIELD_LOAD_APP_ID_HI] = (int)((appId >> 32) & 0xFFFFFFFF); if (nativeSendMessage(msgHeader, app.getAppBinary()) != 0) { return -1; @@ -169,12 +183,14 @@ public class ContextHubService extends IContextHubService.Stub { // Call Native interface here int[] msgHeader = new int[MSG_HEADER_SIZE]; - msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB; - msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE; - msgHeader[MSG_FIELD_VERSION] = 0; - msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP; + msgHeader[HEADER_FIELD_HUB_HANDLE] = ANY_HUB; + msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppInstanceHandle; + msgHeader[HEADER_FIELD_MSG_VERSION] = 0; + msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_UNLOAD_NANO_APP; - if (nativeSendMessage(msgHeader, null) != 0) { + byte msg[] = new byte[0]; + + if (nativeSendMessage(msgHeader, msg) != 0) { return -1; } @@ -222,10 +238,10 @@ public class ContextHubService extends IContextHubService.Stub { checkPermissions(); int[] msgHeader = new int[MSG_HEADER_SIZE]; - msgHeader[MSG_FIELD_HUB_HANDLE] = hubHandle; - msgHeader[MSG_FIELD_APP_INSTANCE] = nanoAppHandle; - msgHeader[MSG_FIELD_VERSION] = msg.getVersion(); - msgHeader[MSG_FIELD_TYPE] = msg.getMsgType(); + msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle; + msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppHandle; + msgHeader[HEADER_FIELD_MSG_VERSION] = msg.getVersion(); + msgHeader[HEADER_FIELD_MSG_TYPE] = msg.getMsgType(); return nativeSendMessage(msgHeader, msg.getData()); } @@ -269,15 +285,17 @@ public class ContextHubService extends IContextHubService.Stub { Log.v(TAG, "No message callbacks registered."); return 0; } - ContextHubMessage message = - new ContextHubMessage(header[MSG_FIELD_TYPE], header[MSG_FIELD_VERSION], data); + + ContextHubMessage msg = new ContextHubMessage(header[HEADER_FIELD_MSG_TYPE], + header[HEADER_FIELD_MSG_VERSION], + data); for (int i = 0; i < callbacksCount; ++i) { IContextHubCallback callback = mCallbacksList.getBroadcastItem(i); try { callback.onMessageReceipt( - header[MSG_FIELD_HUB_HANDLE], - header[MSG_FIELD_APP_INSTANCE], - message); + header[HEADER_FIELD_HUB_HANDLE], + header[HEADER_FIELD_APP_INSTANCE], + msg); } catch (RemoteException e) { Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ")."); continue; @@ -308,12 +326,20 @@ public class ContextHubService extends IContextHubService.Stub { return 0; } + private int deleteAppInstance(int appInstanceHandle) { + if (mNanoAppHash.remove(appInstanceHandle) == null) { + return -1; + } + + return 0; + } + private void sendVrStateChangeMessageToApp(NanoAppInstanceInfo app, boolean vrModeEnabled) { int[] msgHeader = new int[MSG_HEADER_SIZE]; - msgHeader[MSG_FIELD_TYPE] = 0; - msgHeader[MSG_FIELD_VERSION] = 0; - msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB; - msgHeader[MSG_FIELD_APP_INSTANCE] = app.getHandle(); + msgHeader[HEADER_FIELD_MSG_TYPE] = 0; + msgHeader[HEADER_FIELD_MSG_VERSION] = 0; + msgHeader[HEADER_FIELD_HUB_HANDLE] = ANY_HUB; + msgHeader[HEADER_FIELD_APP_INSTANCE] = app.getHandle(); byte[] data = new byte[1]; data[0] = (byte) ((vrModeEnabled) ? 1 : 0); diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 80927f368e0c..8d6d9ed567b6 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -286,6 +286,11 @@ public class Environment { } /** {@hide} */ + public static File getReferenceProfile(String packageName) { + return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName); + } + + /** {@hide} */ public static File getDataProfilesDePackageDirectory(int userId, String packageName) { return buildPath(getDataProfilesDeDirectory(userId), packageName); } diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 1158776f5fd1..d587ba80a18c 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -235,7 +235,6 @@ public final class DocumentsContract { * @see #FLAG_DIR_PREFERS_GRID * @see #FLAG_DIR_PREFERS_LAST_MODIFIED * @see #FLAG_VIRTUAL_DOCUMENT - * @see #FLAG_ARCHIVE * @see #FLAG_SUPPORTS_COPY * @see #FLAG_SUPPORTS_MOVE * @see #FLAG_SUPPORTS_REMOVE @@ -326,7 +325,7 @@ public final class DocumentsContract { * Flag indicating that a document can be renamed. * * @see #COLUMN_FLAGS - * @see DocumentsContract#renameDocument(ContentProviderClient, Uri, + * @see DocumentsContract#renameDocument(ContentResolver, Uri, * String) * @see DocumentsProvider#renameDocument(String, String) */ @@ -337,7 +336,7 @@ public final class DocumentsContract { * within the same document provider. * * @see #COLUMN_FLAGS - * @see DocumentsContract#copyDocument(ContentProviderClient, Uri, Uri) + * @see DocumentsContract#copyDocument(ContentResolver, Uri, Uri) * @see DocumentsProvider#copyDocument(String, String) */ public static final int FLAG_SUPPORTS_COPY = 1 << 7; @@ -347,7 +346,7 @@ public final class DocumentsContract { * within the same document provider. * * @see #COLUMN_FLAGS - * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri, Uri) + * @see DocumentsContract#moveDocument(ContentResolver, Uri, Uri, Uri) * @see DocumentsProvider#moveDocument(String, String, String) */ public static final int FLAG_SUPPORTS_MOVE = 1 << 8; @@ -368,7 +367,7 @@ public final class DocumentsContract { * Flag indicating that a document can be removed from a parent. * * @see #COLUMN_FLAGS - * @see DocumentsContract#removeDocument(ContentProviderClient, Uri, Uri) + * @see DocumentsContract#removeDocument(ContentResolver, Uri, Uri) * @see DocumentsProvider#removeDocument(String, String) */ public static final int FLAG_SUPPORTS_REMOVE = 1 << 10; @@ -870,7 +869,7 @@ public final class DocumentsContract { * Test if the given URI represents a {@link Document} tree. * * @see #buildTreeDocumentUri(String, String) - * @see #getTreeDocumentId(Uri, String) + * @see #getTreeDocumentId(Uri) */ public static boolean isTreeUri(Uri uri) { final List<String> paths = uri.getPathSegments(); diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 6911b0161704..69960b04518a 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -20,6 +20,8 @@ import android.app.ActivityManager; import android.app.NotificationManager.Policy; import android.content.ComponentName; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; import android.os.Parcel; @@ -118,6 +120,7 @@ public class ZenModeConfig implements Parcelable { private static final String RULE_ATT_ZEN = "zen"; private static final String RULE_ATT_CONDITION_ID = "conditionId"; private static final String RULE_ATT_CREATION_TIME = "creationTime"; + private static final String RULE_ATT_ENABLER = "enabler"; public boolean allowCalls = DEFAULT_ALLOW_CALLS; public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS; @@ -502,6 +505,7 @@ public class ZenModeConfig implements Parcelable { rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID); rt.component = safeComponentName(parser, RULE_ATT_COMPONENT); rt.creationTime = safeLong(parser, RULE_ATT_CREATION_TIME, 0); + rt.enabler = parser.getAttributeValue(null, RULE_ATT_ENABLER); rt.condition = readConditionXml(parser); return rt; } @@ -520,6 +524,9 @@ public class ZenModeConfig implements Parcelable { out.attribute(null, RULE_ATT_CONDITION_ID, rule.conditionId.toString()); } out.attribute(null, RULE_ATT_CREATION_TIME, Long.toString(rule.creationTime)); + if (rule.enabler != null) { + out.attribute(null, RULE_ATT_ENABLER, rule.enabler); + } if (rule.condition != null) { writeConditionXml(rule.condition, out); } @@ -989,6 +996,25 @@ public class ZenModeConfig implements Parcelable { return UUID.randomUUID().toString().replace("-", ""); } + private static String getOwnerCaption(Context context, String owner) { + final PackageManager pm = context.getPackageManager(); + try { + final ApplicationInfo info = pm.getApplicationInfo(owner, 0); + if (info != null) { + final CharSequence seq = info.loadLabel(pm); + if (seq != null) { + final String str = seq.toString().trim(); + if (str.length() > 0) { + return str; + } + } + } + } catch (Throwable e) { + Slog.w(TAG, "Error loading owner caption", e); + } + return ""; + } + public static String getConditionSummary(Context context, ZenModeConfig config, int userHandle, boolean shortVersion) { return getConditionLine(context, config, userHandle, false /*useLine1*/, shortVersion); @@ -997,23 +1023,28 @@ public class ZenModeConfig implements Parcelable { private static String getConditionLine(Context context, ZenModeConfig config, int userHandle, boolean useLine1, boolean shortVersion) { if (config == null) return ""; + String summary = ""; if (config.manualRule != null) { final Uri id = config.manualRule.conditionId; - if (id == null) { - return context.getString(com.android.internal.R.string.zen_mode_forever); - } - final long time = tryParseCountdownConditionId(id); - Condition c = config.manualRule.condition; - if (time > 0) { - final long now = System.currentTimeMillis(); - final long span = time - now; - c = toTimeCondition(context, time, Math.round(span / (float) MINUTES_MS), - userHandle, shortVersion); + if (config.manualRule.enabler != null) { + summary = getOwnerCaption(context, config.manualRule.enabler); + } else { + if (id == null) { + summary = context.getString(com.android.internal.R.string.zen_mode_forever); + } else { + final long time = tryParseCountdownConditionId(id); + Condition c = config.manualRule.condition; + if (time > 0) { + final long now = System.currentTimeMillis(); + final long span = time - now; + c = toTimeCondition(context, time, Math.round(span / (float) MINUTES_MS), + userHandle, shortVersion); + } + final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary; + summary = TextUtils.isEmpty(rt) ? "" : rt; + } } - final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary; - return TextUtils.isEmpty(rt) ? "" : rt; } - String summary = ""; for (ZenRule automaticRule : config.automaticRules.values()) { if (automaticRule.isAutomaticActive()) { if (summary.isEmpty()) { @@ -1023,6 +1054,7 @@ public class ZenModeConfig implements Parcelable { .getString(R.string.zen_mode_rule_name_combination, summary, automaticRule.name); } + } } return summary; @@ -1038,6 +1070,7 @@ public class ZenModeConfig implements Parcelable { public ComponentName component; // optional public String id; // required for automatic (unique) public long creationTime; // required for automatic + public String enabler; // package name, only used for manual rules. public ZenRule() { } @@ -1055,6 +1088,9 @@ public class ZenModeConfig implements Parcelable { id = source.readString(); } creationTime = source.readLong(); + if (source.readInt() == 1) { + enabler = source.readString(); + } } @Override @@ -1083,6 +1119,12 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(0); } dest.writeLong(creationTime); + if (enabler != null) { + dest.writeInt(1); + dest.writeString(enabler); + } else { + dest.writeInt(0); + } } @Override @@ -1097,6 +1139,7 @@ public class ZenModeConfig implements Parcelable { .append(",component=").append(component) .append(",id=").append(id) .append(",creationTime=").append(creationTime) + .append(",enabler=").append(enabler) .append(']').toString(); } @@ -1143,6 +1186,9 @@ public class ZenModeConfig implements Parcelable { if (creationTime != to.creationTime) { d.addLine(item, "creationTime", creationTime, to.creationTime); } + if (enabler != to.enabler) { + d.addLine(item, "enabler", enabler, to.enabler); + } } @Override @@ -1158,13 +1204,14 @@ public class ZenModeConfig implements Parcelable { && Objects.equals(other.condition, condition) && Objects.equals(other.component, component) && Objects.equals(other.id, id) - && other.creationTime == creationTime; + && other.creationTime == creationTime + && Objects.equals(other.enabler, enabler); } @Override public int hashCode() { return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition, - component, id, creationTime); + component, id, creationTime, enabler); } public boolean isAutomaticActive() { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index a64827af32c2..e6481147c295 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4215,25 +4215,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setAlpha(a.getFloat(attr, 1f)); break; case com.android.internal.R.styleable.View_transformPivotX: - setPivotX(a.getDimensionPixelOffset(attr, 0)); + setPivotX(a.getDimension(attr, 0)); break; case com.android.internal.R.styleable.View_transformPivotY: - setPivotY(a.getDimensionPixelOffset(attr, 0)); + setPivotY(a.getDimension(attr, 0)); break; case com.android.internal.R.styleable.View_translationX: - tx = a.getDimensionPixelOffset(attr, 0); + tx = a.getDimension(attr, 0); transformSet = true; break; case com.android.internal.R.styleable.View_translationY: - ty = a.getDimensionPixelOffset(attr, 0); + ty = a.getDimension(attr, 0); transformSet = true; break; case com.android.internal.R.styleable.View_translationZ: - tz = a.getDimensionPixelOffset(attr, 0); + tz = a.getDimension(attr, 0); transformSet = true; break; case com.android.internal.R.styleable.View_elevation: - elevation = a.getDimensionPixelOffset(attr, 0); + elevation = a.getDimension(attr, 0); transformSet = true; break; case com.android.internal.R.styleable.View_rotation: diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index c42752287a42..209886b27c18 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1731,7 +1731,7 @@ public final class ViewRootImpl implements ViewParent, } boolean hwInitialized = false; - boolean framesChanged = false; + boolean contentInsetsChanged = false; boolean hadSurface = mSurface.isValid(); try { @@ -1771,7 +1771,7 @@ public final class ViewRootImpl implements ViewParent, final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals( mAttachInfo.mOverscanInsets); - boolean contentInsetsChanged = !mPendingContentInsets.equals( + contentInsetsChanged = !mPendingContentInsets.equals( mAttachInfo.mContentInsets); final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals( mAttachInfo.mVisibleInsets); @@ -1821,19 +1821,6 @@ public final class ViewRootImpl implements ViewParent, + mAttachInfo.mVisibleInsets); } - // If any of the insets changed, do a forceLayout on the view so that the - // measure cache is cleared. We might have a pending MSG_RESIZED_REPORT - // that is supposed to take care of it, but since pending insets are - // already modified here, it won't detect the frame change after this. - framesChanged = overscanInsetsChanged - || contentInsetsChanged - || stableInsetsChanged - || visibleInsetsChanged - || outsetsChanged; - if (mAdded && mView != null && framesChanged) { - forceLayout(mView); - } - if (!hadSurface) { if (mSurface.isValid()) { // If we are creating a new surface, then we need to @@ -2017,7 +2004,7 @@ public final class ViewRootImpl implements ViewParent, boolean focusChangedDueToTouchMode = ensureTouchModeLocally( (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0); if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() - || mHeight != host.getMeasuredHeight() || framesChanged || + || mHeight != host.getMeasuredHeight() || contentInsetsChanged || updatedConfiguration) { int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); @@ -2026,7 +2013,7 @@ public final class ViewRootImpl implements ViewParent, + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() - + " framesChanged=" + framesChanged); + + " coveredInsetsChanged=" + contentInsetsChanged); // Ask host how big it wants to be performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); @@ -3186,7 +3173,7 @@ public final class ViewRootImpl implements ViewParent, } focusNode.recycle(); } - if (mAccessibilityFocusedHost != null) { + if ((mAccessibilityFocusedHost != null) && (mAccessibilityFocusedHost != view)) { // Clear accessibility focus in the view. mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks( AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 48bcc0930164..77452ca3a4dc 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -341,6 +341,20 @@ public class NotificationColorUtil { } /** + * Lighten a color by a specified value + * @param baseColor the base color to lighten + * @param amount the amount to lighten the color from 0 to 100. This corresponds to the L + * increase in the LAB color space. + * @return the lightened color + */ + public static int lightenColor(int baseColor, int amount) { + final double[] result = ColorUtilsFromCompat.getTempDouble3Array(); + ColorUtilsFromCompat.colorToLAB(baseColor, result); + result[0] = Math.min(100, result[0] + amount); + return ColorUtilsFromCompat.LABToColor(result[0], result[1], result[2]); + } + + /** * Framework copy of functions needed from android.support.v4.graphics.ColorUtils. */ private static class ColorUtilsFromCompat { @@ -434,7 +448,7 @@ public class NotificationColorUtil { * Convert RGB components to its CIE Lab representative components. * * <ul> - * <li>outLab[0] is L [0 ...1)</li> + * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> @@ -516,7 +530,7 @@ public class NotificationColorUtil { * 2° Standard Observer (1931).</p> * * <ul> - * <li>outLab[0] is L [0 ...1)</li> + * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> @@ -634,7 +648,7 @@ public class NotificationColorUtil { : (XYZ_KAPPA * component + 16) / 116; } - private static double[] getTempDouble3Array() { + public static double[] getTempDouble3Array() { double[] result = TEMP_ARRAY.get(); if (result == null) { result = new double[3]; diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java index 9dd118c5a942..073aac542e31 100644 --- a/core/java/com/android/internal/widget/NotificationActionListLayout.java +++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java @@ -17,11 +17,13 @@ package com.android.internal.widget; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Pair; import android.view.Gravity; +import android.view.RemotableViewMethod; import android.view.View; -import android.view.ViewGroup; +import android.widget.LinearLayout; import android.widget.RemoteViews; import android.widget.TextView; @@ -33,11 +35,14 @@ import java.util.Comparator; * the remaining available width, and the last action consumes the remaining space. */ @RemoteViews.RemoteView -public class NotificationActionListLayout extends ViewGroup { +public class NotificationActionListLayout extends LinearLayout { private int mTotalWidth = 0; private ArrayList<Pair<Integer, TextView>> mMeasureOrderTextViews = new ArrayList<>(); private ArrayList<View> mMeasureOrderOther = new ArrayList<>(); + private boolean mMeasureLinearly; + private int mDefaultPaddingEnd; + private Drawable mDefaultBackground; public NotificationActionListLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -45,6 +50,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mMeasureLinearly) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + return; + } final int N = getChildCount(); int textViews = 0; int otherViews = 0; @@ -186,6 +195,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (mMeasureLinearly) { + super.onLayout(changed, left, top, right, bottom); + return; + } final boolean isLayoutRtl = isLayoutRtl(); final int paddingTop = mPaddingTop; @@ -241,26 +254,24 @@ public class NotificationActionListLayout extends ViewGroup { } @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new MarginLayoutParams(getContext(), attrs); - } - - @Override - protected LayoutParams generateDefaultLayoutParams() { - return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + protected void onFinishInflate() { + super.onFinishInflate(); + mDefaultPaddingEnd = getPaddingEnd(); + mDefaultBackground = getBackground(); } - @Override - protected LayoutParams generateLayoutParams(LayoutParams p) { - if (p instanceof MarginLayoutParams) { - return new MarginLayoutParams((MarginLayoutParams)p); - } - return new MarginLayoutParams(p); - } - - @Override - protected boolean checkLayoutParams(LayoutParams p) { - return p instanceof MarginLayoutParams; + /** + * Set whether the list is in a mode where some actions are emphasized. This will trigger an + * equal measuring where all actions are full height and change a few parameters like + * the padding. + */ + @RemotableViewMethod + public void setEmphasizedMode(boolean emphasizedMode) { + mMeasureLinearly = emphasizedMode; + setPaddingRelative(getPaddingStart(), getPaddingTop(), + emphasizedMode ? 0 : mDefaultPaddingEnd, getPaddingBottom()); + setBackground(emphasizedMode ? null : mDefaultBackground); + requestLayout(); } public static final Comparator<Pair<Integer, TextView>> MEASURE_ORDER_COMPARATOR diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index a56eba6c133f..46f76de87a2f 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -21,28 +21,34 @@ #include <inttypes.h> #include <jni.h> -#include <queue> -#include <unordered_map> +#include <mutex> #include <string.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <unordered_map> +#include <queue> #include <cutils/log.h> #include "JNIHelp.h" #include "core_jni_helpers.h" -static constexpr int OS_APP_ID=-1; +static constexpr int OS_APP_ID = -1; +static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF); + +static constexpr int MIN_APP_ID = 1; +static constexpr int MAX_APP_ID = 128; -static constexpr int MIN_APP_ID=1; -static constexpr int MAX_APP_ID=128; +static constexpr size_t MSG_HEADER_SIZE = 4; +static constexpr size_t HEADER_FIELD_MSG_TYPE = 0; +static constexpr size_t HEADER_FIELD_MSG_VERSION = 1; +static constexpr size_t HEADER_FIELD_HUB_HANDLE = 2; +static constexpr size_t HEADER_FIELD_APP_INSTANCE = 3; -static constexpr size_t MSG_HEADER_SIZE=4; -static constexpr int HEADER_FIELD_MSG_TYPE=0; -//static constexpr int HEADER_FIELD_MSG_VERSION=1; -static constexpr int HEADER_FIELD_HUB_HANDLE=2; -static constexpr int HEADER_FIELD_APP_INSTANCE=3; +static constexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE; +static constexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1; +static constexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2; namespace android { @@ -83,6 +89,7 @@ struct jniInfo_s { jmethodID contextHubServiceMsgReceiptCallback; jmethodID contextHubServiceAddAppInstance; + jmethodID contextHubServiceDeleteAppInstance; }; struct context_hub_info_s { @@ -93,10 +100,53 @@ struct context_hub_info_s { }; struct app_instance_info_s { - uint32_t hubHandle; // Id of the hub this app is on - int instanceId; // systemwide unique instance id - assigned + uint64_t truncName; // Possibly truncated name for logging + uint32_t hubHandle; // Id of the hub this app is on + int instanceId; // system wide unique instance id - assigned struct hub_app_info appInfo; // returned from the HAL - uint64_t truncName; // Possibly truncated name - logging +}; + +/* + * TODO(ashutoshj): From original code review: + * + * So, I feel like we could possible do a better job of organizing this code, + * and being more C++-y. Consider something like this: + * class TxnManager { + * public: + * TxnManager(); + * ~TxnManager(); + * int add(hub_message_e identifier, void *data); + * int close(); + * bool isPending() const; + * int fetchData(hub_message_e *identifier, void **data) const; + * + * private: + * bool mPending; + * mutable std::mutex mLock; + * hub_message_e mIdentifier; + * void *mData; + * }; + * + * And then, for example, we'd have things like: + * TxnManager::TxnManager() : mPending(false), mLock(), mIdentifier(), mData(nullptr) {} + * int TxnManager::add(hub_message_e identifier, void *data) { + * std::lock_guard<std::mutex> lock(mLock); + * mPending = true; + * mData = txnData; + * mIdentifier = txnIdentifier; + * return 0; + * } + * And then calling code would look like: + * if (!db.txnManager.add(CONTEXT_HUB_LOAD_APP, txnInfo)) { + * + * This would make it clearer the nothing is manipulating any state within TxnManager + * unsafely and outside of these couple of calls. + */ +struct txnManager_s { + bool txnPending; // Is a transaction pending + std::mutex m; // mutex for manager + hub_messages_e txnIdentifier; // What are we doing + void *txnData; // Details }; struct contextHubServiceDb_s { @@ -105,12 +155,69 @@ struct contextHubServiceDb_s { jniInfo_s jniInfo; std::queue<int> freeIds; std::unordered_map<int, app_instance_info_s> appInstances; + txnManager_s txnManager; }; } // unnamed namespace static contextHubServiceDb_s db; +static bool initTxnManager() { + txnManager_s *mgr = &db.txnManager; + + mgr->txnData = nullptr; + mgr->txnPending = false; + return true; +} + +static int addTxn(hub_messages_e txnIdentifier, void *txnData) { + txnManager_s *mgr = &db.txnManager; + + std::lock_guard<std::mutex>lock(mgr->m); + + mgr->txnPending = true; + mgr->txnData = txnData; + mgr->txnIdentifier = txnIdentifier; + + return 0; +} + +static int closeTxn() { + txnManager_s *mgr = &db.txnManager; + std::lock_guard<std::mutex>lock(mgr->m); + mgr->txnPending = false; + free(mgr->txnData); + mgr->txnData = nullptr; + + return 0; +} + +static bool isTxnPending() { + txnManager_s *mgr = &db.txnManager; + std::lock_guard<std::mutex>lock(mgr->m); + return mgr->txnPending; +} + +static int fetchTxnData(hub_messages_e *id, void **data) { + txnManager_s *mgr = &db.txnManager; + + if (!id || !data) { + ALOGW("Null params id %p, data %p", id, data); + return -1; + } + + std::lock_guard<std::mutex>lock(mgr->m); + if (!mgr->txnPending) { + ALOGW("No Transactions pending"); + return -1; + } + + // else + *id = mgr->txnIdentifier; + *data = mgr->txnData; + return 0; +} + int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg, void *cookie); @@ -152,13 +259,21 @@ static int get_hub_id_for_hub_handle(int hubHandle) { } } -static int get_hub_id_for_app_instance(int id) { +static int get_hub_handle_for_app_instance(int id) { if (!db.appInstances.count(id)) { ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id); return -1; } - int hubHandle = db.appInstances[id].hubHandle; + return db.appInstances[id].hubHandle; +} + +static int get_hub_id_for_app_instance(int id) { + int hubHandle = get_hub_handle_for_app_instance(id); + + if (hubHandle < 0) { + return -1; + } return db.hubInfo.hubs[hubHandle].hub_id; } @@ -184,7 +299,7 @@ static int set_dest_app(hub_message_t *msg, int id) { return 0; } -static void send_query_for_apps() { +static void query_hub_for_apps(uint64_t appId, uint32_t hubHandle) { hub_message_t msg; query_apps_request_t queryMsg; @@ -194,23 +309,31 @@ static void send_query_for_apps() { msg.message_len = sizeof(queryMsg); msg.message = &queryMsg; + ALOGD("Sending query for apps to hub %" PRIu32, hubHandle); + set_os_app_as_destination(&msg, hubHandle); + if (send_msg_to_hub(&msg, hubHandle) != 0) { + ALOGW("Could not query hub %" PRIu32 " for apps", hubHandle); + } +} + +static void sendQueryForApps(uint64_t appId) { for (int i = 0; i < db.hubInfo.numHubs; i++ ) { - ALOGD("Sending query for apps to hub %d", i); - set_os_app_as_destination(&msg, i); - if (send_msg_to_hub(&msg, i) != 0) { - ALOGW("Could not query hub %i for apps", i); - } + query_hub_for_apps(appId, i); } } static int return_id(int id) { // Note : This method is not thread safe. - // id returned is guarenteed to be in use - db.freeIds.push(id); - return 0; + // id returned is guaranteed to be in use + if (id >= 0) { + db.freeIds.push(id); + return 0; + } + + return -1; } -static int generate_id(void) { +static int generate_id() { // Note : This method is not thread safe. int retVal = -1; @@ -222,23 +345,31 @@ static int generate_id(void) { return retVal; } -int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) { + +static int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, + int appInstanceHandle, JNIEnv *env) { + + ALOGI("Loading App"); + // Not checking if the apps are indeed distinct app_instance_info_s entry; - int appInstanceHandle = generate_id(); - assert(appInfo); - if (appInstanceHandle < 0) { - ALOGE("Cannot find resources to add app instance %d", - appInstanceHandle); - return -1; + if (db.appInstances.count(appInstanceHandle) == 0) { + appInstanceHandle = generate_id(); + if (appInstanceHandle < 0) { + ALOGE("Cannot find resources to add app instance %d", + appInstanceHandle); + return -1; + } } entry.appInfo = *appInfo; + entry.instanceId = appInstanceHandle; entry.truncName = appInfo->app_name.id; entry.hubHandle = hubHandle; + db.appInstances[appInstanceHandle] = entry; // Finally - let the service know of this app instance @@ -254,17 +385,70 @@ int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *en return appInstanceHandle; } -int delete_app_instance(int id) { +int delete_app_instance(int id, JNIEnv *env) { if (!db.appInstances.count(id)) { + ALOGW("Cannot find App id : %d", id); return -1; } return_id(id); db.appInstances.erase(id); + if (env->CallIntMethod(db.jniInfo.jContextHubService, + db.jniInfo.contextHubServiceDeleteAppInstance, + id) != 0) { + ALOGW("Could not delete App id : %d", id); + return -1; + } + + ALOGI("Deleted App id : %d", id); + + return 0; +} + +static int startLoadAppTxn(uint64_t appId, int hubHandle) { + app_instance_info_s *txnInfo = (app_instance_info_s *)malloc(sizeof(app_instance_info_s)); + int instanceId = generate_id(); + + if (!txnInfo || instanceId < 0) { + return_id(instanceId); + free(txnInfo); + return -1; + } + + txnInfo->truncName = appId; + txnInfo->hubHandle = hubHandle; + txnInfo->instanceId = instanceId; + + txnInfo->appInfo.app_name.id = appId; + txnInfo->appInfo.num_mem_ranges = 0; + txnInfo->appInfo.version = -1; // Awaited + + if (!addTxn(CONTEXT_HUB_LOAD_APP, txnInfo)) { + return_id(instanceId); + free(txnInfo); + return -1; + } return 0; } +static int startUnloadAppTxn(uint32_t appInstanceHandle) { + uint32_t *txnData = (uint32_t *) malloc(sizeof(uint32_t)); + if (!txnData) { + ALOGW("Cannot allocate memory to start unload transaction"); + return -1; + } + + *txnData = appInstanceHandle; + + if (addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) { + free(txnData); + ALOGW("Cannot start transaction to unload app"); + return -1; + } + + return 0; +} static void initContextHubService() { int err = 0; @@ -285,6 +469,7 @@ static void initContextHubService() { db.freeIds.push(i); } + initTxnManager(); if (db.hubInfo.contextHubModule) { int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule, &db.hubInfo.hubs); @@ -302,6 +487,7 @@ static void initContextHubService() { for (i = 0; i < db.hubInfo.numHubs; i++) { db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id; + ALOGI("Subscribing to hubHandle %d with OS App name %" PRIu64, i, db.hubInfo.hubs[i].os_app_name.id); if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id, context_hub_callback, &db.hubInfo.cookies[i]) == 0) { @@ -309,7 +495,7 @@ static void initContextHubService() { } } - send_query_for_apps(); + sendQueryForApps(ALL_APPS); } else { ALOGW("No Context Hub Module present"); } @@ -346,7 +532,8 @@ static int onMessageReceipt(uint32_t *header, size_t headerLen, char *msg, size_ return ret; } -int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) { +int handle_query_apps_response(const uint8_t *msg, int msgLen, + uint32_t hubHandle) { JNIEnv *env; if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { return -1; @@ -354,53 +541,201 @@ int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) { int numApps = msgLen/sizeof(hub_app_info); hub_app_info info; - hub_app_info *unalignedInfoAddr = (hub_app_info*)msg; + const hub_app_info *unalignedInfoAddr = (const hub_app_info*)msg; for (int i = 0; i < numApps; i++, unalignedInfoAddr++) { memcpy(&info, unalignedInfoAddr, sizeof(info)); - add_app_instance(&info, hubHandle, env); + // We will only have one instance of the app + // TODO : Change this logic once we support multiple instances of the same app + int appInstance = get_app_instance_for_app_id(info.app_name.id); + add_app_instance(&info, hubHandle, appInstance, env); } return 0; } +static void passOnOsResponse(uint32_t hubHandle, uint32_t msgType, + status_response_t *rsp, int8_t *additionalData, + size_t additionalDataLen) { + JNIEnv *env; -int handle_os_message(uint32_t msgType, uint32_t hubHandle, - char *msg, int msgLen) { - int retVal; + if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { + ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32, msgType); + return; + } - //ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d", - // hubHandle, msgType, msgLen); + uint32_t header[MSG_HEADER_SIZE]; + memset(header, 0, sizeof(header)); - switch(msgType) { - case CONTEXT_HUB_APPS_ENABLE: - retVal = 0; - break; + if (!additionalData) { + additionalDataLen = 0; // clamp + } + int msgLen = 1 + additionalDataLen; - case CONTEXT_HUB_APPS_DISABLE: - retVal = 0; - break; + int8_t *msg = new int8_t[msgLen]; - case CONTEXT_HUB_LOAD_APP: - retVal = 0; - break; + if (!msg) { + ALOGW("Unexpected : Ran out of memory, cannot send response"); + return; + } + + header[HEADER_FIELD_MSG_TYPE] = msgType; + header[HEADER_FIELD_MSG_VERSION] = 0; + header[HEADER_FIELD_HUB_HANDLE] = hubHandle; + header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID; + + msg[0] = rsp->result; + + if (additionalData) { + memcpy(&msg[1], additionalData, additionalDataLen); + } + + jbyteArray jmsg = env->NewByteArray(msgLen); + jintArray jheader = env->NewIntArray(sizeof(header)); + + env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg); + env->SetIntArrayRegion(jheader, 0, sizeof(header), (jint *)header); + + ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32, + header[HEADER_FIELD_MSG_TYPE], header[HEADER_FIELD_APP_INSTANCE], + header[HEADER_FIELD_HUB_HANDLE]); + + env->CallIntMethod(db.jniInfo.jContextHubService, + db.jniInfo.contextHubServiceMsgReceiptCallback, + jheader, jmsg); + + delete[] msg; +} + +void closeUnloadTxn(bool success) { + void *txnData = nullptr; + hub_messages_e txnId; + + if (success && fetchTxnData(&txnId, &txnData) == 0 && + txnId == CONTEXT_HUB_UNLOAD_APP) { + db.appInstances.erase(*(uint32_t *)txnData); + } else { + ALOGW("Could not unload the app successfully ! success %d, txnData %p", success, txnData); + } + + closeTxn(); +} + +void closeLoadTxn(bool success, int *appInstanceHandle) { + void *txnData; + hub_messages_e txnId; + + if (success && fetchTxnData(&txnId, &txnData) == 0 && + txnId == CONTEXT_HUB_LOAD_APP) { + app_instance_info_s *info = (app_instance_info_s *)txnData; + *appInstanceHandle = info->instanceId; + + JNIEnv *env; + if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) { + add_app_instance(&info->appInfo, info->hubHandle, info->instanceId, env); + } else { + ALOGW("Could not attach to JVM !"); + } + sendQueryForApps(info->appInfo.app_name.id); + } else { + ALOGW("Could not load the app successfully ! Unexpected failure"); + } + + closeTxn(); +} + +static bool isValidOsStatus(const uint8_t *msg, size_t msgLen, + status_response_t *rsp) { + // Workaround a bug in some HALs + if (msgLen == 1) { + rsp->result = msg[0]; + return true; + } + + if (!msg || msgLen != sizeof(*rsp)) { + ALOGW("Received invalid response %p of size %zu", msg, msgLen); + return false; + } + + memcpy(rsp, msg, sizeof(*rsp)); + + // No sanity checks on return values + return true; +} + +static void invalidateNanoApps(uint32_t hubHandle) { + JNIEnv *env; + + if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { + ALOGW("Could not attach to JVM !"); + } + + auto end = db.appInstances.end(); + for (auto current = db.appInstances.begin(); current != end; ) { + app_instance_info_s info = current->second; + current++; + if (info.hubHandle == hubHandle) { + delete_app_instance(info.instanceId, env); + } + } +} - case CONTEXT_HUB_UNLOAD_APP: - retVal = 0; - break; +static int handle_os_message(uint32_t msgType, uint32_t hubHandle, + const uint8_t *msg, int msgLen) { + int retVal = -1; - case CONTEXT_HUB_QUERY_APPS: - retVal = handle_query_apps_response(msg, msgLen, hubHandle); - break; + ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d", + hubHandle, msgType, msgLen); - case CONTEXT_HUB_QUERY_MEMORY: - retVal = 0; - break; + struct status_response_t rsp; - default: - retVal = -1; - break; + switch(msgType) { + case CONTEXT_HUB_APPS_ENABLE: + case CONTEXT_HUB_APPS_DISABLE: + case CONTEXT_HUB_LOAD_APP: + case CONTEXT_HUB_UNLOAD_APP: + if (isValidOsStatus(msg, msgLen, &rsp)) { + if (msgType == CONTEXT_HUB_LOAD_APP) { + int appInstanceHandle; + closeLoadTxn(rsp.result == 0, &appInstanceHandle); + passOnOsResponse(hubHandle, msgType, &rsp, (int8_t *)(&appInstanceHandle), + sizeof(appInstanceHandle)); + } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { + closeUnloadTxn(rsp.result == 0); + passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); + } else { + passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); + } + retVal = 0; + } + break; + + case CONTEXT_HUB_QUERY_APPS: + rsp.result = 0; + retVal = handle_query_apps_response(msg, msgLen, hubHandle); + passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); + break; + + case CONTEXT_HUB_QUERY_MEMORY: + // Deferring this use + retVal = 0; + break; + + case CONTEXT_HUB_OS_REBOOT: + if (isValidOsStatus(msg, msgLen, &rsp)) { + rsp.result = 0; + ALOGW("Context Hub handle %d restarted", hubHandle); + passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); + invalidateNanoApps(hubHandle); + query_hub_for_apps(ALL_APPS, hubHandle); + retVal = 0; + } + break; + + default: + retVal = -1; + break; } return retVal; @@ -420,10 +755,12 @@ static bool sanity_check_cookie(void *cookie, uint32_t hub_id) { } } + int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg, void *cookie) { if (!msg) { + ALOGW("NULL message"); return -1; } if (!sanity_check_cookie(cookie, hubId)) { @@ -433,11 +770,12 @@ int context_hub_callback(uint32_t hubId, return -1; } + uint32_t messageType = msg->message_type; uint32_t hubHandle = *(uint32_t*) cookie; if (messageType < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) { - handle_os_message(messageType, hubHandle, (char*) msg->message, msg->message_len); + handle_os_message(messageType, hubHandle, (uint8_t*) msg->message, msg->message_len); } else { int appHandle = get_app_instance_for_app_id(msg->app_name.id); if (appHandle < 0) { @@ -528,7 +866,9 @@ static int init_jni(JNIEnv *env, jobject instance) { env->GetMethodID(db.jniInfo.contextHubServiceClass, "addAppInstance", "(IIJI)I"); - + db.jniInfo.contextHubServiceDeleteAppInstance = + env->GetMethodID(db.jniInfo.contextHubServiceClass, + "deleteAppInstance", "(I)I"); return 0; } @@ -538,8 +878,6 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t jintArray jintBuf; jobjectArray jmemBuf; - int dummyConnectedSensors[] = {1, 2, 3, 4, 5}; - jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass, db.jniInfo.contextHubInfoCtor); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id); @@ -569,11 +907,21 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t hub->max_supported_msg_len); - // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors); - // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, - // hub->connected_sensors); - jintBuf = env->NewIntArray(array_length(dummyConnectedSensors)); - env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors); + jintBuf = env->NewIntArray(hub->num_connected_sensors); + int *connectedSensors = new int[hub->num_connected_sensors]; + + if (!connectedSensors) { + ALOGW("Cannot allocate memory! Unexpected"); + assert(false); + } else { + for (unsigned int i = 0; i < hub->num_connected_sensors; i++) { + connectedSensors[i] = hub->connected_sensors[i].sensor_id; + } + } + + env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, + connectedSensors); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf); env->DeleteLocalRef(jintBuf); @@ -584,6 +932,7 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t env->DeleteLocalRef(jmemBuf); + delete[] connectedSensors; return jHub; } @@ -622,33 +971,96 @@ static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, jbyte *data = env->GetByteArrayElements(data_, 0); int dataBufferLength = env->GetArrayLength(data_); + if (numHeaderElements < MSG_HEADER_SIZE) { + ALOGW("Malformed header len"); + return -1; + } + + uint32_t appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE]; + uint32_t msgType = header[HEADER_FIELD_MSG_TYPE]; + int hubHandle = -1; + int hubId; + uint64_t appId; + + if (msgType == CONTEXT_HUB_UNLOAD_APP) { + hubHandle = get_hub_handle_for_app_instance(appInstanceHandle); + } else if (msgType == CONTEXT_HUB_LOAD_APP) { + if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) { + return -1; + } + uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO]; + uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI]; + appId = appIdHi << 32 | appIdLo; + + hubHandle = header[HEADER_FIELD_HUB_HANDLE]; + } else { + hubHandle = header[HEADER_FIELD_HUB_HANDLE]; + } + + if (hubHandle < 0) { + ALOGD("Invalid hub Handle %d", hubHandle); + return -1; + } + + if (msgType == CONTEXT_HUB_LOAD_APP || + msgType == CONTEXT_HUB_UNLOAD_APP) { + + if (isTxnPending()) { + ALOGW("Cannot load or unload app while a transaction is pending !"); + return -1; + } - if (numHeaderElements >= MSG_HEADER_SIZE) { - bool setAddressSuccess; - int hubId; - hub_message_t msg; + if (msgType == CONTEXT_HUB_LOAD_APP) { + if (startLoadAppTxn(appId, hubHandle) != 0) { + return -1; + } + } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { + if (startUnloadAppTxn(appInstanceHandle) != 0) { + return -1; + } + } + } + + bool setAddressSuccess = false; + hub_message_t msg; + + msg.message_type = msgType; + + if (msgType == CONTEXT_HUB_UNLOAD_APP) { + msg.message_len = sizeof(db.appInstances[appInstanceHandle].appInfo.app_name); + msg.message = &db.appInstances[appInstanceHandle].appInfo.app_name; + setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0); + hubId = get_hub_id_for_hub_handle(hubHandle); + } else { + msg.message_len = dataBufferLength; + msg.message = data; if (header[HEADER_FIELD_APP_INSTANCE] == OS_APP_ID) { - setAddressSuccess = (set_os_app_as_destination(&msg, header[HEADER_FIELD_HUB_HANDLE]) == 0); - hubId = get_hub_id_for_hub_handle(header[HEADER_FIELD_HUB_HANDLE]); + setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0); + hubId = get_hub_id_for_hub_handle(hubHandle); } else { setAddressSuccess = (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0); hubId = get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]); } + } - if (setAddressSuccess && hubId >= 0) { - msg.message_type = header[HEADER_FIELD_MSG_TYPE]; - msg.message_len = dataBufferLength; - msg.message = data; - retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); - } else { - ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d", - header[HEADER_FIELD_APP_INSTANCE], - header[HEADER_FIELD_HUB_HANDLE], - (int)setAddressSuccess); - } + if (setAddressSuccess && hubId >= 0) { + ALOGD("Asking HAL to remove app"); + retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); } else { - ALOGD("Malformed header len"); + ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d", + header[HEADER_FIELD_APP_INSTANCE], + header[HEADER_FIELD_HUB_HANDLE], + (int)setAddressSuccess); + } + + if (retVal != 0) { + ALOGD("Send Message failure - %d", retVal); + if (msgType == CONTEXT_HUB_LOAD_APP) { + closeLoadTxn(false, nullptr); + } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { + closeUnloadTxn(false); + } } env->ReleaseIntArrayElements(header_, header, 0); diff --git a/core/res/res/drawable/notification_material_action_background_emphasized.xml b/core/res/res/drawable/notification_material_action_background_emphasized.xml new file mode 100644 index 000000000000..b7153ba620e3 --- /dev/null +++ b/core/res/res/drawable/notification_material_action_background_emphasized.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="@color/ripple_material_dark"> + <item android:id="@id/mask"> + <color android:color="@color/white" /> + </item> +</ripple> + diff --git a/core/res/res/layout/notification_material_action_emphasized.xml b/core/res/res/layout/notification_material_action_emphasized.xml new file mode 100644 index 000000000000..992e43ede404 --- /dev/null +++ b/core/res/res/layout/notification_material_action_emphasized.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/button_holder" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="#ff000000"> + <Button + style="@android:style/Widget.Material.Light.Button.Borderless.Small" + android:id="@+id/action0" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:textColor="#ffffffff" + android:singleLine="true" + android:ellipsize="end" + android:background="@drawable/notification_material_action_background_emphasized" + /> +</FrameLayout> diff --git a/core/res/res/values-watch/colors_material.xml b/core/res/res/values-watch/colors_material.xml index 91eee7d0039f..45eb9812f137 100644 --- a/core/res/res/values-watch/colors_material.xml +++ b/core/res/res/values-watch/colors_material.xml @@ -20,5 +20,7 @@ <color name="accent_material_dark">#ff5e97f6</color> <color name="accent_material_light">#ff4285f4</color> + <color name="primary_material_dark">#4D4D4D</color> + <color name="button_material_dark">#ff999999</color> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e87bb8173049..674a0d7f61eb 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -764,7 +764,7 @@ 1 - AUTO_MODE_CUSTOM 2 - AUTO_MODE_TWILIGHT --> - <integer name="config_defaultNightDisplayAutoMode">1</integer> + <integer name="config_defaultNightDisplayAutoMode">0</integer> <!-- Default time when Night display is automatically activated. Represented as milliseconds from midnight (e.g. 79200000 == 10pm). --> @@ -2528,6 +2528,9 @@ <!-- Package name for the device provisioning package. --> <string name="config_deviceProvisioningPackage"></string> + <!-- Colon separated list of package names that should be granted DND access --> + <string name="config_defaultDndAccessPackages" translatable="false">com.android.camera2</string> + <!-- User restrictions set when the first user is created. Note: Also update appropriate overlay files. --> <string-array translatable="false" name="config_defaultFirstUserRestrictions"> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f0cfd2b01a20..473796a6b650 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2794,6 +2794,9 @@ <!-- [CHAR LIMIT=200] Body of notification that is shown when performing a system upgrade. --> <string name="android_upgrading_notification_body">Some apps may not work properly until the upgrade finishes</string> + <!-- [CHAR LIMIT=40] Toast that is shown when an app is still upgrading. --> + <string name="app_upgrading_toast"><xliff:g id="application">%1$s</xliff:g> is upgrading\u2026</string> + <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog for each .apk that is optimized. --> <string name="android_upgrading_apk">Optimizing app <xliff:g id="number" example="123">%1$d</xliff:g> of diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 6b064c10447b..3590ac86afd0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2628,6 +2628,8 @@ <!-- Used internally for assistant to launch activity transitions --> <java-symbol type="id" name="cross_task_transition" /> + <java-symbol type="id" name="button_holder" /> + <java-symbol type="bool" name="config_useRoundIcon" /> <!-- For System navigation keys --> @@ -2636,9 +2638,14 @@ <java-symbol type="layout" name="unsupported_display_size_dialog_content" /> <java-symbol type="string" name="unsupported_display_size_message" /> + <java-symbol type="layout" name="notification_material_action_emphasized" /> + <!-- Package name for the device provisioning package --> <java-symbol type="string" name="config_deviceProvisioningPackage" /> + <!-- Colon separated list of package names that should be granted DND access --> + <java-symbol type="string" name="config_defaultDndAccessPackages" /> + <!-- Used for MimeIconUtils. --> <java-symbol type="drawable" name="ic_doc_apk" /> <java-symbol type="drawable" name="ic_doc_audio" /> diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml index d4732f8ba78f..48aca2860edd 100644 --- a/docs/html/_redirects.yaml +++ b/docs/html/_redirects.yaml @@ -1193,3 +1193,5 @@ redirects: to: http://tools.android.com/tech-docs/new-build-system/gradle-experimental/experimental-to-stable-gradle - from: /r/studio-ui/sdk-manager.html to: https://developer.android.com/studio/intro/update.html#sdk-manager +- from: /r/studio-ui/newjclass.html + to: /studio/write/index.html diff --git a/docs/html/distribute/stories/apps.jd b/docs/html/distribute/stories/apps.jd index 9c2e8e9680a4..76e9f5ac368b 100644 --- a/docs/html/distribute/stories/apps.jd +++ b/docs/html/distribute/stories/apps.jd @@ -29,5 +29,5 @@ page.metaDescription=How app developers are making use of localization, tablet f data-sortOrder="-timestamp" data-cardSizes="6x6" data-items-per-page="15" - data-initial-results="3"></div> + data-initial-results="6"></div> </div></section>
\ No newline at end of file diff --git a/docs/html/distribute/stories/apps/aftenposten.jd b/docs/html/distribute/stories/apps/aftenposten.jd new file mode 100644 index 000000000000..f1f388e2b6bd --- /dev/null +++ b/docs/html/distribute/stories/apps/aftenposten.jd @@ -0,0 +1,80 @@ +page.title=Aftenposten Improves Retention by Allowing Readers to Customize Notifications +page.metaDescription=Aftenposten upgraded their app and improved user retention. +page.tags="developerstory", "apps", "googleplay" +page.image=images/cards/distribute/stories/aftenposten.png +page.timestamp=1468270114 + +@jd:body + +<div class="figure" style="width:113px"> + <img src="{@docRoot}images/distribute/stories/aftenposten-icon.png" height= + "106"> +</div> + +<h3> + Background +</h3> + +<p> + Aftenposten is one of the largest newspapers in Norway. Their <a class= + "external-link" href= + "https://play.google.com/store/apps/details?id=no.cita&e=-EnableAppDetailsPageRedesign"> + news app</a> was released on Android in 2013. +</p> + +<p> + Aftenposten found that sending too many notifications, with no user control + over the default <em>on</em> setting or differentiation between general and + breaking news, caused many people to uninstall their app. They changed the + user controls for notifications and used the native Android share button in + the app, <strong>which reduced user uninstalls</strong>. +</p> + +<h3> + What they did +</h3> + +<p> + Aftenposten created a new onboarding flow that explained what notifications + were available, allowing readers to manage their preferences and customize up + to three topics. They also changed their custom share icon for the native + Android app. +</p> + +<h3> + Results +</h3> + +<p> + The results showed that with the new notifications management onboarding + screen, <strong>uninstalls decreased by 9.2% over 60 days</strong>. And with + the option to customize notifications, 51% of readers decided to keep two out + of three topics turned on. This led to a <strong>28% decrease over 60 days in + the number of users muting notifications completely</strong>. It also + provided insight into users’ content preferences, with <em>Sport</em> being + the least-favored notification. +</p> + +<p> + Aftenposten also increased share interactions by 17% just by replacing their + custom share icon with the native Android share icon. +</p> + +<p> + Aftenposten commented that: <em>Many of our users who see the onboarding + screen interact with it by turning off at least one notification topic. This + means that users are accepting push from one or more topics, instead of + turning it off completely. Moreover, readers are sharing more articles since + we added the standard share Android icon.</em> +</p> + +<h3> + Get started +</h3> + +<p> + Find out more about best practices for <a href= + "{@docRoot}design/patterns/notifications.html">Notifications</a> and <a href= + "{@docRoot}training/building-content-sharing.html">Building Apps with Content + Sharing</a>. +</p> diff --git a/docs/html/distribute/stories/apps/el-mundo.jd b/docs/html/distribute/stories/apps/el-mundo.jd new file mode 100644 index 000000000000..2ee813d55d11 --- /dev/null +++ b/docs/html/distribute/stories/apps/el-mundo.jd @@ -0,0 +1,73 @@ +page.title=El Mundo Improves User Ratings and Engagement with Material Design +page.metaDescription=El Mundo uses Material Design principles to enhance their app's user experience. +page.tags="developerstory", "apps", "googleplay" +page.image=images/cards/distribute/stories/el-mundo.png +page.timestamp=1468270112 + +@jd:body + +<div class="figure" style="width:113px"> + <img src="{@docRoot}images/distribute/stories/el-mundo-icon.png" height= + "113"> +</div> + +<h3> + Background +</h3> + +<p> + <a class="external-link" href= + "https://play.google.com/store/apps/details?id=com.gi.elmundo.main">El + Mundo</a>, one of Spain’s largest newspapers, integrated material design + principles into their app, which helped increase their Google Play Store + rating and improve user engagement. +</p> + +<h3> + What they did +</h3> + +<p> + El Mundo decided to completely redesign their app to provide a higher quality + user experience, making it easier for their readers to engage with news + content. By implementing material design guidelines, they created a + consistent look and feel throughout their app. +</p> + +<p> + After analyzing user comments, El Mundo discovered that readers considered + their app to be complicated and out-of-date. Therefore, they decided to + simplify the app’s functionality by removing features that were redundant. + They also removed sections of their app that were less relevant to their + readers, such as weather updates and movie trailers. Finally, they applied a + brand new internal development framework that they now use consistently + across all of their apps. +</p> + +<h3> + Results +</h3> + +<p> + Following the re-launch of their material design app, El Mundo saw a + <strong>45% increase in the weekly install rate</strong>. Readers now spend + more time in the app, with the average time spent in-app increasing from one + to three minutes. +</p> + +<p> + Additionally, this redesign resulted in more readers providing positive + feedback around the new experience, increasing the app rating in the Google + Play store by 25.8%, from 3.1 to 3.9. +</p> + +<h3> + Get started +</h3> + +<p> + Learn how to integrate <a class="external-link" href= + "https://material.google.com">Material Design</a> guidelines and follow + <a class="external-link" href="https://design.google.com">design + principles</a> for your app. +</p> diff --git a/docs/html/distribute/stories/apps/segundamano.jd b/docs/html/distribute/stories/apps/segundamano.jd new file mode 100644 index 000000000000..4cbf817c6d43 --- /dev/null +++ b/docs/html/distribute/stories/apps/segundamano.jd @@ -0,0 +1,63 @@ +page.title=Segundamano Develops Android-First as Its Fastest Channel for Growth +page.metaDescription=Segundamano developed Android app to increase potential for growth. +page.tags="developerstory", "apps", "googleplay" +page.image=images/cards/distribute/stories/segundamano.png +page.timestamp=1468270110 + +@jd:body + +<div class="figure" style="width:113px"> + <img src="{@docRoot}images/distribute/stories/segundamano-icon.png" height= + "113"> +</div> + +<h3> + Background +</h3> + +<p> + <a class="external-link" href= + "https://play.google.com/store/apps/details?id=mx.segundamano.android">Segundamano</a> + is a leading shopping application in Mexico for second-hand products. They + started by placing classified ads in newspapers, progressed to desktop, and + over the past year have seen significant growth in mobile, which now accounts + for 70% of their business. They have also seen <strong>270% year-over-year + growth on the Android platform alone</strong>. +</p> + +<h3> + What they did +</h3> + +<p> + Segundamano shifted focus to mobile with their Android app because of the + high potential for growth. From July 2015 to January 2016, they saw an + increase of 55% in the number of classified ads on Android, higher than any + other platform. To leverage this momentum, Segundamano implemented two new + features on Android: premium offers and push notifications. Segundamano also + decided to implement material design in order to improve the in-app + experience and streamline the sales process for users. +</p> + +<h3> + Results +</h3> + +<p> + Following Segundamano’s enhancements to the user experience, they've seen an + increase in their star rating, a 4.7% lift in monthly active users, and a 7% + increase in sales of premium listings. Additionally, year-to-date, their + <strong>installs are over seven times higher on Android than on other + platforms</strong>. +</p> + +<h3> + Get started +</h3> + +<p> + Learn more about simplifying your in-app experience with <a href= + "{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> + and the <a href="{@docRoot}design/material/index.html">material design + guidelines</a>. +</p>
\ No newline at end of file diff --git a/docs/html/distribute/stories/apps/tapps.jd b/docs/html/distribute/stories/apps/tapps.jd new file mode 100644 index 000000000000..129213946630 --- /dev/null +++ b/docs/html/distribute/stories/apps/tapps.jd @@ -0,0 +1,366 @@ +page.title=Tapps Games Increases Installs by More Than 20% with Store Listing Experiments +page.metaDescription=Tapps Games increased their use of store listing experiments in the Developer Console, with impressive results. +page.tags="developerstory", "apps", "googleplay" +page.image=images/cards/distribute/stories/tapps.png +page.timestamp=1468270108 + +@jd:body + +<style type="text/css"> + span.positive{ + color:green; + font-size: 125%; + font-weight:bold;"> + } + span.negative{ + color:red; + font-size: 125%; + font-weight:bold;"> + } +</style> + +<div class="figure" style="width:215px"> + <img src="{@docRoot}images/distribute/stories/tapps-logo.png" height="65"> +</div> + +<h3> + Background +</h3> + +<p> + <a class="external-link" href= + "https://play.google.com/store/apps/dev?id=6615809648420562690">Tapps</a> is + a mobile game publisher in São Paulo, Brazil. With a mission of <em>creating + fun for everyone</em>, Tapps has a portfolio of over 200 titles on the Google + Play Store, with roughly 70% of their installs coming from Android. Store + listing experiments have provided invaluable metrics to help their growing + team understand what makes the most effective product listings. +</p> + +<h3> + What they did +</h3> + +<p> + Tapps has increased their use of store listing experiments in the Developer + Console. They recently expanded their marketing team to allocate greater time + and designated resources to the Developer Console tools. <strong>"We can’t + stress enough how much value the store listing experiments have brought us + over the past months. Right now, our marketing team has a substantial time + allocated to these tests every week,"</strong> said Felipe Watanabe, head of + marketing at Tapps. With icons and screenshots, Tapps tested variations in + color, character positioning, and the overall amount of graphic detail. In + the description tests, they found that shorter messages with clear calls to + action and appropriate language localizations were most successful. +</p> + +<h3> + Results +</h3> + +<p> + By frequently conducting store listing experiments, Tapps gained valuable + insights that they have applied across their greater portfolio of games. + Results showed that shortening messaging, using contrasting colors, + reordering screenshots, and simplifying graphics often led to variant results + representing an average increase in performance between 5% and 50%. After + making changes based on the test results, Tapps saw <strong>install rates + increase beyond 20-30%</strong>. +</p> + +<h4> + Screen tests +</h4> + +<p> + The following table compares the install rates for three apps based on + changes to each app's screenshot. +</p> + +<p class="table-caption"> + <strong>Table 1</strong>. Screen test results +</p> + +<table> + <tr> + <th> + Original + </th> + <th> + Variant + </th> + <th> + Variant results + </th> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-3.png" + width="240"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-var-3.png" + width="240"> + </td> + <td> + <span class="positive">+25%</span> + </td> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-1.png" + width="240"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-var-1.png" + width="240"> + </td> + <td> + <span class="positive">+17.1%</span> + </td> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-2.png" + width="240"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-screen-var-2.png" + width="240"> + </td> + <td> + <span class="positive">+7.4%</span> + </td> + </tr> + +</table> + +<h4> + Icon tests +</h4> + +<p> + The following tables compare install rates for three apps based on changes + to each app's icon. +</p> + +<p class="table-caption"> + <strong>Table 2</strong>. Icon 1 test results +</p> + +<table> + <tr> + <th> + Original + </th> + <th> + Variant 1 + </th> + <th> + Variant 2 + </th> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-1.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-1.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-1-2.png"> + </td> + </tr> + + <tr> + <td> + --- + </td> + <td> + <span class="negative">-29.6%</span> + </td> + <td> + <span class="positive">+20.8%</span> + </td> + </tr> +</table> + +<p class="table-caption"> + <strong>Table 3</strong>. Icon 2 test results +</p> + +<table> + <tr> + <th> + Original + </th> + <th> + Variant 1 + </th> + <th> + Variant 2 + </th> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-2.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-2.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-2-2.png"> + </td> + </tr> + + <tr> + <td> + --- + </td> + <td> + <span class="positive">+5.1%</span> + </td> + <td> + <span class="positive">+19.7%</span> + </td> + </tr> +</table> + +<p class="table-caption"> + <strong>Table 4</strong>. Icon 3 test results +</p> + +<table> + <tr> + <th> + Original + </th> + <th> + Variant 1 + </th> + <th> + Variant 2 + </th> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-3.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-3.png"> + </td> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-icon-var-3-2.png"> + </td> + </tr> + + <tr> + <td> + --- + </td> + <td> + <span class="negative">-17.7%</span> + </td> + <td> + <span class="positive">+50.7%</span> + </td> + </tr> +</table> + +<h4> + Description tests +</h4> + +<p> + The following table compares install rates for three apps based on changes to + each app's description text. +</p> + +<p class="table-caption"> + <strong>Table 5</strong>. Description test results +</p> + +<table> + <tr> + <th> + Game + </th> + <th> + Original + </th> + <th> + Variant + </th> + <th> + Variant results + </th> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-logic-pic.png"> + <strong>Logic Pic</strong> + </td> + <td> + <em>"Use logic to solve fun puzzles and discover hidden pictures! Logic + Pic is free!"</em> + </td> + <td> + <strong><em>"Discover all the hidden pictures in this challenging classic + japanese puzzle!"</em></strong> + </td> + <td> + <span class="positive">+10.7%</span> + </td> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-candy-hills.png" + width="96"> <strong>Candy Hills</strong> + </td> + <td> + <em>"What will your candy park look like? Build it now in Candy + Hills!"</em> + </td> + <td> + <strong><em>"Build your own sweet candy park in Candy + Hills!"</em></strong> + </td> + <td> + <span class="positive">+8.2%</span> + </td> + </tr> + + <tr> + <td> + <img src="{@docRoot}images/distribute/stories/tapps-villains-corp.png" + width="96"> <strong>Villains Corp.</strong> + </td> + <td> + <em>"Be a real villain and CONQUER THE WORLD!"</em> + </td> + <td> + <strong><em>"Mwahahaha! Be a real villain and CONQUER THE + WORLD!"</em></strong> + </td> + <td> + <span class="positive">+6.8%</span> + </td> + </tr> +</table> + +<h3> + Get started +</h3> + +<p> + Find out more about <a href= + "{@docRoot}distribute/users/experiments.html">store listing experiments</a>. +</p> diff --git a/docs/html/distribute/stories/apps/upbeat-games.jd b/docs/html/distribute/stories/apps/upbeat-games.jd new file mode 100644 index 000000000000..02222d39e686 --- /dev/null +++ b/docs/html/distribute/stories/apps/upbeat-games.jd @@ -0,0 +1,69 @@ +page.title=Witch Puzzle Achieves 98% of International Installs on Android +page.metaDescription=Witch Puzzle localized their app into 12 languages. +page.tags="developerstory", "apps", "googleplay" +page.image=images/cards/distribute/stories/witch-puzzle.png +page.timestamp=1468270106 + +@jd:body + + +<div class="figure"> + <img src="{@docRoot}images/distribute/stories/witch-puzzle-icon.png" + width="113"> +</div> + +<h3> + Background +</h3> + +<p> + Located in São Paulo, Brazil, <a class="external-link" href= + "https://play.google.com/store/apps/dev?id=8995071809141037139">Upbeat + Games</a> is an indie game developer with a mission to build fun and easy + games that anyone can play. As a small team, the Upbeat crew reacted quickly + to their game’s growing installs in Asian countries, and is now seeing strong + international growth with their game <a class="external-link" href= + "https://play.google.com/store/apps/details?id=com.upbeatgames.witchpuzzle">Witch + Puzzle</a>. +</p> + +<h3> + What they did +</h3> + +<p> + After noticing that Witch Puzzle was gaining traction throughout Asia, Upbeat + localized their game into 12 languages, prioritizing countries with an + existing user base and high gross national income (GNI). This led to a direct + increase in installs. +</p> + +<div class="figure"> + <img src="{@docRoot}images/distribute/stories/japanese-witch-puzzle.png" + width="214"> + <p class="img-caption"> + Japanese version of Witch Puzzle + </p> +</div> + +<h3> + Results +</h3> + +<p> + “In the last three months, 98% of our international installs for Witch Puzzle + came from Android,” said Vinicius Sormani Heimbeck, Upbeat’s founder. Upbeat + applied these learnings across their portfolio of games. Now, <strong>75% of + their portfolio’s revenue is driven by Android</strong>. +</p> + +<h3> + Get started +</h3> + +<p> + Use the <a href= + "{@docRoot}distribute/tools/localization-checklist.html">Localization + Checklist</a> to learn more about tailoring your app for different markets to + drive installs and revenue, and to create a better overall user experience. +</p> diff --git a/docs/html/images/cards/distribute/stories/aftenposten.png b/docs/html/images/cards/distribute/stories/aftenposten.png Binary files differnew file mode 100644 index 000000000000..60cb85104f8c --- /dev/null +++ b/docs/html/images/cards/distribute/stories/aftenposten.png diff --git a/docs/html/images/cards/distribute/stories/el-mundo.png b/docs/html/images/cards/distribute/stories/el-mundo.png Binary files differnew file mode 100644 index 000000000000..23db783d47dd --- /dev/null +++ b/docs/html/images/cards/distribute/stories/el-mundo.png diff --git a/docs/html/images/cards/distribute/stories/segundamano.png b/docs/html/images/cards/distribute/stories/segundamano.png Binary files differnew file mode 100644 index 000000000000..60e873c0c8cb --- /dev/null +++ b/docs/html/images/cards/distribute/stories/segundamano.png diff --git a/docs/html/images/cards/distribute/stories/tapps.png b/docs/html/images/cards/distribute/stories/tapps.png Binary files differnew file mode 100644 index 000000000000..e01e3adf596d --- /dev/null +++ b/docs/html/images/cards/distribute/stories/tapps.png diff --git a/docs/html/images/cards/distribute/stories/witch-puzzle.png b/docs/html/images/cards/distribute/stories/witch-puzzle.png Binary files differnew file mode 100644 index 000000000000..c336f1bf16ef --- /dev/null +++ b/docs/html/images/cards/distribute/stories/witch-puzzle.png diff --git a/docs/html/images/distribute/stories/aftenposten-icon.png b/docs/html/images/distribute/stories/aftenposten-icon.png Binary files differnew file mode 100644 index 000000000000..60cb85104f8c --- /dev/null +++ b/docs/html/images/distribute/stories/aftenposten-icon.png diff --git a/docs/html/images/distribute/stories/el-mundo-icon.png b/docs/html/images/distribute/stories/el-mundo-icon.png Binary files differnew file mode 100644 index 000000000000..23db783d47dd --- /dev/null +++ b/docs/html/images/distribute/stories/el-mundo-icon.png diff --git a/docs/html/images/distribute/stories/japanese-witch-puzzle.png b/docs/html/images/distribute/stories/japanese-witch-puzzle.png Binary files differnew file mode 100644 index 000000000000..6a7ef13dd9f9 --- /dev/null +++ b/docs/html/images/distribute/stories/japanese-witch-puzzle.png diff --git a/docs/html/images/distribute/stories/segundamano-icon.png b/docs/html/images/distribute/stories/segundamano-icon.png Binary files differnew file mode 100644 index 000000000000..60e873c0c8cb --- /dev/null +++ b/docs/html/images/distribute/stories/segundamano-icon.png diff --git a/docs/html/images/distribute/stories/tapps-candy-hills.png b/docs/html/images/distribute/stories/tapps-candy-hills.png Binary files differnew file mode 100644 index 000000000000..14dcb9447ba6 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-candy-hills.png diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-1.png b/docs/html/images/distribute/stories/tapps-icon-orig-1.png Binary files differnew file mode 100644 index 000000000000..44af423f3795 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-orig-1.png diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-2.png b/docs/html/images/distribute/stories/tapps-icon-orig-2.png Binary files differnew file mode 100644 index 000000000000..1b362557b2b0 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-orig-2.png diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-3.png b/docs/html/images/distribute/stories/tapps-icon-orig-3.png Binary files differnew file mode 100644 index 000000000000..2f393f8ba965 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-orig-3.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-1-2.png b/docs/html/images/distribute/stories/tapps-icon-var-1-2.png Binary files differnew file mode 100644 index 000000000000..fecab6e06f90 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-1-2.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-1.png b/docs/html/images/distribute/stories/tapps-icon-var-1.png Binary files differnew file mode 100644 index 000000000000..77bd02a17f63 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-1.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-2-2.png b/docs/html/images/distribute/stories/tapps-icon-var-2-2.png Binary files differnew file mode 100644 index 000000000000..84166c43c9f1 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-2-2.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-2.png b/docs/html/images/distribute/stories/tapps-icon-var-2.png Binary files differnew file mode 100644 index 000000000000..939c2fdf1b34 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-2.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-3-2.png b/docs/html/images/distribute/stories/tapps-icon-var-3-2.png Binary files differnew file mode 100644 index 000000000000..4aa782d0b9f9 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-3-2.png diff --git a/docs/html/images/distribute/stories/tapps-icon-var-3.png b/docs/html/images/distribute/stories/tapps-icon-var-3.png Binary files differnew file mode 100644 index 000000000000..1e44fdf7cfbc --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-icon-var-3.png diff --git a/docs/html/images/distribute/stories/tapps-logic-pic.png b/docs/html/images/distribute/stories/tapps-logic-pic.png Binary files differnew file mode 100644 index 000000000000..5029f79ca610 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-logic-pic.png diff --git a/docs/html/images/distribute/stories/tapps-logo.png b/docs/html/images/distribute/stories/tapps-logo.png Binary files differnew file mode 100644 index 000000000000..e01e3adf596d --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-logo.png diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-1.png b/docs/html/images/distribute/stories/tapps-screen-orig-1.png Binary files differnew file mode 100644 index 000000000000..d54e75c8dd80 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-orig-1.png diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-2.png b/docs/html/images/distribute/stories/tapps-screen-orig-2.png Binary files differnew file mode 100644 index 000000000000..a2d18e3cd0da --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-orig-2.png diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-3.png b/docs/html/images/distribute/stories/tapps-screen-orig-3.png Binary files differnew file mode 100644 index 000000000000..e01fe20fb6b2 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-orig-3.png diff --git a/docs/html/images/distribute/stories/tapps-screen-var-1.png b/docs/html/images/distribute/stories/tapps-screen-var-1.png Binary files differnew file mode 100644 index 000000000000..b93035093d3f --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-var-1.png diff --git a/docs/html/images/distribute/stories/tapps-screen-var-2.png b/docs/html/images/distribute/stories/tapps-screen-var-2.png Binary files differnew file mode 100644 index 000000000000..9ccb8a647e44 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-var-2.png diff --git a/docs/html/images/distribute/stories/tapps-screen-var-3.png b/docs/html/images/distribute/stories/tapps-screen-var-3.png Binary files differnew file mode 100644 index 000000000000..8eb58e1cb6d1 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-screen-var-3.png diff --git a/docs/html/images/distribute/stories/tapps-villains-corp.png b/docs/html/images/distribute/stories/tapps-villains-corp.png Binary files differnew file mode 100644 index 000000000000..6e037dad4f23 --- /dev/null +++ b/docs/html/images/distribute/stories/tapps-villains-corp.png diff --git a/docs/html/images/distribute/stories/witch-puzzle-icon.png b/docs/html/images/distribute/stories/witch-puzzle-icon.png Binary files differnew file mode 100644 index 000000000000..c336f1bf16ef --- /dev/null +++ b/docs/html/images/distribute/stories/witch-puzzle-icon.png diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd index 3e95f3e864c0..ff11e8e93c3f 100644 --- a/docs/html/preview/setup-sdk.jd +++ b/docs/html/preview/setup-sdk.jd @@ -77,32 +77,10 @@ Android N Preview SDK in Android Studio as follows:</p> <h3 id="docs-dl">Get the N Preview reference documentation</h3> <p>Beginning with the Preview 4 release, the API reference for the -N platform (API level 24) is now available online at <a href= - "{@docRoot}reference/">developer.android.com/reference/</a>. -</p> - -<p>If you'd like an offline copy of the API reference, you can download it -from the following table. The download also includes an incremental diff report -for API changes between the Preview 3 and Preview 4 release, which is not -available online.</p> - -<table> - <tr> - <th scope="col">Documentation</th> - <th scope="col">Checksums</th> - </tr> - <tr> - <td style="white-space: nowrap"> - <a href="{@docRoot}shareables/preview/n-preview-4-docs.zip" - >n-preview-4-docs.zip</a></td> - <td width="100%"> - MD5: f853e3ba0707083336dfa780b8fed9a7<br> - SHA-1: 36fcbc497cc2e63b1bc1d629c304b0ba43a88946 - </td> - </tr> -</table> - - + N platform (API level 24) is now available online at <a href= + "{@docRoot}reference/">developer.android.com/reference/</a>. There is also + an incremental diff report for <a href="{@docRoot}sdk/api_diff/24/changes.html" + >API changes between API levels 23 and 24</a>.</p> <h2 id="java8">Get the Java 8 JDK</h2> diff --git a/docs/html/topic/performance/index.jd b/docs/html/topic/performance/index.jd index 08c610f291dc..e08db15baa08 100644 --- a/docs/html/topic/performance/index.jd +++ b/docs/html/topic/performance/index.jd @@ -1,6 +1,6 @@ page.title=Performance page.article=true -page.metaDescription=Android Performance does nice things. Details to come. +page.metaDescription=Improve your app's performance by learning how to optimize power consumption, launch times, and other important areas of performance. meta.tags="performance" page.tags="performance" diff --git a/docs/html/topic/performance/launch-time.jd b/docs/html/topic/performance/launch-time.jd index c9ce1d56185f..84d5fab12a6b 100644 --- a/docs/html/topic/performance/launch-time.jd +++ b/docs/html/topic/performance/launch-time.jd @@ -112,7 +112,7 @@ other. </p> <br/> - <img src="{@docRoot}performance/images/cold-launch.png"> + <img src="{@docRoot}topic/performance/images/cold-launch.png"> <p class="img-caption"> <strong>Figure 1.</strong> A visual representation of the important parts of a cold application launch. @@ -262,7 +262,7 @@ the {@code Displayed} time. </p> <br/> - <img src="{@docRoot}performance/images/displayed-logcat.png"> + <img src="{@docRoot}topic/performance/images/displayed-logcat.png"> <p class="img-caption"> <strong>Figure 2.</strong> Disabling filters, and finding the {@code Displayed} value in logcat. diff --git a/libs/hwui/PropertyValuesAnimatorSet.h b/libs/hwui/PropertyValuesAnimatorSet.h index 49021bc82825..f9274e173536 100644 --- a/libs/hwui/PropertyValuesAnimatorSet.h +++ b/libs/hwui/PropertyValuesAnimatorSet.h @@ -60,7 +60,7 @@ public: virtual uint32_t dirtyMask(); bool isInfinite() { return mIsInfinite; } void setVectorDrawable(VectorDrawableRoot* vd) { mVectorDrawable = vd; } - VectorDrawableRoot* getVectorDrawable() const { return mVectorDrawable; } + VectorDrawableRoot* getVectorDrawable() const { return mVectorDrawable.get(); } AnimationListener* getOneShotListener() { return mOneShotListener.get(); } void clearOneShotListener() { mOneShotListener = nullptr; } uint32_t getRequestId() const { return mRequestId; } @@ -78,7 +78,7 @@ private: std::vector< std::unique_ptr<PropertyAnimator> > mAnimators; float mLastFraction = 0.0f; bool mInitialized = false; - VectorDrawableRoot* mVectorDrawable = nullptr; + sp<VectorDrawableRoot> mVectorDrawable; bool mIsInfinite = false; // This request id gets incremented (on UI thread only) when a new request to modfiy the // lifecycle of an animation happens, namely when start/end/reset/reverse is called. diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index 7d5939c9720a..81cc93da2e6f 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -264,7 +264,6 @@ public final class AudioFormat implements Parcelable { */ public static final int ENCODING_IEC61937 = 13; /** Audio data format: DOLBY TRUEHD compressed - * @hide **/ public static final int ENCODING_DOLBY_TRUEHD = 14; diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 8d4a1510715a..31c7a3249542 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -3498,7 +3498,7 @@ public class MediaPlayer extends PlayerBase * @param extra an extra code, specific to the info. Typically * implementation dependent. * @return True if the method handled the info, false if it didn't. - * Returning false, or not having an OnErrorListener at all, will + * Returning false, or not having an OnInfoListener at all, will * cause the info to be discarded. */ boolean onInfo(MediaPlayer mp, int what, int extra); diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index 0f7dc9a819c7..b262d97cfb8e 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -181,10 +181,15 @@ public abstract class PlayerBase { * @return */ boolean isRestricted_sync() { + // check app ops + if (mHasAppOpsPlayAudio) { + return false; + } + // check bypass flag if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { return false; } - return !mHasAppOpsPlayAudio; + return true; } // Abstract methods a subclass needs to implement diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 5ede1d5f7c91..9fafda48d652 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -505,27 +505,31 @@ public class SoundPool { } private boolean isRestricted() { - IAudioService service = getService(); - boolean cameraSoundForced = false; - - try { - cameraSoundForced = service.isCameraSoundForced(); - } catch (RemoteException e) { - Log.e(TAG, "Cannot access AudioService in isRestricted()"); - } - - if (cameraSoundForced && - ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0) -// FIXME: should also check usage when set properly by camera app -// && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) - ) { + // check app ops + if (mHasAppOpsPlayAudio) { return false; } - + // check bypass flag if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { return false; } - return !mHasAppOpsPlayAudio; + // check force audibility flag and camera restriction + if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0) { +// FIXME: should also check usage when set properly by camera app +// && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + boolean cameraSoundForced = false; + try { + cameraSoundForced = getService().isCameraSoundForced(); + } catch (RemoteException e) { + Log.e(TAG, "Cannot access AudioService in isRestricted()"); + } catch (NullPointerException e) { + Log.e(TAG, "Null AudioService in isRestricted()"); + } + if (cameraSoundForced) { + return false; + } + } + return true; } private void updateAppOpsPlayAudio() { diff --git a/packages/PrintSpooler/res/drawable/print_button.xml b/packages/PrintSpooler/res/drawable/print_button.xml index b59afba80293..01141032e66f 100644 --- a/packages/PrintSpooler/res/drawable/print_button.xml +++ b/packages/PrintSpooler/res/drawable/print_button.xml @@ -16,7 +16,7 @@ --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="@color/print_button_tint_color"> + android:color="?android:attr/colorControlHighlight"> <item android:drawable="@drawable/print_button_background"> </item> diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml index 47e616ef40c7..9464c678e59c 100644 --- a/packages/PrintSpooler/res/values/colors.xml +++ b/packages/PrintSpooler/res/values/colors.xml @@ -16,8 +16,6 @@ <resources> - <color name="print_button_tint_color">#EEFF41</color> - <color name="print_preview_scrim_color">#99000000</color> <color name="print_preview_background_color">#F2F1F2</color> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 28e9a45cc40e..1928f92f5855 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -799,7 +799,8 @@ public class SettingsProvider extends ContentProvider { // If this is a setting that is currently restricted for this user, do not allow // unrestricting changes. - if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value)) { + if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value, + Binder.getCallingUid())) { return false; } @@ -930,7 +931,8 @@ public class SettingsProvider extends ContentProvider { // If this is a setting that is currently restricted for this user, do not allow // unrestricting changes. - if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value)) { + if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value, + Binder.getCallingUid())) { return false; } @@ -1153,7 +1155,7 @@ public class SettingsProvider extends ContentProvider { * @return true if the change is prohibited, false if the change is allowed. */ private boolean isGlobalOrSecureSettingRestrictedForUser(String setting, int userId, - String value) { + String value, int callingUid) { String restriction; switch (setting) { case Settings.Secure.LOCATION_MODE: @@ -1191,6 +1193,15 @@ public class SettingsProvider extends ContentProvider { restriction = UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS; break; + case Settings.Secure.ALWAYS_ON_VPN_APP: + case Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN: + // Whitelist system uid (ConnectivityService) and root uid to change always-on vpn + if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { + return false; + } + restriction = UserManager.DISALLOW_CONFIG_VPN; + break; + default: if (setting != null && setting.startsWith(Settings.Global.DATA_ROAMING)) { if ("0".equals(value)) return false; @@ -2074,7 +2085,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 128; + private static final int SETTINGS_VERSION = 129; private final int mUserId; @@ -2334,6 +2345,37 @@ public class SettingsProvider extends ContentProvider { currentVersion = 128; } + if (currentVersion == 128) { + // Version 128: Allow OEMs to grant DND access to default apps. Note that + // the new apps are appended to the list of already approved apps. + final SettingsState systemSecureSettings = + getSecureSettingsLocked(userId); + + final Setting policyAccess = systemSecureSettings.getSettingLocked( + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES); + String defaultPolicyAccess = getContext().getResources().getString( + com.android.internal.R.string.config_defaultDndAccessPackages); + if (!TextUtils.isEmpty(defaultPolicyAccess)) { + if (policyAccess.isNull()) { + systemSecureSettings.insertSettingLocked( + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES, + defaultPolicyAccess, + SettingsState.SYSTEM_PACKAGE_NAME); + } else { + StringBuilder currentSetting = + new StringBuilder(policyAccess.getValue()); + currentSetting.append(":"); + currentSetting.append(defaultPolicyAccess); + systemSecureSettings.updateSettingLocked( + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES, + currentSetting.toString(), + SettingsState.SYSTEM_PACKAGE_NAME); + } + } + + currentVersion = 129; + } + // vXXX: Add new settings above this point. // Return the current version. diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml new file mode 100644 index 000000000000..778ccbc5f4a4 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml @@ -0,0 +1,27 @@ +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="64dp" + android:height="64dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:alpha="0.3"> + + <path + android:fillColor="#FFF" + android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" /> + +</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml new file mode 100644 index 000000000000..aaca663e59e9 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="64dp" + android:height="64dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#FFF" + android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" /> + +</vector> diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml index 3b8b909118f1..6673d6e8255f 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml @@ -111,7 +111,7 @@ android:layout_alignParentTop="true" android:paddingStart="16dp" android:paddingEnd="16dp" - android:paddingTop="2dp" + android:paddingTop="6dp" android:visibility="gone" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.EmergencyCallsOnly" android:text="@*android:string/emergency_calls_only" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index e1cbbc5c9c54..ae4f3cf37ce7 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -375,6 +375,8 @@ <!-- The font size of the date in QS --> <dimen name="qs_date_collapsed_size">14sp</dimen> + <!-- Amount the date/time move when emergency calls only is present --> + <dimen name="qs_date_time_translation">8dp</dimen> <!-- Battery level text padding end when in expanded QS and on Keyguard --> <dimen name="battery_level_padding_end">2dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 3ed071177de8..5324968969aa 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -752,6 +752,12 @@ <string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string> <!-- QuickSettings: Work mode [CHAR LIMIT=NONE] --> <string name="quick_settings_work_mode_label">Work mode</string> + <!-- QuickSettings: Label for the toggle to activate Night display (renamed "Night Light" with title caps). [CHAR LIMIT=20] --> + <string name="quick_settings_night_display_label">Night Light</string> + <!-- QuickSettings: Summary for the toggle to deactivate Night display when it's on (renamed "Night Light" with title caps). [CHAR LIMIT=NONE] --> + <string name="quick_settings_night_display_summary_on">Night Light on, tap to turn off</string> + <!-- QuickSettings: Label for the toggle to activate Night display when it's off (renamed "Night Light" with title caps). [CHAR LIMIT=NONE] --> + <string name="quick_settings_night_display_summary_off">Night Light off, tap to turn on</string> <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] --> <string name="recents_empty_message">No recent items</string> diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index af2a2869bc30..9eceeacc3968 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -47,7 +47,7 @@ public class AssistManager { private static final long TIMEOUT_SERVICE = 2500; private static final long TIMEOUT_ACTIVITY = 1000; - private final Context mContext; + protected final Context mContext; private final WindowManager mWindowManager; private final AssistDisclosure mAssistDisclosure; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java new file mode 100644 index 000000000000..9a3549eb6a75 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.tiles; + +import android.content.Intent; +import android.provider.Settings; +import android.widget.Switch; + +import com.android.internal.app.NightDisplayController; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.systemui.R; +import com.android.systemui.qs.QSTile; + +public class NightDisplayTile extends QSTile<QSTile.BooleanState> + implements NightDisplayController.Callback { + + private final NightDisplayController mController; + + public NightDisplayTile(Host host) { + super(host); + mController = new NightDisplayController(mContext); + } + + @Override + public boolean isAvailable() { + return NightDisplayController.isAvailable(mContext); + } + + @Override + public BooleanState newTileState() { + return new BooleanState(); + } + + @Override + protected void handleClick() { + final boolean activated = !mState.value; + MetricsLogger.action(mContext, getMetricsCategory(), activated); + mController.setActivated(activated); + } + + @Override + protected void handleUpdateState(BooleanState state, Object arg) { + final boolean isActivated = mController.isActivated(); + state.value = isActivated; + state.label = mContext.getString(R.string.quick_settings_night_display_label); + state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_night_display_on + : R.drawable.ic_qs_night_display_off); + state.contentDescription = mContext.getString(isActivated + ? R.string.quick_settings_night_display_summary_on + : R.string.quick_settings_night_display_summary_off); + state.minimalAccessibilityClassName = state.expandedAccessibilityClassName + = Switch.class.getName(); + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.QS_NIGHT_DISPLAY; + } + + @Override + public Intent getLongClickIntent() { + return new Intent(Settings.ACTION_DISPLAY_SETTINGS); + } + + @Override + protected void setListening(boolean listening) { + if (listening) { + mController.setListener(this); + refreshState(); + } else { + mController.setListener(null); + } + } + + @Override + public CharSequence getTileLabel() { + return mContext.getString(R.string.quick_settings_night_display_label); + } + + @Override + public void onActivated(boolean activated) { + refreshState(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index b53a99907146..63f726b545db 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -49,6 +49,13 @@ public class ButtonDispatcher { mViews.clear(); } + void addView(View view, boolean landscape) { + addView(view); + if (view instanceof ButtonInterface) { + ((ButtonInterface) view).setLandscape(landscape); + } + } + void addView(View view) { mViews.add(view); view.setOnClickListener(mClickListener); @@ -178,5 +185,7 @@ public class ButtonDispatcher { void setImageDrawable(@Nullable Drawable drawable); void abortCurrentGesture(); + + void setLandscape(boolean landscape); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index dd46b085e005..06c8b685ff63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -28,7 +28,6 @@ import android.widget.LinearLayout; import android.widget.Space; import com.android.systemui.R; -import com.android.systemui.SystemUIFactory; import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.tuner.TunerService; @@ -71,6 +70,8 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi private View mLastRot0; private View mLastRot90; + private boolean mAlternativeOrder; + public NavigationBarInflaterView(Context context, AttributeSet attrs) { super(context, attrs); mDensity = context.getResources().getConfiguration().densityDpi; @@ -114,6 +115,7 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi false); mRot90.setId(R.id.rot90); addView(mRot90); + updateAlternativeOrder(); if (getParent() instanceof NavigationBarView) { ((NavigationBarView) getParent()).updateRotatedViews(); } @@ -152,6 +154,26 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi } } + public void setAlternativeOrder(boolean alternativeOrder) { + if (alternativeOrder != mAlternativeOrder) { + mAlternativeOrder = alternativeOrder; + updateAlternativeOrder(); + } + } + + private void updateAlternativeOrder() { + updateAlternativeOrder(mRot0.findViewById(R.id.ends_group)); + updateAlternativeOrder(mRot0.findViewById(R.id.center_group)); + updateAlternativeOrder(mRot90.findViewById(R.id.ends_group)); + updateAlternativeOrder(mRot90.findViewById(R.id.center_group)); + } + + private void updateAlternativeOrder(View v) { + if (v instanceof ReverseLinearLayout) { + ((ReverseLinearLayout) v).setAlternativeOrder(mAlternativeOrder); + } + } + private void initiallyFill(ButtonDispatcher buttonDispatcher) { addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.ends_group)); addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.center_group)); @@ -258,7 +280,7 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi params.width = (int) (params.width * size); } parent.addView(v); - addToDispatchers(v); + addToDispatchers(v, landscape); View lastView = landscape ? mLastRot90 : mLastRot0; if (lastView != null) { v.setAccessibilityTraversalAfter(lastView.getId()); @@ -305,16 +327,16 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi return buttonSpec.substring(0, buttonSpec.indexOf(SIZE_MOD_START)); } - private void addToDispatchers(View v) { + private void addToDispatchers(View v, boolean landscape) { if (mButtonDispatchers != null) { final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId()); if (indexOfKey >= 0) { - mButtonDispatchers.valueAt(indexOfKey).addView(v); + mButtonDispatchers.valueAt(indexOfKey).addView(v, landscape); } else if (v instanceof ViewGroup) { final ViewGroup viewGroup = (ViewGroup)v; final int N = viewGroup.getChildCount(); for (int i = 0; i < N; i++) { - addToDispatchers(viewGroup.getChildAt(i)); + addToDispatchers(viewGroup.getChildAt(i), landscape); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 53fe6ce3efa9..23aeae8c5b33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -99,6 +99,8 @@ public class NavigationBarView extends LinearLayout { private final SparseArray<ButtonDispatcher> mButtonDisatchers = new SparseArray<>(); private Configuration mConfiguration; + private NavigationBarInflaterView mNavigationInflaterView; + private class NavTransitionListener implements TransitionListener { private boolean mBackTransitioning; private boolean mHomeAppearing; @@ -472,9 +474,10 @@ public class NavigationBarView extends LinearLayout { @Override public void onFinishInflate() { + mNavigationInflaterView = (NavigationBarInflaterView) findViewById( + R.id.navigation_inflater); updateRotatedViews(); - ((NavigationBarInflaterView) findViewById(R.id.navigation_inflater)).setButtonDispatchers( - mButtonDisatchers); + mNavigationInflaterView.setButtonDispatchers(mButtonDisatchers); getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener); @@ -530,6 +533,7 @@ public class NavigationBarView extends LinearLayout { } mCurrentView = mRotatedViews[rot]; mCurrentView.setVisibility(View.VISIBLE); + mNavigationInflaterView.setAlternativeOrder(rot == Surface.ROTATION_90); for (int i = 0; i < mButtonDisatchers.size(); i++) { mButtonDisatchers.valueAt(i).setCurrentView(mCurrentView); } 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 34aaae452475..fb7afc59b276 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -52,6 +52,7 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.hardware.display.DisplayManager; import android.inputmethodservice.InputMethodService; import android.media.AudioAttributes; import android.media.MediaMetadata; @@ -200,7 +201,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener, - HeadsUpManager.OnHeadsUpChangedListener { + HeadsUpManager.OnHeadsUpChangedListener, DisplayManager.DisplayListener { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; public static final boolean SPEW = false; @@ -684,6 +685,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mUnlockMethodCache.addListener(this); startKeyguard(); + mContext.getSystemService(DisplayManager.class).registerDisplayListener(this, null); + mDozeServiceHost = new DozeServiceHost(); KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost); putComponent(DozeHost.class, mDozeServiceHost); @@ -880,9 +883,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mLightStatusBarController = new LightStatusBarController(mIconController, mBatteryController); mKeyguardMonitor = new KeyguardMonitor(mContext); + mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor, + mHandler, this); if (UserManager.get(mContext).isUserSwitcherEnabled()) { - mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor, - mHandler, this); createUserSwitcher(); } @@ -3503,6 +3506,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override + public void onDisplayAdded(int displayId) { + } + + @Override + public void onDisplayRemoved(int displayId) { + } + + @Override + public void onDisplayChanged(int displayId) { + if (displayId == Display.DEFAULT_DISPLAY) { + repositionNavigationBar(); + } + } + + @Override public void userSwitched(int newUserId) { super.userSwitched(newUserId); if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index ca7f9051f56d..15e235dd4d5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -52,6 +52,7 @@ import com.android.systemui.qs.tiles.FlashlightTile; import com.android.systemui.qs.tiles.HotspotTile; import com.android.systemui.qs.tiles.IntentTile; import com.android.systemui.qs.tiles.LocationTile; +import com.android.systemui.qs.tiles.NightDisplayTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.qs.tiles.UserTile; import com.android.systemui.qs.tiles.WifiTile; @@ -440,6 +441,7 @@ public class QSTileHost implements QSTile.Host, Tunable { else if (tileSpec.equals("user")) return new UserTile(this); else if (tileSpec.equals("battery")) return new BatteryTile(this); else if (tileSpec.equals("saver")) return new DataSaverTile(this); + else if (tileSpec.equals("night")) return new NightDisplayTile(this); // Intent tiles. else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec); else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index 85303f422925..21db64febbe0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -37,11 +37,11 @@ import com.android.internal.logging.MetricsProto; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; -import com.android.systemui.qs.QSAnimator; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSPanel.Callback; import com.android.systemui.qs.QuickQSPanel; import com.android.systemui.qs.TouchAnimator; +import com.android.systemui.qs.TouchAnimator.Builder; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback; @@ -84,13 +84,13 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements private ImageView mMultiUserAvatar; - private TouchAnimator mSecondHalfAnimator; - private TouchAnimator mFirstHalfAnimator; + private TouchAnimator mAnimator; protected TouchAnimator mSettingsAlpha; private float mExpansionAmount; private QSTileHost mHost; private View mEdit; private boolean mShowFullAlarm; + private float mDateTimeTranslation; public QuickStatusBarHeader(Context context, AttributeSet attrs) { super(context, attrs); @@ -111,6 +111,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group); mDateTimeGroup.setPivotX(0); mDateTimeGroup.setPivotY(0); + mDateTimeTranslation = getResources().getDimension(R.dimen.qs_date_time_translation); mShowFullAlarm = getResources().getBoolean(R.bool.quick_settings_show_full_alarm); mExpandIndicator = (ExpandableIndicator) findViewById(R.id.expand_indicator); @@ -152,15 +153,13 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements FontSizeUtils.updateFontSize(mAlarmStatus, R.dimen.qs_date_collapsed_size); FontSizeUtils.updateFontSize(mEmergencyOnly, R.dimen.qs_emergency_calls_only_text_size); - mSecondHalfAnimator = new TouchAnimator.Builder() + Builder builder = new Builder() .addFloat(mShowFullAlarm ? mAlarmStatus : findViewById(R.id.date), "alpha", 0, 1) - .addFloat(mEmergencyOnly, "alpha", 0, 1) - .build(); + .addFloat(mEmergencyOnly, "alpha", 0, 1); if (mShowFullAlarm) { - mFirstHalfAnimator = new TouchAnimator.Builder() - .addFloat(mAlarmStatusCollapsed, "alpha", 1, 0) - .build(); + builder.addFloat(mAlarmStatusCollapsed, "alpha", 1, 0); } + mAnimator = builder.build(); updateSettingsAnimator(); } @@ -223,10 +222,8 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements @Override public void setExpansion(float headerExpansionFraction) { mExpansionAmount = headerExpansionFraction; - mSecondHalfAnimator.setPosition(headerExpansionFraction); - if (mShowFullAlarm) { - mFirstHalfAnimator.setPosition(headerExpansionFraction); - } + updateDateTimePosition(); + mAnimator.setPosition(headerExpansionFraction); mSettingsAlpha.setPosition(headerExpansionFraction); updateAlarmVisibilities(); @@ -264,6 +261,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements protected void updateVisibilities() { updateAlarmVisibilities(); + updateDateTimePosition(); mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? View.VISIBLE : View.INVISIBLE); mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility( @@ -274,6 +272,11 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE); } + private void updateDateTimePosition() { + mDateTimeAlarmGroup.setTranslationY(mShowEmergencyCallsOnly + ? mExpansionAmount * mDateTimeTranslation : 0); + } + private void updateListeners() { if (mListening) { mNextAlarmController.addStateChangedCallback(this); @@ -315,7 +318,8 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements public void onClick(View v) { if (v == mSettingsButton) { MetricsLogger.action(mContext, - MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH); + mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH + : MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH); if (mSettingsButton.isTunerClick()) { if (TunerService.isTunerEnabled(mContext)) { TunerService.showResetRequest(mContext, new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java index 3682aa1b06f8..f45967a0a0a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java @@ -30,7 +30,11 @@ import java.util.ArrayList; */ public class ReverseLinearLayout extends LinearLayout { - private boolean mIsLayoutRtl; + /** If true, the layout is reversed vs. a regular linear layout */ + private boolean mIsLayoutReverse; + + /** If true, the layout is opposite to it's natural reversity from the layout direction */ + private boolean mIsAlternativeOrder; public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -39,45 +43,50 @@ public class ReverseLinearLayout extends LinearLayout { @Override protected void onFinishInflate() { super.onFinishInflate(); - mIsLayoutRtl = getResources().getConfiguration() - .getLayoutDirection() == LAYOUT_DIRECTION_RTL; + updateOrder(); } @Override public void addView(View child) { reversParams(child.getLayoutParams()); - if (mIsLayoutRtl) { - super.addView(child); - } else { + if (mIsLayoutReverse) { super.addView(child, 0); + } else { + super.addView(child); } } @Override public void addView(View child, ViewGroup.LayoutParams params) { reversParams(params); - if (mIsLayoutRtl) { - super.addView(child, params); - } else { + if (mIsLayoutReverse) { super.addView(child, 0, params); + } else { + super.addView(child, params); } } @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - updateRTLOrder(); + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + updateOrder(); + } + + public void setAlternativeOrder(boolean alternative) { + mIsAlternativeOrder = alternative; + updateOrder(); } /** * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we * have to do it manually */ - private void updateRTLOrder() { - boolean isLayoutRtl = getResources().getConfiguration() - .getLayoutDirection() == LAYOUT_DIRECTION_RTL; - if (mIsLayoutRtl != isLayoutRtl) { - // RTL changed, swap the order of all views. + private void updateOrder() { + boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; + boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder; + + if (mIsLayoutReverse != isLayoutReverse) { + // reversity changed, swap the order of all views. int childCount = getChildCount(); ArrayList<View> childList = new ArrayList<>(childCount); for (int i = 0; i < childCount; i++) { @@ -87,7 +96,7 @@ public class ReverseLinearLayout extends LinearLayout { for (int i = childCount - 1; i >= 0; i--) { super.addView(childList.get(i)); } - mIsLayoutRtl = isLayoutRtl; + mIsLayoutReverse = isLayoutReverse; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index d8b1a62f49b1..3df759068ae9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -265,6 +265,11 @@ public class KeyButtonView extends ImageView implements ButtonDispatcher.ButtonI public void setImageDrawable(@Nullable Drawable drawable) { super.setImageDrawable(drawable); } + + @Override + public void setLandscape(boolean landscape) { + //no op + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 7de38797adcc..e00674a55b1e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -2347,6 +2347,7 @@ public class NotificationStackScrollLayout extends ViewGroup if (hasAddEvent) { // This child was just added lets remove all events. mHeadsUpChangeAnimations.removeAll(mTmpList); + ((ExpandableNotificationRow ) child).setHeadsupDisappearRunning(false); } mTmpList.clear(); return hasAddEvent; @@ -3093,6 +3094,16 @@ public class NotificationStackScrollLayout extends ViewGroup requestChildrenUpdate(); runAnimationFinishedRunnables(); clearViewOverlays(); + clearHeadsUpDisappearRunning(); + } + + private void clearHeadsUpDisappearRunning() { + for (int i = 0; i < getChildCount(); i++) { + View view = getChildAt(i); + if (view instanceof ExpandableNotificationRow) { + ((ExpandableNotificationRow) view).setHeadsupDisappearRunning(false); + } + } } private void clearViewOverlays() { diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java index f01e95fa3873..995ecaed6ecf 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java @@ -124,12 +124,8 @@ public class ZenFooter extends LinearLayout { : null; Util.setText(mSummaryLine1, line1); - final boolean isForever = mConfig != null && mConfig.manualRule != null - && mConfig.manualRule.conditionId == null; - final CharSequence line2 = - isForever ? mContext.getString(com.android.internal.R.string.zen_mode_forever_dnd) - : ZenModeConfig.getConditionSummary(mContext, mConfig, mController.getCurrentUser(), - true /*shortVersion*/); + final CharSequence line2 = ZenModeConfig.getConditionSummary(mContext, mConfig, + mController.getCurrentUser(), true /*shortVersion*/); Util.setText(mSummaryLine2, line2); } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 45e3e7efdcdf..ba59c2f0192a 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -33,73 +33,61 @@ message MetricsEvent { // OPEN: Settings > Accessibility // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY = 2; // OPEN: Settings > Accessibility > Captions // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY_CAPTION_PROPERTIES = 3; // OPEN: Settings > Accessibility > [Service] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY_SERVICE = 4; // OPEN: Settings > Accessibility > Color correction // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY_TOGGLE_DALTONIZER = 5; // OPEN: Settings > Accessibility > Accessibility shortcut // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6; // OPEN: Settings > Accessibility > Magnification gestures // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7; // OPEN: Settings > Accounts // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCOUNT = 8; // OPEN: Settings > Accounts > [Single Account Sync Settings] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCOUNTS_ACCOUNT_SYNC = 9; // OPEN: Settings > Accounts > Add an account // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10; // OPEN: Settings > Accounts > [List of accounts when more than one] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACCOUNTS_MANAGE_ACCOUNTS = 11; // OPEN: Settings > Cellular network settings > APNs // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APN = 12; // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APN_EDITOR = 13; // OBSOLETE @@ -114,7 +102,6 @@ message MetricsEvent { // OPEN: Settings > Apps > Configure apps > App links > [App] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_APP_LAUNCH = 17; // OBSOLETE @@ -123,19 +110,16 @@ message MetricsEvent { // OPEN: Settings > Internal storage > Apps storage > [App] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_APP_STORAGE = 19; // OPEN: Settings > Apps > [App info] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_INSTALLED_APP_DETAILS = 20; // OPEN: Settings > Memory > App usage > [App Memory usage] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_PROCESS_STATS_DETAIL = 21; // OBSOLETE @@ -144,19 +128,16 @@ message MetricsEvent { // OPEN: Settings > Memory > App usage // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_PROCESS_STATS_UI = 23; // OPEN: Settings > Bluetooth // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 BLUETOOTH = 24; // OPEN: Choose Bluetooth device (ex: when sharing) // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 BLUETOOTH_DEVICE_PICKER = 25; // OBSOLETE @@ -165,55 +146,46 @@ message MetricsEvent { // OPEN: Settings > Security > Choose screen lock // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CHOOSE_LOCK_GENERIC = 27; // OPEN: Settings > Security > Choose screen lock > Choose your password // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CHOOSE_LOCK_PASSWORD = 28; // OPEN: Settings > Security > Choose screen lock > Choose your pattern // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CHOOSE_LOCK_PATTERN = 29; // OPEN: Settings > Security > Choose screen lock > Confirm your password // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CONFIRM_LOCK_PASSWORD = 30; // OPEN: Settings > Security > Choose screen lock > Confirm your pattern // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CONFIRM_LOCK_PATTERN = 31; // OPEN: Settings > Security > Encrypt phone // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CRYPT_KEEPER = 32; // OPEN: Settings > Security > Encrypt phone > Confirm // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 CRYPT_KEEPER_CONFIRM = 33; // OPEN: Settings > Search results // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DASHBOARD_SEARCH_RESULTS = 34; // OPEN: Settings (Root page) // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DASHBOARD_SUMMARY = 35; // OBSOLETE @@ -222,49 +194,41 @@ message MetricsEvent { // OPEN: Settings > Data usage // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DATA_USAGE_SUMMARY = 37; // OPEN: Settings > Date & time // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DATE_TIME = 38; // OPEN: Settings > Developer options // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVELOPMENT = 39; // OPEN: Settings > About phone // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVICEINFO = 40; // OPEN: Settings > About phone > Status > IMEI information // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVICEINFO_IMEI_INFORMATION = 41; // OPEN: Settings > Internal storage // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVICEINFO_STORAGE = 42; // OPEN: Settings > About phone > Status > SIM status // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVICEINFO_SIM_STATUS = 43; // OPEN: Settings > About phone > Status // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DEVICEINFO_STATUS = 44; // OBSOLETE @@ -273,25 +237,21 @@ message MetricsEvent { // OPEN: Settings > Display // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DISPLAY = 46; // OPEN: Settings > Display > Daydream // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 DREAM = 47; // OPEN: Settings > Security > Screen lock > Secure start-up // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ENCRYPTION = 48; // OPEN: Settings > Security > Nexus Imprint // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FINGERPRINT = 49; // OBSOLETE @@ -300,55 +260,46 @@ message MetricsEvent { // OPEN: Settings > Battery > History details // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FUELGAUGE_BATTERY_HISTORY_DETAIL = 51; // OPEN: Settings > Battery > Battery saver // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FUELGAUGE_BATTERY_SAVER = 52; // OPEN: Settings > Battery > [App Use details] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FUELGAUGE_POWER_USAGE_DETAIL = 53; // OPEN: Settings > Battery // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FUELGAUGE_POWER_USAGE_SUMMARY = 54; // OPEN: Settings > Home // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 HOME = 55; // OPEN: Settings > Security > SIM card lock settings // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ICC_LOCK = 56; // OPEN: Settings > Language & input // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 INPUTMETHOD_LANGUAGE = 57; // OPEN: Settings > Language & input > Physical keyboard // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 INPUTMETHOD_KEYBOARD = 58; // OPEN: Settings > Language & input > Spell checker // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 INPUTMETHOD_SPELL_CHECKERS = 59; // OBSOLETE @@ -357,79 +308,66 @@ message MetricsEvent { // OPEN: Settings > Language & input > Personal dictionary // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 INPUTMETHOD_USER_DICTIONARY = 61; // OPEN: Settings > Language & input > Add word // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62; // OPEN: Settings > Location // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 LOCATION = 63; // OPEN: Settings > Location > Location mode // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 LOCATION_MODE = 64; // OPEN: Settings > Apps // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 MANAGE_APPLICATIONS = 65; // OPEN: Settings > Backup & reset > Factory data reset // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 MASTER_CLEAR = 66; // OPEN: Settings > Backup & reset > Factory data reset > Confirm // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 MASTER_CLEAR_CONFIRM = 67; // OPEN: Settings > Data usage > Network restrictions // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NET_DATA_USAGE_METERED = 68; // OPEN: Settings > More > Android Beam // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NFC_BEAM = 69; // OPEN: Settings > Tap & pay // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NFC_PAYMENT = 70; // OPEN: Settings > Sound & notification // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION = 71; // OPEN: Settings > Sound & notification > App notifications > [App] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_APP_NOTIFICATION = 72; // OPEN: Settings > Sound & notification > Other sounds // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_OTHER_SOUND = 73; // OBSOLETE @@ -438,13 +376,11 @@ message MetricsEvent { // OPEN: Settings Widget > Notification log // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_STATION = 75; // OPEN: Settings > Sound & notification > Do not disturb // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE = 76; // OPEN: OBSOLETE @@ -453,25 +389,21 @@ message MetricsEvent { // OPEN: Print job notification > Print job settings // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 PRINT_JOB_SETTINGS = 78; // OPEN: Settings > Printing > [Print Service] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 PRINT_SERVICE_SETTINGS = 79; // OPEN: Settings > Printing // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 PRINT_SETTINGS = 80; // OPEN: Settings > Backup & reset // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 PRIVACY = 81; //OBSOLETE @@ -480,37 +412,31 @@ message MetricsEvent { // OPEN: Settings > Backup & reset > Network settings reset // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 RESET_NETWORK = 83; // OPEN: Settings > Backup & reset > Network settings reset > Confirm // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 RESET_NETWORK_CONFIRM = 84; // OPEN: Settings > Developer Options > Running Services // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 RUNNING_SERVICE_DETAILS = 85; // OPEN: Settings > Security > Screen pinning // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 SCREEN_PINNING = 86; // OPEN: Settings > Security // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 SECURITY = 87; // OPEN: Settings > SIM cards // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 SIM = 88; // OBSOLETE @@ -519,55 +445,46 @@ message MetricsEvent { // OPEN: Settings > More > Tethering & portable hotspot // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TETHER = 90; // OPEN: Settings > Security > Trust agents // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TRUST_AGENT = 91; // OPEN: Settings > Security > Trusted credentials // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TRUSTED_CREDENTIALS = 92; // OPEN: Settings > Language & input > TTS output > [Engine] > Settings // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TTS_ENGINE_SETTINGS = 93; // OPEN: Settings > Language & input > Text-to-speech output // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TTS_TEXT_TO_SPEECH = 94; // OPEN: Settings > Security > Apps with usage access // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 USAGE_ACCESS = 95; // OPEN: Settings > Users // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 USER = 96; // OPEN: Settings > Users > [Restricted profile app & content access] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 USERS_APP_RESTRICTIONS = 97; // OPEN: Settings > Users > [User settings] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 USER_DETAILS = 98; // OBSOLETE @@ -576,43 +493,36 @@ message MetricsEvent { // OPEN: Settings > More > VPN // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 VPN = 100; // OPEN: Settings > Display > Choose wallpaper from // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WALLPAPER_TYPE = 101; // OPEN: Settings > Display > Cast // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WFD_WIFI_DISPLAY = 102; // OPEN: Settings > Wi-Fi // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIFI = 103; // OPEN: Settings > Wi-Fi > Advanced Wi-Fi // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIFI_ADVANCED = 104; // OPEN: Settings > More > Wi-Fi Calling // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIFI_CALLING = 105; // OPEN: Settings > Wi-Fi > Saved networks // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIFI_SAVED_ACCESS_POINTS = 106; // OBSOLETE @@ -624,19 +534,16 @@ message MetricsEvent { // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIFI_P2P = 109; // OPEN: Settings > More // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 WIRELESS = 110; // OPEN: Quick Settings Panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_PANEL = 111; // OPEN: QS Airplane mode tile shown @@ -644,7 +551,6 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_AIRPLANEMODE = 112; // OPEN: QS Bluetooth tile shown @@ -652,21 +558,18 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_BLUETOOTH = 113; // OPEN: QS Cast tile shown // ACTION: QS Cast tile tapped // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_CAST = 114; // OPEN: QS Cellular tile shown // ACTION: QS Cellular tile tapped // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_CELLULAR = 115; // OPEN: QS Color inversion tile shown @@ -674,13 +577,11 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_COLORINVERSION = 116; // OPEN: QS Cellular tile > Cellular detail panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_DATAUSAGEDETAIL = 117; // OPEN: QS Do not disturb tile shown @@ -688,7 +589,6 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_DND = 118; // OPEN: QS Flashlight tile shown @@ -696,7 +596,6 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_FLASHLIGHT = 119; // OPEN: QS Hotspot tile shown @@ -704,14 +603,12 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_HOTSPOT = 120; // OPEN: QS 3P tile shown // ACTION: QS 3P tile tapped // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_INTENT = 121; // OPEN: QS Location tile shown @@ -719,7 +616,6 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_LOCATION = 122; // OPEN: QS Rotation tile shown @@ -727,7 +623,6 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_ROTATIONLOCK = 123; // OBSOLETE @@ -736,7 +631,6 @@ message MetricsEvent { // OPEN: QS User list panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_USERDETAIL = 125; // OPEN: QS WiFi tile shown @@ -744,13 +638,11 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.46 QS_WIFI = 126; // OPEN: Notification Panel (including lockscreen) // CATEGORY: NOTIFICATION // OS: 5.1.1 - // GMS: 7.5.26 NOTIFICATION_PANEL = 127; // OPEN: Notification in panel became visible. @@ -764,7 +656,6 @@ message MetricsEvent { // SUBTYPE: Dismiss reason from NotificationManagerService.java // CATEGORY: NOTIFICATION // OS: 5.1.1 - // GMS: 7.5.26 NOTIFICATION_ITEM = 128; // ACTION: User tapped notification action @@ -772,19 +663,16 @@ message MetricsEvent { // SUBTYPE: Index of action on notification // CATEGORY: NOTIFICATION // OS: 5.0 - // GMS: 7.5.26 NOTIFICATION_ITEM_ACTION = 129; // OPEN: Settings > Apps > Configure apps > App permissions // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_ADVANCED = 130; // OPEN: Settings > Location > Scanning // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 LOCATION_SCANNING = 131; // OBSOLETE @@ -793,43 +681,36 @@ message MetricsEvent { // OPEN: Settings > Sound & notification > App notifications // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 MANAGE_APPLICATIONS_NOTIFICATIONS = 133; // ACTION: Settings > Wi-Fi > Overflow > Add Network // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_ADD_NETWORK = 134; // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_CONNECT = 135; // ACTION: Settings > Wi-Fi > Overflow > Refresh // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_FORCE_SCAN = 136; // ACTION: Settings > Wi-Fi > [Long press network] > Forget network // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_FORGET = 137; // ACTION: Settings > Wi-Fi > Toggle off // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_OFF = 138; // ACTION: Settings > Wi-Fi > Toggle on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_WIFI_ON = 139; // OBSOLETE @@ -838,280 +719,236 @@ message MetricsEvent { // OPEN: Settings > Sound & notification > DND > Priority only allows // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_PRIORITY = 141; // OPEN: Settings > Sound & notification > DND > Automatic rules // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_AUTOMATION = 142; // OPEN: Settings > Apps > Configure apps > App links // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 MANAGE_DOMAIN_URLS = 143; // OPEN: Settings > Sound & notification > DND > [Time based rule] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144; // OPEN: Settings > Sound & notification > DND > [External rule] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145; // OPEN: Settings > Sound & notification > DND > [Event rule] // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_EVENT_RULE = 146; // ACTION: App notification settings > Block Notifications // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BAN_APP_NOTES = 147; // ACTION: Notification shade > Dismiss all button // CATEGORY: NOTIFICATION // OS: 6.0 - // GMS: 7.5.26 ACTION_DISMISS_ALL_NOTES = 148; // OPEN: QS Do Not Disturb detail panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_DND_DETAILS = 149; // OPEN: QS Bluetooth detail panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_BLUETOOTH_DETAILS = 150; // OPEN: QS Cast detail panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_CAST_DETAILS = 151; // OPEN: QS Wi-Fi detail panel // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_WIFI_DETAILS = 152; // ACTION: QS Wi-Fi detail panel > Wi-Fi toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_WIFI_TOGGLE = 153; // ACTION: QS Bluetooth detail panel > Bluetooth toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_BLUETOOTH_TOGGLE = 154; // ACTION: QS Cellular detail panel > Cellular toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_CELLULAR_TOGGLE = 155; // ACTION: QS User list panel > Select different user // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_SWITCH_USER = 156; // ACTION: QS Cast detail panel > Select cast device // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_CAST_SELECT = 157; // ACTION: QS Cast detail panel > Disconnect cast device // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_CAST_DISCONNECT = 158; // ACTION: Settings > Bluetooth > Toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BLUETOOTH_TOGGLE = 159; // ACTION: Settings > Bluetooth > Overflow > Refresh // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BLUETOOTH_SCAN = 160; // ACTION: Settings > Bluetooth > Overflow > Rename this device // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BLUETOOTH_RENAME = 161; // ACTION: Settings > Bluetooth > Overflow > Show received files // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BLUETOOTH_FILES = 162; // ACTION: QS DND details panel > Increase / Decrease exit time // SUBTYPE: true is increase, false is decrease // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_DND_TIME = 163; // ACTION: QS DND details panel > [Exit condition] // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_DND_CONDITION_SELECT = 164; // ACTION: QS DND details panel > [DND mode] // SUBTYPE: 1 is priority, 2 is silence, 3 is alarms only // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_DND_ZEN_SELECT = 165; // ACTION: QS DND detail panel > DND toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 QS_DND_TOGGLE = 166; // ACTION: DND Settings > Priority only allows > Reminder toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ALLOW_REMINDERS = 167; // ACTION: DND Settings > Priority only allows > Event toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ALLOW_EVENTS = 168; // ACTION: DND Settings > Priority only allows > Messages // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ALLOW_MESSAGES = 169; // ACTION: DND Settings > Priority only allows > Calls // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ALLOW_CALLS = 170; // ACTION: DND Settings > Priority only allows > Repeat callers toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ALLOW_REPEAT_CALLS = 171; // ACTION: DND Settings > Automatic rules > Add rule // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ADD_RULE = 172; // ACTION: DND Settings > Automatic rules > Add rule > OK // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ADD_RULE_OK = 173; // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_DELETE_RULE = 174; // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_DELETE_RULE_OK = 175; // ACTION: DND Settings > Automatic rules > [Rule] > Toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ZEN_ENABLE_RULE = 176; // ACTION: Settings > More > Airplane mode toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_AIRPLANE_TOGGLE = 177; // ACTION: Settings > Data usage > Cellular data toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_CELL_DATA_TOGGLE = 178; // OPEN: Settings > Sound & notification > Notification access // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ACCESS = 179; // OPEN: Settings > Sound & notification > Do Not Disturb access // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 NOTIFICATION_ZEN_MODE_ACCESS = 180; // OPEN: Settings > Apps > Configure apps > Default Apps // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_DEFAULT_APPS = 181; // OPEN: Settings > Internal storage > Apps storage // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_STORAGE_APPS = 182; // OPEN: Settings > Security > Usage access // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_USAGE_ACCESS_DETAIL = 183; // OPEN: Settings > Battery > Battery optimization // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_HIGH_POWER_APPS = 184; // OBSOLETE @@ -1120,448 +957,377 @@ message MetricsEvent { // ACTION: Lockscreen > Unlock gesture // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_UNLOCK = 186; // ACTION: Lockscreen > Pull shade open // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_SHADE = 187; // ACTION: Lockscreen > Tap on lock, shows hint // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_HINT = 188; // ACTION: Lockscreen > Camera // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_CAMERA = 189; // ACTION: Lockscreen > Dialer // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_DIALER = 190; // ACTION: Lockscreen > Tap on lock, locks phone // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_LOCK = 191; // ACTION: Lockscreen > Tap on notification, false touch rejection // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 ACTION_LS_NOTE = 192; // ACTION: Lockscreen > Swipe down to open quick settings // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.8.22 ACTION_LS_QS = 193; // ACTION: Swipe down to open quick settings when unlocked // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.8.22 ACTION_SHADE_QS_PULL = 194; // ACTION: Notification shade > Tap to open quick settings // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.8.22 ACTION_SHADE_QS_TAP = 195; // OPEN: Lockscreen // SUBTYPE: 0 is unsecure, 1 is secured by password / pattern / PIN // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 LOCKSCREEN = 196; // OPEN: Lockscreen > Screen to enter password / pattern / PIN // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 BOUNCER = 197; // OPEN: Screen turned on // SUBTYPE: 2 is user action // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.8.22 SCREEN = 198; // OPEN: Notification caused sound, vibration, and/or LED blink // SUBTYPE: 1 is buzz, 2 is beep, blink is 4, or'd together // CATEGORY: NOTIFICATION // OS: 5.1.1 - // GMS: 7.8.53 NOTIFICATION_ALERT = 199; // ACTION: Lockscreen > Emergency Call button // CATEGORY: GLOBAL_SYSTEM_UI // OS: 5.1.1 - // GMS: 7.5.26 ACTION_EMERGENCY_CALL = 200; // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 APPLICATIONS_MANAGE_ASSIST = 201; // OPEN: Settings > Memory // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 PROCESS_STATS_SUMMARY = 202; // ACTION: Settings > Display > When device is rotated // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_ROTATION_LOCK = 203; // ACTION: Long press on notification to view controls // CATEGORY: NOTIFICATION // OS: 6.0 - // GMS: 7.5.26 ACTION_NOTE_CONTROLS = 204; // ACTION: Notificatoin controls > Info button // CATEGORY: NOTIFICATION // OS: 6.0 - // GMS: 7.5.26 ACTION_NOTE_INFO = 205; // ACTION: Notification controls > Settings button // CATEGORY: NOTIFICATION // OS: 6.0 - // GMS: 7.5.26 ACTION_APP_NOTE_SETTINGS = 206; // OPEN: Volume Dialog (with hardware buttons) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 VOLUME_DIALOG = 207; // OPEN: Volume dialog > Expanded volume dialog (multiple sliders) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 VOLUME_DIALOG_DETAILS = 208; // ACTION: Volume dialog > Adjust volume slider // SUBTYPE: volume level (0-7) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_VOLUME_SLIDER = 209; // ACTION: Volume dialog > Select non-active stream // SUBTYPE: stream (defined in AudioSystem.java) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_VOLUME_STREAM = 210; // ACTION: Adjust volume with hardware key // SUBTYPE: volume level (0-7) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_VOLUME_KEY = 211; // ACTION: Volume dialog > Mute a stream by tapping icon // SUBTYPE: mute is 1, audible is 2 // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_VOLUME_ICON = 212; // ACTION: Volume dialog > Change ringer mode by tapping icon // SUBTYPE: 2 is audible, 3 is vibrate // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_RINGER_MODE = 213; // ACTION: Chooser shown (share target, file open, etc.) // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_ACTIVITY_CHOOSER_SHOWN = 214; // ACTION: Chooser > User taps an app target // SUBTYPE: Index of target // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215; // ACTION: Chooser > User taps a service target // SUBTYPE: Index of target // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216; // ACTION: Chooser > User taps a standard target // SUBTYPE: Index of target // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217; // ACTION: QS Brightness Slider (with auto brightness disabled) // SUBTYPE: slider value // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BRIGHTNESS = 218; // ACTION: QS Brightness Slider (with auto brightness enabled) // SUBTYPE: slider value // CATEGORY: QUICK_SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_BRIGHTNESS_AUTO = 219; // OPEN: Settings > Display > Brightness Slider // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 BRIGHTNESS_DIALOG = 220; // OPEN: Settings > Apps > Configure Apps > Draw over other apps // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 SYSTEM_ALERT_WINDOW_APPS = 221; // OPEN: Display has entered dream mode // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 DREAMING = 222; // OPEN: Display has entered ambient notification mode // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 DOZING = 223; // OPEN: Overview // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 OVERVIEW_ACTIVITY = 224; // OPEN: Settings > About phone > Legal information // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ABOUT_LEGAL_SETTINGS = 225; // OPEN: Settings > Search > Perform search // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 ACTION_SEARCH_RESULTS = 226; // OPEN: Settings > System UI Tuner // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER = 227; // OPEN: Settings > System UI Tuner > Quick Settings // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_QS = 228; // OPEN: Settings > System UI Tuner > Demo mode // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_DEMO_MODE = 229; // ACTION: Settings > System UI Tuner > Quick Settings > Move tile // PACKAGE: Tile // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_QS_REORDER = 230; // ACTION: Settings > System UI Tuner > Quick Settings > Add tile // PACKAGE: Tile // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_QS_ADD = 231; // ACTION: Settings > System UI Tuner > Quick Settings > Remove tile // PACKAGE: Tile // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_QS_REMOVE = 232; // ACTION: Settings > System UI Tuner > Status bar > Enable icon // PACKAGE: Icon // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_STATUS_BAR_ENABLE = 233; // ACTION: Settings > System UI Tuner > Status bar > Disable icon // PACKAGE: Icon // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_STATUS_BAR_DISABLE = 234; // ACTION: Settings > System UI Tuner > Demo mode > Enable demo mode // SUBTYPE: false is disabled, true is enabled // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_DEMO_MODE_ENABLED = 235; // ACTION: Settings > System UI Tuner > Demo mode > Show demo mode // SUBTYPE: false is disabled, true is enabled // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_DEMO_MODE_ON = 236; // ACTION: Settings > System UI Tuner > Show embedded battery percentage // SUBTYPE: 0 is disabled, 1 is enabled // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 TUNER_BATTERY_PERCENTAGE = 237; // OPEN: Settings > Developer options > Inactive apps // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.5.26 FUELGAUGE_INACTIVE_APPS = 238; // ACTION: Long press home to bring up assistant // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.5.26 ACTION_ASSIST_LONG_PRESS = 239; // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLLING = 240; // OPEN: Fingerprint Enroll > Find Sensor // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_FIND_SENSOR = 241; // OPEN: Fingerprint Enroll > Fingerprint Enrolled! // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_FINISH = 242; // OPEN: Fingerprint Enroll introduction // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_INTRO = 243; // OPEN: Fingerprint Enroll onboarding // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_ONBOARD = 244; // OPEN: Fingerprint Enroll > Let's Start! // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_SIDECAR = 245; // OPEN: Fingerprint Enroll SUW > Let's Start! // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLLING_SETUP = 246; // OPEN: Fingerprint Enroll SUW > Find Sensor // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_FIND_SENSOR_SETUP = 247; // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled! // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_FINISH_SETUP = 248; // OPEN: Fingerprint Enroll SUW introduction // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_INTRO_SETUP = 249; // OPEN: Fingerprint Enroll SUW onboarding // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 FINGERPRINT_ENROLL_ONBOARD_SETUP = 250; // ACTION: Add fingerprint > Enroll fingerprint // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 ACTION_FINGERPRINT_ENROLL = 251; // ACTION: Authenticate using fingerprint // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 ACTION_FINGERPRINT_AUTH = 252; // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 ACTION_FINGERPRINT_DELETE = 253; // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename // CATEGORY: SETTINGS // OS: 6.0 - // GMS: 7.8.99 ACTION_FINGERPRINT_RENAME = 254; // ACTION: Double tap camera shortcut // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.8.99 ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255; // ACTION: Double twist camera shortcut // CATEGORY: GLOBAL_SYSTEM_UI // OS: 6.0 - // GMS: 7.8.99 ACTION_WIGGLE_CAMERA_GESTURE = 256; // OPEN: QS Work Mode tile shown @@ -1569,13 +1335,11 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_WORKMODE = 257; // OPEN: Settings > Developer Options > Background Check // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 BACKGROUND_CHECK_SUMMARY = 258; // OPEN: QS Lock tile shown @@ -1583,52 +1347,44 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_LOCK_TILE = 259; // OPEN: QS User Tile shown // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_USER_TILE = 260; // OPEN: QS Battery tile shown // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_BATTERY_TILE = 261; // OPEN: Settings > Sound > Do not disturb > Visual interruptions // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 262; // ACTION: Visual interruptions > No screen interuptions toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF = 263; // ACTION: Visual interruptions > No notification light toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_ZEN_ALLOW_LIGHTS = 264; // OPEN: Settings > Notifications > [App] > Topic Notifications // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 NOTIFICATION_TOPIC_NOTIFICATION = 265; // ACTION: Settings > Apps > Default Apps > Select different SMS app // PACKAGE: Selected SMS app // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_DEFAULT_SMS_APP_CHANGED = 266; // OPEN: QS Color modification tile shown @@ -1636,105 +1392,88 @@ message MetricsEvent { // SUBTYPE: 0 is off, 1 is on // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_COLOR_MATRIX = 267; // OPEN: QS Custom tile shown // ACTION: QS Work Mode tile tapped // CATEGORY: QUICK_SETTINGS // OS: N - // GMS: 7.8.99 QS_CUSTOM = 268; // ACTION: Visual interruptions > Never turn off the screen toggle // SUBTYPE: 0 is off, 1 is on // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_ZEN_ALLOW_WHEN_SCREEN_ON = 269; // ACTION: Overview > Long-press task, drag to enter split-screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_WINDOW_DOCK_DRAG_DROP = 270; // ACTION: In App > Long-press Overview button to enter split-screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_WINDOW_DOCK_LONGPRESS = 271; // ACTION: In App > Swipe Overview button to enter split-screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_WINDOW_DOCK_SWIPE = 272; // ACTION: Launch profile-specific app > Confirm credentials // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 PROFILE_CHALLENGE = 273; // OPEN: QS Battery detail panel // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 QS_BATTERY_DETAIL = 274; // OPEN: Overview > History // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 OVERVIEW_HISTORY = 275; // ACTION: Overview > Page by tapping Overview button // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_OVERVIEW_PAGE = 276; // ACTION: Overview > Select app // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_OVERVIEW_SELECT = 277; // ACTION: View emergency info // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_VIEW_EMERGENCY_INFO = 278; // ACTION: Edit emergency info activity // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_EDIT_EMERGENCY_INFO = 279; // ACTION: Edit emergency info field // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_EDIT_EMERGENCY_INFO_FIELD = 280; // ACTION: Add emergency contact // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_ADD_EMERGENCY_CONTACT = 281; // ACTION: Delete emergency contact // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_DELETE_EMERGENCY_CONTACT = 282; // ACTION: Call emergency contact // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 ACTION_CALL_EMERGENCY_CONTACT = 283; // OPEN: QS Data Saver tile shown @@ -1745,13 +1484,11 @@ message MetricsEvent { // OPEN: Settings > Security > User credentials // CATEGORY: Settings // OS: N - // GMS: 7.8.99 USER_CREDENTIALS = 285; // ACTION: In App (splitscreen) > Long-press Overview to exit split-screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_WINDOW_UNDOCK_LONGPRESS = 286; // Logged when the user scrolls through overview manually @@ -1773,81 +1510,68 @@ message MetricsEvent { // ACTION: Long-press power button, then tap "Take bug report" option. // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE = 292; // ACTION: Long-press power button, then long-press "Take bug report" option. // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_FROM_POWER_MENU_FULL = 293; // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 // Interactive bug report initiated from Settings. ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294; // ACTION: Settings -> Developer Options -> Take bug report -> Full report // CATEGORY: SETTINGS // OS: N - // GMS: 7.8.99 // Interactive bug report initiated from Settings. ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295; // ACTION: User tapped notification action to cancel a bug report // CATEGORY: NOTIFICATION // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_CANCEL = 296; // ACTION: User tapped notification action to launch bug report details screen // CATEGORY: NOTIFICATION // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_DETAILS = 297; // ACTION: User tapped notification action to take adition screenshot on bug report // CATEGORY: NOTIFICATION // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT = 298; // ACTION: User tapped notification to share bug report // CATEGORY: NOTIFICATION // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE = 299; // ACTION: User changed bug report name using the details screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_NAME_CHANGED = 300; // ACTION: User changed bug report title using the details screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_TITLE_CHANGED = 301; // ACTION: User changed bug report description using the details screen // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_DESCRIPTION_CHANGED = 302; // ACTION: User tapped Save in the bug report details screen. // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_SAVED = 303; // ACTION: User tapped Cancel in the bug report details screen. // CATEGORY: GLOBAL_SYSTEM_UI // OS: N - // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_CANCELED = 304; // Tuner: Open/close calibrate dialog. @@ -1920,79 +1644,140 @@ message MetricsEvent { // the transition was executed. APP_TRANSITION_DEVICE_UPTIME_SECONDS = 325; - // User granted access to the request folder; action takes an integer - // representing the folder's index on Environment.STANDARD_DIRECTORIES - // (or -2 for root access, or -1 or unknown directory). + // ACTION: app requested access to a scoped directory, user granted it. + // SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER = 326; - // User denied access to the request folder; action takes an integer - // representing the folder's index on Environment.STANDARD_DIRECTORIES - // (or -2 for root access, or -1 or unknown directory). + // ACTION: app requested access to a scoped directory, user denied it. + // SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER = 327; - // User granted access to the request folder; action pass package name - // of calling package. + // ACTION: app requested access to a scoped directory, user granted it. + // PACKAGE: app that requested access + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE = 328; - // User denied access to the request folder; action pass package name - // of calling package. + // ACTION: app requested access to a scoped directory, user denied it. + // PACKAGE: app that requested access. + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE = 329; - // App requested access to a directory it has already been granted - // access before; action takes an integer representing the folder's - // index on Environment.STANDARD_DIRECTORIES - // (or -2 for root access, or -1 or unknown directory). + // ACTION: app requested access to a directory user has already been granted + // access before. + // SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES. + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER = 330; - // App requested access to a directory it has already been granted - // access before; action pass package name of calling package. + // ACTION: app requested access to a directory user has already been granted + // access before. + // PACKAGE: app that requested access. + // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE = 331; - // Logged when the user slides a notification and - // reveals the gear beneath it. + // ACTION: Logged when the user slides a notification and reveals the gear + // beneath it. + // CATEGORY: NOTIFICATION + // OS: N ACTION_REVEAL_GEAR = 332; - // Logged when the user taps on the gear beneath - // a notification. + // ACTION: Logged when the user taps on the gear beneath a notification. + // CATEGORY: NOTIFICATION + // OS: N ACTION_TOUCH_GEAR = 333; // Logs that the user has edited the enabled VR listeners. + // CATEGORY: SETTINGS + // OS: N VR_MANAGE_LISTENERS = 334; // Settings -> Accessibility -> Click after pointer stops moving + // CATEGORY: SETTINGS + // OS: N ACCESSIBILITY_TOGGLE_AUTOCLICK = 335; + // Settings -> Sound + // CATEGORY: SETTINGS + // OS: N SOUND = 336; + // Settings -> Notifications -> Gear + // CATEGORY: SETTINGS + // OS: N CONFIGURE_NOTIFICATION = 337; + // Settings -> Wi-Fi -> Gear + // CATEGORY: SETTINGS + // OS: N CONFIGURE_WIFI = 338; + // Settings -> Display -> Display size + // OS: N DISPLAY_SCREEN_ZOOM = 339; + // Settings -> Display -> Font size + // CATEGORY: SETTINGS + // OS: N ACCESSIBILITY_FONT_SIZE = 340; + // Settings -> Data usage -> Cellular/Wi-Fi data usage + // CATEGORY: SETTINGS + // OS: N DATA_USAGE_LIST = 341; + // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear + // CATEGORY: SETTINGS + // OS: N BILLING_CYCLE = 342; + // DATA_USAGE_LIST -> Any item or App info -> Data usage + // CATEGORY: SETTINGS + // OS: N APP_DATA_USAGE = 343; + // Settings -> Language & input -> Language + // CATEGORY: SETTINGS + // OS: N USER_LOCALE_LIST = 344; + // Settings -> Language & input -> Virtual keyboard + // CATEGORY: SETTINGS + // OS: N VIRTUAL_KEYBOARDS = 345; + // Settings -> Language & input -> Physical keyboard + // CATEGORY: SETTINGS + // OS: N PHYSICAL_KEYBOARDS = 346; + // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard + // CATEGORY: SETTINGS + // OS: N ENABLE_VIRTUAL_KEYBOARDS = 347; + // Settings -> Data usage -> Data Saver + // CATEGORY: SETTINGS + // OS: N DATA_SAVER_SUMMARY = 348; + // Settings -> Data usage -> Data Saver -> Unrestricted data access + // CATEGORY: SETTINGS + // OS: N DATA_USAGE_UNRESTRICTED_ACCESS = 349; // Used for generic logging of Settings Preference Persistence, should not be used // outside SharedPreferencesLogger. + // CATEGORY: SETTINGS + // OS: N ACTION_GENERIC_PACKAGE = 350; + // Settings -> Apps -> Gear -> Special access SPECIAL_ACCESS = 351; @@ -2158,15 +1943,28 @@ message MetricsEvent { // System UI Tuner > Other > Power notification controls > Toggle on/off ACTION_TUNER_POWER_NOTIFICATION_CONTROLS = 393; - // Action: user enable / disabled data saver using Settings. Arguments: - // 0: Data Saver mode is disabled. - // 1: Data Saver mode is enabled. + // Action: user enable / disabled data saver using Settings + // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle + // VALUE: 1 for enabled, 0 for disabled + // CATEGORY: SETTINGS + // OS: N ACTION_DATA_SAVER_MODE = 394; - // User whitelisted an app for Data Saver mode; action pass package name of app. + // User whitelisted an app for Data Saver mode; action pass package name of app + // Action: user enable / disabled data saver using Settings + // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on + // or + // Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on + // VALUE: package name of APP + // CATEGORY: SETTINGS + // OS: N ACTION_DATA_SAVER_WHITELIST = 395; - // User blacklisted an app for Data Saver mode; action pass package name of app. + // User blacklisted an app for Data Saver mode; action pass package name of app + // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off + // VALUE: package name of APP + // CATEGORY: SETTINGS + // OS: N ACTION_DATA_SAVER_BLACKLIST = 396; // User opened a remote input view associated with a notification. Passes package name of app @@ -2332,45 +2130,70 @@ message MetricsEvent { SUPPORT_FRAGMENT = 475; // ACTION: Settings -> Select summary tab. + // CATEGORY: SETTINGS ACTION_SELECT_SUMMARY=476; // ACTION: Settings -> Select support tab. + // CATEGORY: SETTINGS ACTION_SELECT_SUPPORT_FRAGMENT = 477; // ACTION: Settings -> Support -> Tips & tricks + // CATEGORY: SETTINGS ACTION_SUPPORT_TIPS_AND_TRICKS = 478; // ACTION: Settings -> Support -> Help & feedback + // CATEGORY: SETTINGS ACTION_SUPPORT_HELP_AND_FEEDBACK = 479; // ACTION: Settings -> Support -> Sign in + // CATEGORY: SETTINGS ACTION_SUPPORT_SIGN_IN = 480; // ACTION: Settings -> Support -> Phone + // CATEGORY: SETTINGS ACTION_SUPPORT_PHONE = 481; // ACTION: Settings -> Support -> Chat + // CATEGORY: SETTINGS ACTION_SUPPORT_CHAT = 482; // ACTION: Settings -> Support -> Phone/Chat -> Disclaimer Cancel + // CATEGORY: SETTINGS ACTION_SUPPORT_DISCLAIMER_CANCEL = 483; // ACTION: Settings -> Support -> Phone/Chat -> Disclaimer OK + // CATEGORY: SETTINGS ACTION_SUPPORT_DISCLAIMER_OK = 484; // ACTION: Settings -> Support -> Toll-Free Phone + // CATEGORY: SETTINGS ACTION_SUPPORT_DAIL_TOLLFREE = 485; // ACTION: Settings -> Support -> "Travel Abroad" Button + // CATEGORY: SETTINGS ACTION_SUPPORT_VIEW_TRAVEL_ABROAD_DIALOG = 486; // ACTION: Settings -> Support -> "Travel Abroad" Button -> Tolled Phone + // CATEGORY: SETTINGS ACTION_SUPPORT_DIAL_TOLLED = 487; // OPEN: Settings > Display > Night display // CATEGORY: SETTINGS NIGHT_DISPLAY_SETTINGS = 488; + // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager + // SUBTYPE: false is off, true is on + ACTION_TOGGLE_STORAGE_MANAGER = 489; + + // Settings launched from collapsed quick settings. + ACTION_QS_COLLAPSED_SETTINGS_LAUNCH = 490; + + // OPEN: QS Night mode tile shown + // ACTION: QS Night mode tile tapped + // SUBTYPE: 0 is off, 1 is on + // CATEGORY: QUICK_SETTINGS + QS_NIGHT_DISPLAY = 491; + // ---- End N-MR1 Constants, all N-MR1 constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4762a6785bb2..1f0dbfe361f7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -12042,6 +12042,9 @@ public final class ActivityManagerService extends ActivityManagerNative case ActivityManager.BUGREPORT_OPTION_REMOTE: service = "bugreportremote"; break; + case ActivityManager.BUGREPORT_OPTION_WEAR: + service = "bugreportwear"; + break; } if (service == null) { throw new IllegalArgumentException("Provided bugreport type is not correct, value: " diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 03843d11a62e..5807502ef791 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -743,6 +743,12 @@ class AppErrors { mService.updateCpuStatsNow(); } + // Unless configured otherwise, swallow ANRs in background processes & kill the process. + boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; + + boolean isSilentANR; + synchronized (mService) { // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. if (mService.mShuttingDown) { @@ -767,25 +773,29 @@ class AppErrors { // Dump thread traces as quickly as we can, starting with "interesting" processes. firstPids.add(app.pid); - int parentPid = app.pid; - if (parent != null && parent.app != null && parent.app.pid > 0) { - parentPid = parent.app.pid; - } - if (parentPid != app.pid) firstPids.add(parentPid); - - if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); - - for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { - ProcessRecord r = mService.mLruProcesses.get(i); - if (r != null && r.thread != null) { - int pid = r.pid; - if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { - if (r.persistent) { - firstPids.add(pid); - if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); - } else { - lastPids.put(pid, Boolean.TRUE); - if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); + // Don't dump other PIDs if it's a background ANR + isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID; + if (!isSilentANR) { + int parentPid = app.pid; + if (parent != null && parent.app != null && parent.app.pid > 0) { + parentPid = parent.app.pid; + } + if (parentPid != app.pid) firstPids.add(parentPid); + + if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); + + for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { + ProcessRecord r = mService.mLruProcesses.get(i); + if (r != null && r.thread != null) { + int pid = r.pid; + if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { + if (r.persistent) { + firstPids.add(pid); + if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); + } else { + lastPids.put(pid, Boolean.TRUE); + if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); + } } } } @@ -808,10 +818,18 @@ class AppErrors { info.append("Parent: ").append(parent.shortComponentName).append("\n"); } - final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); + ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); - File tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, - NATIVE_STACKS_OF_INTEREST); + String[] nativeProcs = NATIVE_STACKS_OF_INTEREST; + // don't dump native PIDs for background ANRs + File tracesFile = null; + if (isSilentANR) { + tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids, + null); + } else { + tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, + nativeProcs); + } String cpuInfo = null; if (ActivityManagerService.MONITOR_CPU_USAGE) { @@ -855,14 +873,10 @@ class AppErrors { } } - // Unless configured otherwise, swallow ANRs in background processes & kill the process. - boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; - synchronized (mService) { mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid); - if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { + if (isSilentANR) { app.kill("bg anr", true); return; } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 92b55db40cd8..12310e390061 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -591,13 +591,13 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering synchronized (mPublicSync) { TetherState tetherState = mTetherStates.get(iface); if (tetherState == null) { - Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); + Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring"); return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; } // Ignore the error status of the interface. If the interface is available, // the errors are referring to past tethering attempts anyway. if (tetherState.mLastState != IControlsTethering.STATE_AVAILABLE) { - Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); + Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring"); return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; } tetherState.mStateMachine.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED); @@ -1018,15 +1018,29 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering */ class UpstreamNetworkCallback extends NetworkCallback { @Override + public void onAvailable(Network network) { + mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK, + UpstreamNetworkMonitor.EVENT_ON_AVAILABLE, 0, network); + } + + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) { + mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK, + UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES, 0, + new NetworkState(null, null, newNc, network, null, null)); + } + + @Override public void onLinkPropertiesChanged(Network network, LinkProperties newLp) { - mTetherMasterSM.sendMessage( - TetherMasterSM.EVENT_UPSTREAM_LINKPROPERTIES_CHANGED, + mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK, + UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 0, new NetworkState(null, newLp, null, network, null, null)); } @Override public void onLost(Network network) { - mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_LOST, network); + mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK, + UpstreamNetworkMonitor.EVENT_ON_LOST, 0, network); } } @@ -1045,6 +1059,11 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering * could/should be moved here. */ class UpstreamNetworkMonitor { + static final int EVENT_ON_AVAILABLE = 1; + static final int EVENT_ON_CAPABILITIES = 2; + static final int EVENT_ON_LINKPROPERTIES = 3; + static final int EVENT_ON_LOST = 4; + final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>(); NetworkCallback mDefaultNetworkCallback; NetworkCallback mDunTetheringCallback; @@ -1079,33 +1098,107 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering mNetworkMap.clear(); } - // Returns true if these updated LinkProperties pertain to the current - // upstream network interface, false otherwise (or if there is not - // currently any upstream tethering interface). - boolean processLinkPropertiesChanged(NetworkState networkState) { - if (networkState == null || - networkState.network == null || - networkState.linkProperties == null) { - return false; - } + NetworkState lookup(Network network) { + return (network != null) ? mNetworkMap.get(network) : null; + } - mNetworkMap.put(networkState.network, networkState); + NetworkState processCallback(int arg1, Object obj) { + switch (arg1) { + case EVENT_ON_AVAILABLE: { + final Network network = (Network) obj; + if (VDBG) { + Log.d(TAG, "EVENT_ON_AVAILABLE for " + network); + } + if (!mNetworkMap.containsKey(network)) { + mNetworkMap.put(network, + new NetworkState(null, null, null, network, null, null)); + } + + final ConnectivityManager cm = getConnectivityManager(); + + if (mDefaultNetworkCallback != null) { + cm.requestNetworkCapabilities(mDefaultNetworkCallback); + cm.requestLinkProperties(mDefaultNetworkCallback); + } - if (mCurrentUpstreamIface != null) { - for (String ifname : networkState.linkProperties.getAllInterfaceNames()) { - if (mCurrentUpstreamIface.equals(ifname)) { - return true; + // Requesting updates for mDunTetheringCallback is not + // necessary. Because it's a listen, it will already have + // heard all NetworkCapabilities and LinkProperties updates + // since UpstreamNetworkMonitor was started. Because we + // start UpstreamNetworkMonitor before chooseUpstreamType() + // is ever invoked (it can register a DUN request) this is + // mostly safe. However, if a DUN network is already up for + // some reason (unlikely, because DUN is restricted and, + // unless the DUN network is shared with another APN, only + // the system can request it and this is the only part of + // the system that requests it) we won't know its + // LinkProperties or NetworkCapabilities. + + return mNetworkMap.get(network); + } + case EVENT_ON_CAPABILITIES: { + final NetworkState ns = (NetworkState) obj; + if (!mNetworkMap.containsKey(ns.network)) { + // Ignore updates for networks for which we have not yet + // received onAvailable() - which should never happen - + // or for which we have already received onLost(). + return null; + } + if (VDBG) { + Log.d(TAG, String.format("EVENT_ON_CAPABILITIES for %s: %s", + ns.network, ns.networkCapabilities)); } + + final NetworkState prev = mNetworkMap.get(ns.network); + mNetworkMap.put(ns.network, + new NetworkState(null, prev.linkProperties, ns.networkCapabilities, + ns.network, null, null)); + return mNetworkMap.get(ns.network); } + case EVENT_ON_LINKPROPERTIES: { + final NetworkState ns = (NetworkState) obj; + if (!mNetworkMap.containsKey(ns.network)) { + // Ignore updates for networks for which we have not yet + // received onAvailable() - which should never happen - + // or for which we have already received onLost(). + return null; + } + if (VDBG) { + Log.d(TAG, String.format("EVENT_ON_LINKPROPERTIES for %s: %s", + ns.network, ns.linkProperties)); + } + + final NetworkState prev = mNetworkMap.get(ns.network); + mNetworkMap.put(ns.network, + new NetworkState(null, ns.linkProperties, prev.networkCapabilities, + ns.network, null, null)); + return mNetworkMap.get(ns.network); + } + case EVENT_ON_LOST: { + final Network network = (Network) obj; + if (VDBG) { + Log.d(TAG, "EVENT_ON_LOST for " + network); + } + return mNetworkMap.remove(network); + } + default: + return null; } - return false; } + } - void processNetworkLost(Network network) { - if (network != null) { - mNetworkMap.remove(network); + // Needed because the canonical source of upstream truth is just the + // upstream interface name, |mCurrentUpstreamIface|. This is ripe for + // future simplification, once the upstream Network is canonical. + boolean pertainsToCurrentUpstream(NetworkState ns) { + if (ns != null && ns.linkProperties != null && mCurrentUpstreamIface != null) { + for (String ifname : ns.linkProperties.getAllInterfaceNames()) { + if (mCurrentUpstreamIface.equals(ifname)) { + return true; + } } } + return false; } class TetherMasterSM extends StateMachine { @@ -1120,8 +1213,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4; // Events from NetworkCallbacks that we process on the master state // machine thread on behalf of the UpstreamNetworkMonitor. - static final int EVENT_UPSTREAM_LINKPROPERTIES_CHANGED = BASE_MASTER + 5; - static final int EVENT_UPSTREAM_LOST = BASE_MASTER + 6; + static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5; private State mInitialState; private State mTetherModeAliveState; @@ -1278,6 +1370,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } protected void chooseUpstreamType(boolean tryCell) { + final ConnectivityManager cm = getConnectivityManager(); int upType = ConnectivityManager.TYPE_NONE; String iface = null; @@ -1292,8 +1385,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } for (Integer netType : mUpstreamIfaceTypes) { - NetworkInfo info = - getConnectivityManager().getNetworkInfo(netType.intValue()); + NetworkInfo info = cm.getNetworkInfo(netType.intValue()); if ((info != null) && info.isConnected()) { upType = netType.intValue(); break; @@ -1334,9 +1426,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering break; } + Network network = null; if (upType != ConnectivityManager.TYPE_NONE) { - LinkProperties linkProperties = - getConnectivityManager().getLinkProperties(upType); + LinkProperties linkProperties = cm.getLinkProperties(upType); if (linkProperties != null) { // Find the interface with the default IPv4 route. It may be the // interface described by linkProperties, or one of the interfaces @@ -1353,7 +1445,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } if (iface != null) { - Network network = getConnectivityManager().getNetworkForType(upType); + network = cm.getNetworkForType(upType); if (network == null) { Log.e(TAG, "No Network for upstream type " + upType + "!"); } @@ -1361,6 +1453,13 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } } notifyTetheredOfNewUpstreamIface(iface); + NetworkState ns = mUpstreamNetworkMonitor.lookup(network); + if (ns != null && pertainsToCurrentUpstream(ns)) { + // If we already have NetworkState for this network examine + // it immediately, because there likely will be no second + // EVENT_ON_AVAILABLE (it was already received). + handleNewUpstreamNetworkState(ns); + } } protected void setDnsForwarders(final Network network, final LinkProperties lp) { @@ -1393,6 +1492,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering ifaceName); } } + + protected void handleNewUpstreamNetworkState(NetworkState ns) { + mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns); + } } private final AtomicInteger mSimBcastGenerationNumber = new AtomicInteger(0); @@ -1582,24 +1685,55 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering chooseUpstreamType(mTryCell); mTryCell = !mTryCell; break; - case EVENT_UPSTREAM_LINKPROPERTIES_CHANGED: - NetworkState state = (NetworkState) message.obj; - if (mUpstreamNetworkMonitor.processLinkPropertiesChanged(state)) { - setDnsForwarders(state.network, state.linkProperties); - } else if (mCurrentUpstreamIface == null) { - // If we have no upstream interface, try to run through upstream - // selection again. If, for example, IPv4 connectivity has shown up - // after IPv6 (e.g., 464xlat became available) we want the chance to - // notice and act accordingly. - chooseUpstreamType(false); + case EVENT_UPSTREAM_CALLBACK: { + // First: always update local state about every network. + final NetworkState ns = mUpstreamNetworkMonitor.processCallback( + message.arg1, message.obj); + + if (ns == null || !pertainsToCurrentUpstream(ns)) { + // TODO: In future, this is where upstream evaluation and selection + // could be handled for notifications which include sufficient data. + // For example, after CONNECTIVITY_ACTION listening is removed, here + // is where we could observe a Wi-Fi network becoming available and + // passing validation. + if (mCurrentUpstreamIface == null) { + // If we have no upstream interface, try to run through upstream + // selection again. If, for example, IPv4 connectivity has shown up + // after IPv6 (e.g., 464xlat became available) we want the chance to + // notice and act accordingly. + chooseUpstreamType(false); + } + break; + } + + switch (message.arg1) { + case UpstreamNetworkMonitor.EVENT_ON_AVAILABLE: + // The default network changed, or DUN connected + // before this callback was processed. Updates + // for the current NetworkCapabilities and + // LinkProperties have been requested (default + // request) or are being sent shortly (DUN). Do + // nothing until they arrive; if no updates + // arrive there's nothing to do. + break; + case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES: + handleNewUpstreamNetworkState(ns); + break; + case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: + setDnsForwarders(ns.network, ns.linkProperties); + handleNewUpstreamNetworkState(ns); + break; + case UpstreamNetworkMonitor.EVENT_ON_LOST: + // TODO: Re-evaluate possible upstreams. Currently upstream + // reevaluation is triggered via received CONNECTIVITY_ACTION + // broadcasts that result in being passed a + // TetherMasterSM.CMD_UPSTREAM_CHANGED. + break; + default: + break; } break; - case EVENT_UPSTREAM_LOST: - // TODO: Re-evaluate possible upstreams. Currently upstream reevaluation - // is triggered via received CONNECTIVITY_ACTION broadcasts that result - // in being passed a TetherMasterSM.CMD_UPSTREAM_CHANGED. - mUpstreamNetworkMonitor.processNetworkLost((Network) message.obj); - break; + } default: retValue = false; break; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index f15fdd5304a1..b22a08484b8a 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1241,6 +1241,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { // TODO: reach into ConnectivityManager to proactively disable bringing // up this network, since we know that traffic will be blocked. + + if (template.getMatchRule() == MATCH_MOBILE_ALL) { + // If mobile data usage hits the limit or if the user resumes the data, we need to + // notify telephony. + final SubscriptionManager sm = SubscriptionManager.from(mContext); + final TelephonyManager tm = TelephonyManager.from(mContext); + + final int[] subIds = sm.getActiveSubscriptionIdList(); + for (int subId : subIds) { + final String subscriberId = tm.getSubscriberId(subId); + final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); + // Template is matched when subscriber id matches. + if (template.matches(probeIdent)) { + tm.setPolicyDataEnabled(enabled, subId); + } + } + } } /** diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ec77dafb2914..8d19a24753a2 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1851,7 +1851,7 @@ public class NotificationManagerService extends SystemService { enforceSystemOrSystemUIOrVolume("INotificationManager.setZenMode"); final long identity = Binder.clearCallingIdentity(); try { - mZenModeHelper.setManualZenMode(mode, conditionId, reason); + mZenModeHelper.setManualZenMode(mode, conditionId, null, reason); } finally { Binder.restoreCallingIdentity(identity); } @@ -1928,7 +1928,7 @@ public class NotificationManagerService extends SystemService { if (zen == -1) throw new IllegalArgumentException("Invalid filter: " + filter); final long identity = Binder.clearCallingIdentity(); try { - mZenModeHelper.setManualZenMode(zen, null, "setInterruptionFilter"); + mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter"); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 6864ed898ada..8c9dc3ba60f2 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -54,7 +54,6 @@ import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ZenRule; -import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.Log; import android.util.SparseArray; @@ -229,7 +228,7 @@ public class ZenModeHelper { public void requestFromListener(ComponentName name, int filter) { final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1); if (newZen != -1) { - setManualZenMode(newZen, null, + setManualZenMode(newZen, null, name != null ? name.getPackageName() : null, "listener:" + (name != null ? name.flattenToShortString() : null)); } } @@ -452,11 +451,11 @@ public class ZenModeHelper { rule.creationTime); } - public void setManualZenMode(int zenMode, Uri conditionId, String reason) { - setManualZenMode(zenMode, conditionId, reason, true /*setRingerMode*/); + public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) { + setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/); } - private void setManualZenMode(int zenMode, Uri conditionId, String reason, + private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller, boolean setRingerMode) { ZenModeConfig newConfig; synchronized (mConfig) { @@ -478,6 +477,7 @@ public class ZenModeHelper { newRule.enabled = true; newRule.zenMode = zenMode; newRule.conditionId = conditionId; + newRule.enabler = caller; newConfig.manualRule = newRule; } setConfigLocked(newConfig, reason, setRingerMode); @@ -950,7 +950,8 @@ public class ZenModeHelper { break; } if (newZen != -1) { - setManualZenMode(newZen, null, "ringerModeInternal", false /*setRingerMode*/); + setManualZenMode(newZen, null, "ringerModeInternal", null, + false /*setRingerMode*/); } if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) { @@ -988,7 +989,8 @@ public class ZenModeHelper { break; } if (newZen != -1) { - setManualZenMode(newZen, null, "ringerModeExternal", false /*setRingerMode*/); + setManualZenMode(newZen, null, "ringerModeExternal", caller, + false /*setRingerMode*/); } ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller, diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index 098b39e50d92..1cff926d14e1 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -31,6 +31,7 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.print.PrintManager; import android.provider.CalendarContract; import android.provider.ContactsContract; @@ -605,6 +606,15 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(nfcTagPkg, CONTACTS_PERMISSIONS, false, userId); grantRuntimePermissionsLPw(nfcTagPkg, PHONE_PERMISSIONS, false, userId); } + + // Storage Manager + Intent storageManagerIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); + PackageParser.Package storageManagerPckg = getDefaultSystemHandlerActivityPackageLPr( + storageManagerIntent, userId); + if (storageManagerPckg != null + && doesPackageSupportRuntimePermissions(storageManagerPckg)) { + grantRuntimePermissionsLPw(storageManagerPckg, STORAGE_PERMISSIONS, true, userId); + } mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId); } } @@ -619,6 +629,7 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(dialerPackage, CAMERA_PERMISSIONS, userId); } } @@ -656,6 +667,7 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId); grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, false, true, userId); grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(dialerPackage, CAMERA_PERMISSIONS, false, true, userId); } } diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 01b3dc28b50e..02c6472b2f88 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -213,9 +213,19 @@ public class OtaDexoptService extends IOtaDexopt.Stub { // Use the package manager install and install lock here for the OTA dex optimizer. PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( collectingInstaller, mPackageManagerService.mInstallLock, mContext); + // Make sure that core apps are optimized according to their own "reason". + // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed + // (by default is speed-profile) they will be interepreted/JITed. This in itself is not a + // problem as we will end up doing profile guided compilation. However, some core apps may + // be loaded by system server which doesn't JIT and we need to make sure we don't + // interpret-only + int compilationReason = nextPackage.coreApp + ? PackageManagerService.REASON_CORE_APP + : PackageManagerService.REASON_AB_OTA; + optimizer.performDexOpt(nextPackage, nextPackage.usesLibraryFiles, null /* ISAs */, false /* checkProfiles */, - getCompilerFilterForReason(PackageManagerService.REASON_AB_OTA)); + getCompilerFilterForReason(compilationReason)); mCommandsForCurrentPackage = collectingConnection.commands; if (mCommandsForCurrentPackage.isEmpty()) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index a3cf9c856ae5..6a56fa6e629b 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -182,6 +182,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub { */ private final Random mRandom = new SecureRandom(); + /** All sessions allocated */ + @GuardedBy("mSessions") + private final SparseBooleanArray mAllocatedSessions = new SparseBooleanArray(); + @GuardedBy("mSessions") private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>(); @@ -365,6 +369,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { // keep details around for dumpsys. mHistoricalSessions.put(session.sessionId, session); } + mAllocatedSessions.put(session.sessionId, true); } } } @@ -768,8 +773,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { int sessionId; do { sessionId = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1; - if (mSessions.get(sessionId) == null && mHistoricalSessions.get(sessionId) == null - && !mLegacySessions.get(sessionId, false)) { + if (!mAllocatedSessions.get(sessionId, false)) { + mAllocatedSessions.put(sessionId, true); return sessionId; } } while (n++ < 32); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 1ca61480973a..78fa3a37dcf5 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -95,6 +95,7 @@ import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; +import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; @@ -159,7 +160,6 @@ import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; -import android.content.pm.ShortcutServiceInternal; import android.content.pm.Signature; import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; @@ -2801,7 +2801,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - int[] stats = performDexOpt(coreApps, false, + int[] stats = performDexOptUpgrade(coreApps, false, getCompilerFilterForReason(REASON_CORE_APP)); final int elapsedTimeSeconds = @@ -7325,7 +7325,7 @@ public class PackageManagerService extends IPackageManager.Stub { } final long startTime = System.nanoTime(); - final int[] stats = performDexOpt(pkgs, mIsPreNUpgrade /* showDialog */, + final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); final int elapsedTimeSeconds = @@ -7344,7 +7344,7 @@ public class PackageManagerService extends IPackageManager.Stub { * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} * and {@code numberOfPackagesFailed}. */ - private int[] performDexOpt(List<PackageParser.Package> pkgs, boolean showDialog, + private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, String compilerFilter) { int numberOfPackagesVisited = 0; @@ -7378,6 +7378,19 @@ public class PackageManagerService extends IPackageManager.Stub { } } + // If the OTA updates a system app which was previously preopted to a non-preopted state + // the app might end up being verified at runtime. That's because by default the apps + // are verify-profile but for preopted apps there's no profile. + // Do a hacky check to ensure that if we have no profiles (a reasonable indication + // that before the OTA the app was preopted) the app gets compiled with a non-profile + // filter (by default interpret-only). + // Note that at this stage unused apps are already filtered. + if (isSystemApp(pkg) && + DexFile.isProfileGuidedCompilerFilter(compilerFilter) && + !Environment.getReferenceProfile(pkg.packageName).exists()) { + compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); + } + // checkProfiles is false to avoid merging profiles during boot which // might interfere with background compilation (b/28612421). // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will @@ -11439,9 +11452,6 @@ public class PackageManagerService extends IPackageManager.Stub { } else { resolvedUserIds = userIds; } - final ShortcutServiceInternal shortcutService = - LocalServices.getService(ShortcutServiceInternal.class); - for (int id : resolvedUserIds) { final Intent intent = new Intent(action, pkg != null ? Uri.fromParts("package", pkg, null) : null); @@ -11466,10 +11476,6 @@ public class PackageManagerService extends IPackageManager.Stub { + intent.toShortString(false, true, false, false) + " " + intent.getExtras(), here); } - // TODO b/29385425 Consider making lifecycle callbacks for this. - if (shortcutService != null) { - shortcutService.onPackageBroadcast(intent); - } am.broadcastIntent(null, intent, null, finishedReceiver, 0, null, null, null, android.app.AppOpsManager.OP_NONE, null, finishedReceiver != null, false, id); diff --git a/services/core/java/com/android/server/pm/ShortcutPendingTasks.java b/services/core/java/com/android/server/pm/ShortcutPendingTasks.java deleted file mode 100644 index a5ace56fee1f..000000000000 --- a/services/core/java/com/android/server/pm/ShortcutPendingTasks.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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.server.pm; - -import android.annotation.NonNull; -import android.util.Slog; - -import java.io.PrintWriter; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.logging.Handler; - -/** - * Used by {@link ShortcutService} to register tasks to be executed on Handler and also wait for - * all pending tasks. - * - * Tasks can be registered with {@link #addTask(Runnable)}. Call {@link #waitOnAllTasks()} to wait - * on all tasks that have been registered. - * - * In order to avoid deadlocks, {@link #waitOnAllTasks} MUST NOT be called with any lock held, nor - * on the handler thread. These conditions are checked by {@link #mWaitThreadChecker} and wtf'ed. - * - * During unit tests, we can't run tasks asynchronously, so we just run Runnables synchronously, - * which also means the "is lock held" check doesn't work properly during unit tests (e.g. normally - * when a Runnable is executed on a Handler, the thread doesn't hold any lock, but during the tests - * we just run a Runnable on the thread that registers it, so the thread may or may not hold locks.) - * So unfortunately we have to disable {@link #mWaitThreadChecker} during unit tests. - * - * Because of the complications like those, this class should be used only for specific purposes: - * - {@link #addTask(Runnable)} should only be used to register tasks on callbacks from lower level - * services like the package manager or the activity manager. - * - * - {@link #waitOnAllTasks} should only be called at the entry point of RPC calls (or the test only - * accessors}. - */ -public class ShortcutPendingTasks { - private static final String TAG = "ShortcutPendingTasks"; - - private static final boolean DEBUG = false || ShortcutService.DEBUG; // DO NOT SUBMIT WITH TRUE. - - private final Consumer<Runnable> mRunner; - - private final BooleanSupplier mWaitThreadChecker; - - private final Consumer<Throwable> mExceptionHandler; - - /** # of tasks in the queue, including the running one. */ - private final AtomicInteger mRunningTaskCount = new AtomicInteger(); - - /** For dumpsys */ - private final AtomicLong mLastTaskStartTime = new AtomicLong(); - - /** - * Constructor. In order to allow injection during unit tests, it doesn't take a - * {@link Handler} directly, and instead takes {@code runner} which will post an argument - * to a handler. - */ - public ShortcutPendingTasks(Consumer<Runnable> runner, BooleanSupplier waitThreadChecker, - Consumer<Throwable> exceptionHandler) { - mRunner = runner; - mWaitThreadChecker = waitThreadChecker; - mExceptionHandler = exceptionHandler; - } - - private static void dlog(String message) { - if (DEBUG) { - Slog.d(TAG, message); - } - } - - /** - * Block until all tasks that are already queued finish. DO NOT call it while holding any lock - * or on the handler thread. - */ - public boolean waitOnAllTasks() { - dlog("waitOnAllTasks: enter"); - try { - // Make sure it's not holding the lock. - if (!mWaitThreadChecker.getAsBoolean()) { - return false; - } - - // Optimize for the no-task case. - if (mRunningTaskCount.get() == 0) { - return true; - } - - final CountDownLatch latch = new CountDownLatch(1); - - addTask(latch::countDown); - - for (; ; ) { - try { - if (latch.await(1, TimeUnit.SECONDS)) { - return true; - } - dlog("waitOnAllTasks: Task(s) still running..."); - } catch (InterruptedException ignore) { - } - } - } finally { - dlog("waitOnAllTasks: exit"); - } - } - - /** - * Add a new task. This operation is lock-free. - */ - public void addTask(Runnable task) { - mRunningTaskCount.incrementAndGet(); - mLastTaskStartTime.set(System.currentTimeMillis()); - - dlog("Task registered"); - - mRunner.accept(() -> { - try { - dlog("Task started"); - - task.run(); - } catch (Throwable th) { - mExceptionHandler.accept(th); - } finally { - dlog("Task finished"); - mRunningTaskCount.decrementAndGet(); - } - }); - } - - public void dump(@NonNull PrintWriter pw, @NonNull String prefix) { - pw.print(prefix); - pw.print("Pending tasks: # running tasks: "); - pw.println(mRunningTaskCount.get()); - - pw.print(prefix); - pw.print(" Last task started time: "); - final long lastStarted = mLastTaskStartTime.get(); - pw.print(" ["); - pw.print(lastStarted); - pw.print("] "); - pw.println(ShortcutService.formatTime(lastStarted)); - } -} diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index a9018b3a5a84..5f8cbbf0544b 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -49,7 +49,6 @@ import android.graphics.Bitmap.CompressFormat; import android.graphics.Canvas; import android.graphics.RectF; import android.graphics.drawable.Icon; -import android.net.Uri; import android.os.Binder; import android.os.Environment; import android.os.FileUtils; @@ -82,6 +81,7 @@ import android.view.IWindowManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Preconditions; @@ -122,6 +122,9 @@ import java.util.function.Predicate; /** * TODO: + * - Deal with the async nature of PACKAGE_ADD. Basically when a publisher does anything after + * it's upgraded, the manager should make sure the upgrade process has been executed. + * * - getIconMaxWidth()/getIconMaxHeight() should use xdpi and ydpi. * -> But TypedValue.applyDimension() doesn't differentiate x and y..? * @@ -301,8 +304,6 @@ public class ShortcutService extends IShortcutService.Stub { private final AtomicBoolean mBootCompleted = new AtomicBoolean(); - private final ShortcutPendingTasks mPendingTasks; - private static final int PACKAGE_MATCH_FLAGS = PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE @@ -376,41 +377,16 @@ public class ShortcutService extends IShortcutService.Stub { mUsageStatsManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UsageStatsManagerInternal.class)); - mPendingTasks = new ShortcutPendingTasks( - this::injectPostToHandler, - this::injectCheckPendingTaskWaitThread, - throwable -> wtf(throwable.getMessage(), throwable)); - if (onlyForPackageManagerApis) { return; // Don't do anything further. For unit tests only. } + mPackageMonitor.register(context, looper, UserHandle.ALL, /* externalStorage= */ false); + injectRegisterUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE); } - /** - * Check whether {@link ShortcutPendingTasks#waitOnAllTasks()} can be called on the current - * thread. - * - * During unit tests, all tasks are executed synchronously which makes the lock held check would - * misfire, so we override this method to always return true. - */ - @VisibleForTesting - boolean injectCheckPendingTaskWaitThread() { - // We shouldn't wait while holding mLock. We should never do this so wtf(). - if (Thread.holdsLock(mLock)) { - wtf("waitOnAllTasks() called while holding the lock"); - return false; - } - // This shouldn't be called on the handler thread either. - if (Thread.currentThread() == mHandler.getLooper().getThread()) { - wtf("waitOnAllTasks() called on handler thread"); - return false; - } - return true; - } - void logDurationStat(int statId, long start) { synchronized (mStatLock) { mCountStats[statId]++; @@ -1516,8 +1492,6 @@ public class ShortcutService extends IShortcutService.Stub { @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); @@ -1567,8 +1541,6 @@ public class ShortcutService extends IShortcutService.Stub { @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); @@ -1647,8 +1619,6 @@ public class ShortcutService extends IShortcutService.Stub { @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); @@ -1699,8 +1669,6 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId); @@ -1728,8 +1696,6 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId); @@ -1750,8 +1716,6 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId); @@ -1774,8 +1738,6 @@ public class ShortcutService extends IShortcutService.Stub { public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts(); } @@ -1788,9 +1750,6 @@ public class ShortcutService extends IShortcutService.Stub { public ParceledListSlice<ShortcutInfo> getDynamicShortcuts(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { return getShortcutsWithQueryLocked( packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR, @@ -1802,9 +1761,6 @@ public class ShortcutService extends IShortcutService.Stub { public ParceledListSlice<ShortcutInfo> getManifestShortcuts(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { return getShortcutsWithQueryLocked( packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR, @@ -1816,9 +1772,6 @@ public class ShortcutService extends IShortcutService.Stub { public ParceledListSlice<ShortcutInfo> getPinnedShortcuts(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { return getShortcutsWithQueryLocked( packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR, @@ -1848,8 +1801,6 @@ public class ShortcutService extends IShortcutService.Stub { public int getRemainingCallCount(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { return mMaxUpdatesPerInterval - getPackageShortcutsLocked(packageName, userId).getApiCallCount(); @@ -1860,8 +1811,6 @@ public class ShortcutService extends IShortcutService.Stub { public long getRateLimitResetTime(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { return getNextResetTimeLocked(); } @@ -1880,8 +1829,6 @@ public class ShortcutService extends IShortcutService.Stub { public void reportShortcutUsed(String packageName, String shortcutId, int userId) { verifyCaller(packageName, userId); - mPendingTasks.waitOnAllTasks(); - Preconditions.checkNotNull(shortcutId); if (DEBUG) { @@ -1914,8 +1861,6 @@ public class ShortcutService extends IShortcutService.Stub { public void resetThrottling() { enforceSystemOrShell(); - mPendingTasks.waitOnAllTasks(); - resetThrottlingInner(getCallingUserId()); } @@ -1948,9 +1893,6 @@ public class ShortcutService extends IShortcutService.Stub { if (DEBUG) { Slog.d(TAG, "onApplicationActive: package=" + packageName + " userid=" + userId); } - - mPendingTasks.waitOnAllTasks(); - enforceResetThrottlingPermission(); resetPackageThrottling(packageName, userId); } @@ -2113,14 +2055,6 @@ public class ShortcutService extends IShortcutService.Stub { @Nullable String packageName, @Nullable List<String> shortcutIds, @Nullable ComponentName componentName, int queryFlags, int userId) { - - // When this method is called from onShortcutChangedInner() in LauncherApps, - // we're on the handler thread. Do not try to wait on tasks. Not waiting for pending - // tasks on this specific case should be fine. - if (Thread.currentThread() != mHandler.getLooper().getThread()) { - mPendingTasks.waitOnAllTasks(); - } - final ArrayList<ShortcutInfo> ret = new ArrayList<>(); final boolean cloneKeyFieldOnly = ((queryFlags & ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) != 0); @@ -2199,8 +2133,6 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkStringNotEmpty(packageName, "packageName"); Preconditions.checkStringNotEmpty(shortcutId, "shortcutId"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { getLauncherShortcutsLocked(callingPackage, userId, launcherUserId) .attemptToRestoreIfNeededAndSave(); @@ -2238,8 +2170,6 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkStringNotEmpty(packageName, "packageName"); Preconditions.checkNotNull(shortcutIds, "shortcutIds"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { final ShortcutLauncher launcher = getLauncherShortcutsLocked(callingPackage, userId, launcherUserId); @@ -2260,8 +2190,6 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty"); Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { getLauncherShortcutsLocked(callingPackage, userId, launcherUserId) .attemptToRestoreIfNeededAndSave(); @@ -2292,8 +2220,6 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkNotNull(packageName, "packageName"); Preconditions.checkNotNull(shortcutId, "shortcutId"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { getLauncherShortcutsLocked(callingPackage, userId, launcherUserId) .attemptToRestoreIfNeededAndSave(); @@ -2318,8 +2244,6 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkNotNull(packageName, "packageName"); Preconditions.checkNotNull(shortcutId, "shortcutId"); - mPendingTasks.waitOnAllTasks(); - synchronized (mLock) { getLauncherShortcutsLocked(callingPackage, userId, launcherUserId) .attemptToRestoreIfNeededAndSave(); @@ -2380,17 +2304,8 @@ public class ShortcutService extends IShortcutService.Stub { if (DEBUG) { Slog.d(TAG, "onSystemLocaleChangedNoLock: " + mLocaleChangeSequenceNumber.get()); } - mPendingTasks.addTask(() -> handleLocaleChanged()); - } - } - - @Override - public void onPackageBroadcast(Intent intent) { - if (DEBUG) { - Slog.d(TAG, "onPackageBroadcast"); + injectPostToHandler(() -> handleLocaleChanged()); } - mPendingTasks.addTask(() -> ShortcutService.this.onPackageBroadcast( - new Intent(intent))); } } @@ -2408,49 +2323,58 @@ public class ShortcutService extends IShortcutService.Stub { } } - private void onPackageBroadcast(Intent intent) { - final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId == UserHandle.USER_NULL) { - Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent); - return; - } + /** + * Package event callbacks. + */ + @VisibleForTesting + final PackageMonitor mPackageMonitor = new PackageMonitor() { - final String action = intent.getAction(); + private boolean isUserUnlocked() { + return mUserManager.isUserUnlocked(getChangingUserId()); + } - if (!mUserManager.isUserUnlocked(userId)) { - if (DEBUG) { - Slog.d(TAG, "Ignoring package broadcast " + action + " for locked/stopped user " - + userId); + @Override + public void onReceive(Context context, Intent intent) { + // clearCallingIdentity is not needed normally, but need to do it for the unit test. + final long token = injectClearCallingIdentity(); + try { + super.onReceive(context, intent); + } finally { + injectRestoreCallingIdentity(token); } - return; } - final Uri intentUri = intent.getData(); - final String packageName = (intentUri != null) ? intentUri.getSchemeSpecificPart() : null; - if (packageName == null) { - Slog.w(TAG, "Intent broadcast does not contain package name: " + intent); - return; + @Override + public void onPackageAdded(String packageName, int uid) { + if (!isUserUnlocked()) return; + handlePackageAdded(packageName, getChangingUserId()); } - final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); + @Override + public void onPackageUpdateFinished(String packageName, int uid) { + if (!isUserUnlocked()) return; + handlePackageUpdateFinished(packageName, getChangingUserId()); + } - if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { - if (replacing) { - handlePackageUpdateFinished(packageName, userId); - } else { - handlePackageAdded(packageName, userId); - } - } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { - if (!replacing) { - handlePackageRemoved(packageName, userId); - } - } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { - handlePackageChanged(packageName, userId); + @Override + public void onPackageRemoved(String packageName, int uid) { + if (!isUserUnlocked()) return; + handlePackageRemoved(packageName, getChangingUserId()); + } - } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) { - handlePackageDataCleared(packageName, userId); + @Override + public void onPackageDataCleared(String packageName, int uid) { + if (!isUserUnlocked()) return; + handlePackageDataCleared(packageName, getChangingUserId()); } - } + + @Override + public boolean onPackageChanged(String packageName, int uid, String[] components) { + if (!isUserUnlocked()) return false; + handlePackageChanged(packageName, getChangingUserId()); + return false; // We don't need to receive onSomePackagesChanged(), so just false. + } + }; /** * Called when a user is unlocked. @@ -3097,9 +3021,6 @@ public class ShortcutService extends IShortcutService.Stub { pw.println(Log.getStackTraceString(mLastWtfStacktrace)); } - pw.println(); - mPendingTasks.dump(pw, " "); - for (int i = 0; i < mUsers.size(); i++) { pw.println(); mUsers.valueAt(i).dump(pw, " "); @@ -3148,8 +3069,6 @@ public class ShortcutService extends IShortcutService.Stub { enforceShell(); - mPendingTasks.waitOnAllTasks(); - final int status = (new MyShellCommand()).exec(this, in, out, err, args, resultReceiver); resultReceiver.send(status, null); @@ -3176,6 +3095,10 @@ public class ShortcutService extends IShortcutService.Stub { case "--user": if (takeUser) { mUserId = UserHandle.parseUserArg(getNextArgRequired()); + if (!mUserManager.isUserUnlocked(mUserId)) { + throw new CommandException( + "User " + mUserId + " is not running or locked"); + } break; } // fallthrough @@ -3501,7 +3424,6 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting ShortcutPackage getPackageShortcutForTest(String packageName, int userId) { - mPendingTasks.waitOnAllTasks(); synchronized (mLock) { final ShortcutUser user = mUsers.get(userId); if (user == null) return null; @@ -3512,12 +3434,8 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting ShortcutInfo getPackageShortcutForTest(String packageName, String shortcutId, int userId) { - mPendingTasks.waitOnAllTasks(); synchronized (mLock) { - final ShortcutUser user = mUsers.get(userId); - if (user == null) return null; - - final ShortcutPackage pkg = user.getAllPackagesForTest().get(packageName); + final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId); if (pkg == null) return null; return pkg.findShortcutById(shortcutId); @@ -3552,12 +3470,4 @@ public class ShortcutService extends IShortcutService.Stub { forEachLoadedUserLocked(u -> u.forAllPackageItems(ShortcutPackageItem::verifyStates)); } } - - ShortcutPendingTasks getPendingTasksForTest() { - return mPendingTasks; - } - - Object getLockForTest() { - return mLock; - } } diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java index 2e32fe381722..c764833e08a6 100644 --- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java +++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java @@ -134,7 +134,7 @@ public class ImmersiveModeConfirmation { } public void immersiveModeChangedLw(String pkg, boolean isImmersiveMode, - boolean userSetupComplete) { + boolean userSetupComplete, boolean navBarEmpty) { mHandler.removeMessages(H.SHOW); if (isImmersiveMode) { final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg); @@ -144,6 +144,7 @@ public class ImmersiveModeConfirmation { && (DEBUG_SHOW_EVERY_TIME || !mConfirmed) && userSetupComplete && !mVrModeEnabled + && !navBarEmpty && !UserManager.isDeviceInDemoMode(mContext)) { mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs); } @@ -152,12 +153,13 @@ public class ImmersiveModeConfirmation { } } - public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) { + public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode, + boolean navBarEmpty) { if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) { // turning the screen back on within the panic threshold return mClingWindow == null; } - if (isScreenOn && inImmersiveMode) { + if (isScreenOn && inImmersiveMode && !navBarEmpty) { // turning the screen off, remember if we were in immersive mode mPanicTime = time; } else { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 3f71ba4cf671..fbc727d348a3 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1024,7 +1024,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Detect user pressing the power button in panic when an application has // taken over the whole screen. boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive, - SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags)); + SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags), + isNavBarEmpty(mLastSystemUiFlags)); if (panic) { mHandler.post(mHiddenNavPanic); } @@ -7590,7 +7591,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (win != null && oldImmersiveMode != newImmersiveMode) { final String pkg = win.getOwningPackage(); mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, - isUserSetupComplete()); + isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility())); } vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); @@ -7649,6 +7650,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { && canHideNavigationBar(); } + private static boolean isNavBarEmpty(int systemUiFlags) { + final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME + | View.STATUS_BAR_DISABLE_BACK + | View.STATUS_BAR_DISABLE_RECENT); + + return (systemUiFlags & disableNavigationBar) == disableNavigationBar; + } + /** * @return whether the navigation or status bar can be made translucent * diff --git a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java index 77e8b1fa541f..40ee5d88fc8a 100644 --- a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java +++ b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java @@ -246,7 +246,9 @@ public class EnabledComponentsObserver implements SettingChangeListener { Intent queryIntent = new Intent(serviceName); List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser( queryIntent, - PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, + PackageManager.GET_SERVICES | PackageManager.GET_META_DATA | + PackageManager.MATCH_DIRECT_BOOT_AWARE | + PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); if (installedServices != null) { for (int i = 0, count = installedServices.size(); i < count; i++) { diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 2b581562d680..3aefc08746bc 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -604,7 +604,7 @@ public class AppTransition implements Dump { float scaleH = mTmpRect.height() / (float) appHeight; Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, computePivot(mTmpRect.left, scaleW), - computePivot(mTmpRect.right, scaleH)); + computePivot(mTmpRect.top, scaleH)); scale.setInterpolator(mDecelerateInterpolator); Animation alpha = new AlphaAnimation(0, 1); @@ -1615,8 +1615,7 @@ public class AppTransition implements Dump { if (isTransitionSet()) { clear(); mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP; - putDefaultNextAppTransitionCoordinates(startX, startY, startX + startWidth, - startY + startHeight, null); + putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null); postAnimationCallback(); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 31b756e57037..2120be1ec531 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -218,6 +218,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String ATTR_SETUP_COMPLETE = "setup-complete"; private static final String ATTR_PROVISIONING_STATE = "provisioning-state"; private static final String ATTR_PERMISSION_POLICY = "permission-policy"; + private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED = + "device-provisioning-config-applied"; private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer"; private static final String ATTR_APPLICATION_RESTRICTIONS_MANAGER @@ -417,6 +419,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int mUserProvisioningState; int mPermissionPolicy; + boolean mDeviceProvisioningConfigApplied = false; + final ArrayMap<ComponentName, ActiveAdmin> mAdminMap = new ArrayMap<>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); @@ -2173,6 +2177,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.attribute(null, ATTR_SETUP_COMPLETE, Boolean.toString(true)); } + if (policy.mDeviceProvisioningConfigApplied) { + out.attribute(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED, + Boolean.toString(true)); + } if (policy.mUserProvisioningState != DevicePolicyManager.STATE_USER_UNMANAGED) { out.attribute(null, ATTR_PROVISIONING_STATE, Integer.toString(policy.mUserProvisioningState)); @@ -2333,6 +2341,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) { policy.mUserSetupComplete = true; } + String deviceProvisioningConfigApplied = parser.getAttributeValue(null, + ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED); + if (deviceProvisioningConfigApplied != null + && Boolean.toString(true).equals(deviceProvisioningConfigApplied)) { + policy.mDeviceProvisioningConfigApplied = true; + } String provisioningState = parser.getAttributeValue(null, ATTR_PROVISIONING_STATE); if (!TextUtils.isEmpty(provisioningState)) { policy.mUserProvisioningState = Integer.parseInt(provisioningState); @@ -9046,4 +9060,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // restrictions. pushUserRestrictions(userHandle); } + + @Override + public void setDeviceProvisioningConfigApplied() { + enforceManageUsers(); + synchronized (this) { + DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); + policy.mDeviceProvisioningConfigApplied = true; + saveSettingsLocked(UserHandle.USER_SYSTEM); + } + } + + @Override + public boolean isDeviceProvisioningConfigApplied() { + enforceManageUsers(); + synchronized (this) { + final DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); + return policy.mDeviceProvisioningConfigApplied; + } + } } diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java index 855a2b6d9253..c351e738a04f 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java @@ -321,13 +321,15 @@ public class RetailDemoModeService extends SystemService { private void setupDemoUser(UserInfo userInfo) { UserManager um = getUserManager(); UserHandle user = UserHandle.of(userInfo.id); - LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext()); - lockPatternUtils.setLockScreenDisabled(true, userInfo.id); um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user); um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user); um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user); um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user); um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user); + um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user); + // Disallow rebooting in safe mode - controlled by user 0 + getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, + UserHandle.SYSTEM); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id); Settings.Secure.putIntForUser(getContext().getContentResolver(), @@ -496,6 +498,9 @@ public class RetailDemoModeService extends SystemService { mAmi.updatePersistentConfigurationForUser(getSystemUsersConfiguration(), userId); turnOffAllFlashLights(); muteVolumeStreams(); + // Disable lock screen for demo users. + LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext()); + lockPatternUtils.setLockScreenDisabled(true, userId); mNm.notifyAsUser(TAG, 1, createResetNotification(), UserHandle.of(userId)); synchronized (mActivityLock) { diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 01c19d0ca12b..1be57bccbdb7 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -404,11 +404,6 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { // During tests, WTF is fatal. fail(message + " exception: " + th + "\n" + Log.getStackTraceString(th)); } - - @Override - boolean injectCheckPendingTaskWaitThread() { - return true; - } } /** ShortcutManager with injection override methods. */ @@ -853,8 +848,6 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected void shutdownServices() { if (mService != null) { - mService.getPendingTasksForTest().waitOnAllTasks(); - // Flush all the unsaved data from the previous instance. mService.saveDirtyInfo(); diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index c7673d17424d..bf6c2ff97bec 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -62,7 +62,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.Manifest.permission; import android.app.ActivityManager; @@ -1298,7 +1297,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_3); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast(genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); + mService.mPackageMonitor.onReceive(getTestContext(), + genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertTrue(mManager.setDynamicShortcuts(list( @@ -1316,7 +1316,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast(genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); + mService.mPackageMonitor.onReceive(getTestContext(), + genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertTrue(mManager.setDynamicShortcuts(list( @@ -2814,7 +2815,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0) .areAllManifest() @@ -2851,7 +2852,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_0); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertForLauncherCallback(mLauncherApps, () -> { @@ -3471,7 +3472,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -3488,7 +3489,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -3850,7 +3851,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(getCallerShortcuts()) @@ -3890,7 +3891,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10)); uninstallPackage(USER_0, CALLING_PACKAGE_1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0)); @@ -3910,7 +3911,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mRunningUsers.put(USER_10, true); uninstallPackage(USER_10, CALLING_PACKAGE_2); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0)); @@ -4001,7 +4002,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10)); assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10)); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageDataClear(CALLING_PACKAGE_1, USER_0)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0)); @@ -4020,7 +4021,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mRunningUsers.put(USER_10, true); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageDataClear(CALLING_PACKAGE_2, USER_10)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0)); @@ -4047,7 +4048,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4068,7 +4069,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Clear data - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageDataClear(CALLING_PACKAGE_1, USER_10)); // Only manifest shortcuts will remain, and are no longer pinned. @@ -4133,9 +4134,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { reset(c0); reset(c10); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0)); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10)); waitOnMainThread(); @@ -4156,7 +4157,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { updatePackageVersion(CALLING_PACKAGE_1, 1); // Then send the broadcast, to only user-0. - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0)); waitOnMainThread(); @@ -4221,7 +4222,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { updatePackageVersion(CALLING_PACKAGE_2, 10); // Then send the broadcast, to only user-0. - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0)); mService.handleUnlockUser(USER_10); @@ -4245,7 +4246,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { updatePackageVersion(CALLING_PACKAGE_3, 100); // Then send the broadcast, to only user-0. - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0)); mService.handleUnlockUser(USER_10); @@ -4327,7 +4328,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Update the package. updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -4356,7 +4357,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mRunningUsers.put(USER_10, true); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4388,7 +4389,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // First, no changes. - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageChangedIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4411,7 +4412,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Disable activity 1 mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageChangedIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4431,7 +4432,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Re-enable activity 1. // Manifest shortcuts will be re-published, but dynamic ones are not. mEnabledActivityChecker = (activity, userId) -> true; - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageChangedIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4455,7 +4456,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Disable activity 2 // Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled. mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageChangedIntent(CALLING_PACKAGE_1, USER_10)); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -4518,7 +4519,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { setCaller(LAUNCHER_1, USER_0); assertForLauncherCallback(mLauncherApps, () -> { updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0)); }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0) // Make sure the launcher gets callbacks. @@ -5160,7 +5161,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(mServiceContext, genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Pin from launcher 1. @@ -5173,7 +5174,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(mServiceContext, genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Make sure the manifest shortcuts have been published. @@ -5634,7 +5635,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5655,7 +5656,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_2, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5692,7 +5693,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5729,7 +5730,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mRunningUsers.put(USER_10, false); mUnlockedUsers.put(USER_10, false); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_10)); runWithCaller(CALLING_PACKAGE_2, USER_10, () -> { assertEmpty(mManager.getManifestShortcuts()); @@ -5739,7 +5740,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Try again, but the user is locked, so still ignored. mRunningUsers.put(USER_10, true); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_10)); runWithCaller(CALLING_PACKAGE_2, USER_10, () -> { assertEmpty(mManager.getManifestShortcuts()); @@ -5750,7 +5751,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mUnlockedUsers.put(USER_10, true); // Send PACKAGE_ADD broadcast to have Package 2 on user-10 publish manifest shortcuts. - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_10)); runWithCaller(CALLING_PACKAGE_2, USER_10, () -> { @@ -5791,7 +5792,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { R.xml.shortcut_5_reverse); updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_0)); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { @@ -5819,7 +5820,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()), R.xml.shortcut_0); updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_2, USER_0)); // No manifest shortcuts, and pinned ones are disabled. @@ -5850,7 +5851,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_error_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -5865,7 +5866,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_error_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -5880,7 +5881,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_error_3); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -5896,7 +5897,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_error_4); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5924,7 +5925,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5962,7 +5963,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_error_4); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Make sure 3, 4 and 5 still exist but disabled. @@ -6010,7 +6011,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -6115,7 +6116,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6212,7 +6213,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -6231,7 +6232,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1_disable); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Because shortcut 1 wasn't pinned, it'll just go away. @@ -6252,7 +6253,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Only the valid one is published. @@ -6275,7 +6276,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1_disable); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); // Because shortcut 1 was pinned, it'll still exist as pinned, but disabled. @@ -6308,7 +6309,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2_duplicate); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6338,7 +6339,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6410,7 +6411,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6460,7 +6461,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(LAUNCHER_1, USER_0, () -> { @@ -6471,7 +6472,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6553,7 +6554,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_5); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -6623,7 +6624,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(2, mManager.getManifestShortcuts().size()); @@ -6749,7 +6750,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(2, mManager.getManifestShortcuts().size()); @@ -6898,7 +6899,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(1, mManager.getManifestShortcuts().size()); @@ -6918,7 +6919,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()), R.xml.shortcut_1_alt); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(3, mManager.getManifestShortcuts().size()); @@ -6938,7 +6939,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()), R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3. updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(5, mManager.getManifestShortcuts().size()); @@ -6957,7 +6958,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()), R.xml.shortcut_0); updatePackageVersion(CALLING_PACKAGE_1, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); assertEquals(0, mManager.getManifestShortcuts().size()); diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java index fcf7ea2dcfbb..eb4db7a0f4af 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java @@ -66,7 +66,7 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest { private void publishManifestShortcuts(ComponentName activity, int resId) { addManifestShortcutResource(activity, resId); updatePackageVersion(CALLING_PACKAGE, 1); - mInternal.onPackageBroadcast( + mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE, USER_0)); } diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java deleted file mode 100644 index bf1ed98983df..000000000000 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.server.pm; - -import android.os.Handler; -import android.os.Looper; -import android.test.MoreAsserts; -import android.test.suitebuilder.annotation.LargeTest; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Run with: - adb install \ - -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && - adb shell am instrument -e class com.android.server.pm.ShortcutPendingTasksTest \ - -w com.android.frameworks.servicestests - */ -@LargeTest -public class ShortcutPendingTasksTest extends BaseShortcutManagerTest { - public void testAll() { - final AtomicReference<Throwable> thrown = new AtomicReference<>(); - - final AtomicBoolean threadCheckerResult = new AtomicBoolean(true); - - final Handler handler = new Handler(Looper.getMainLooper()); - - final ShortcutPendingTasks tasks = new ShortcutPendingTasks( - handler::post, - threadCheckerResult::get, - thrown::set); - - // No pending tasks, shouldn't block. - assertTrue(tasks.waitOnAllTasks()); - - final AtomicInteger counter = new AtomicInteger(); - - // Run one task. - tasks.addTask(() -> { - try { - Thread.sleep(1000); - } catch (InterruptedException ignore) { - } - counter.incrementAndGet(); - }); - - assertTrue(tasks.waitOnAllTasks()); - assertNull(thrown.get()); - - assertEquals(1, counter.get()); - - // Run 3 tasks. - - // We use this ID to make sure only one task can run at the same time. - final AtomicInteger currentTaskId = new AtomicInteger(); - - tasks.addTask(() -> { - currentTaskId.set(1); - try { - Thread.sleep(500); - } catch (InterruptedException ignore) { - } - counter.incrementAndGet(); - assertEquals(1, currentTaskId.get()); - }); - tasks.addTask(() -> { - currentTaskId.set(2); - try { - Thread.sleep(500); - } catch (InterruptedException ignore) { - } - counter.incrementAndGet(); - assertEquals(2, currentTaskId.get()); - }); - tasks.addTask(() -> { - currentTaskId.set(3); - try { - Thread.sleep(500); - } catch (InterruptedException ignore) { - } - counter.incrementAndGet(); - assertEquals(3, currentTaskId.get()); - }); - - assertTrue(tasks.waitOnAllTasks()); - assertNull(thrown.get()); - assertEquals(4, counter.get()); - - // No tasks running, shouldn't block. - assertTrue(tasks.waitOnAllTasks()); - assertNull(thrown.get()); - assertEquals(4, counter.get()); - - // Now the thread checker returns false, so waitOnAllTasks() returns false. - threadCheckerResult.set(false); - assertFalse(tasks.waitOnAllTasks()); - - threadCheckerResult.set(true); - - // Make sure the exception handler is called. - tasks.addTask(() -> { - throw new RuntimeException("XXX"); - }); - assertTrue(tasks.waitOnAllTasks()); - assertNotNull(thrown.get()); - MoreAsserts.assertContainsRegex("XXX", thrown.get().getMessage()); - } -} diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 26ef0cbb87a5..df81d7f90008 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5538,5 +5538,22 @@ public class TelephonyManager { } return 0; } + + /** + * Policy control of data connection. Usually used when data limit is passed. + * @param enabled True if enabling the data, otherwise disabling. + * @param subId sub id + * @hide + */ + public void setPolicyDataEnabled(boolean enabled, int subId) { + try { + ITelephony service = getITelephony(); + if (service != null) { + service.setPolicyDataEnabled(enabled, subId); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#setPolicyDataEnabled", e); + } + } } diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 8166e00f31cf..f01e4c0a8c69 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -105,6 +105,7 @@ public class DctConstants { public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 43; public static final int EVENT_REDIRECTION_DETECTED = BASE + 44; public static final int EVENT_PCO_DATA_RECEIVED = BASE + 45; + public static final int EVENT_SET_CARRIER_DATA_ENABLED = BASE + 46; /***** Constants *****/ diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 2168b0ea80db..167e1a739ca5 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1158,4 +1158,12 @@ interface ITelephony { * @hide */ long getVtDataUsage(); + + /** + * Policy control of data connection. Usually used when data limit is passed. + * @param enabled True if enabling the data, otherwise disabling. + * @param subId Subscription index + * @hide + */ + void setPolicyDataEnabled(boolean enabled, int subId); } diff --git a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java index d32f0716fe98..88847eed17fa 100644 --- a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java +++ b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java @@ -23,19 +23,22 @@ import android.view.View; import android.widget.ArrayAdapter; public class ShadowGridActivity extends AppCompatActivity { + public static class NoDividerListFragment extends ListFragment { + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setDivider(null); + } + }; + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); if (fm.findFragmentById(android.R.id.content) == null) { - ListFragment listFragment = new ListFragment() { - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getListView().setDivider(null); - } - }; + ListFragment listFragment = new NoDividerListFragment(); listFragment.setListAdapter(new ArrayAdapter<>(this, R.layout.card_row, R.id.card_text, TextUtils.buildSimpleStringList())); |