Merge "Fixes delay when playing first sound in BootAnimation" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index d5f36bd..d3ee682 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19652,6 +19652,7 @@
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 16c75cc..13ad2d6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -21160,6 +21160,7 @@
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 7fdbb64..c6359dd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19722,6 +19722,7 @@
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 23fea71..af981f6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -93,7 +93,8 @@
@IntDef({
BUGREPORT_OPTION_FULL,
BUGREPORT_OPTION_INTERACTIVE,
- BUGREPORT_OPTION_REMOTE
+ BUGREPORT_OPTION_REMOTE,
+ BUGREPORT_OPTION_WEAR
})
public @interface BugreportMode {}
/**
@@ -114,6 +115,11 @@
* @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 8692336..9fa8a5d 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -345,7 +345,7 @@
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 @@
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 fa943f2..2e37db2 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3519,6 +3519,8 @@
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 @@
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 @@
- 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 @@
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 @@
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 dc33671..2a12ac8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1315,7 +1315,7 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index de52f73..3f8bad1 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -73,11 +73,4 @@
* 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 92134ee..1e44a5c 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -49,6 +49,10 @@
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 @@
private final Resources mResources;
private final DisplayMetrics mMetrics;
- private final AssetManager mAssets;
+ private AssetManager mAssets;
private boolean mRecycled;
@@ -1086,6 +1090,7 @@
// 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 43e596f..fcbc962 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 80927f3..8d6d9ed 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -286,6 +286,11 @@
}
/** {@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 1158776..d587ba8 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -235,7 +235,6 @@
* @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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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/view/View.java b/core/java/android/view/View.java
index a64827a..e648114 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4215,25 +4215,25 @@
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 c427522..209886b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1731,7 +1731,7 @@
}
boolean hwInitialized = false;
- boolean framesChanged = false;
+ boolean contentInsetsChanged = false;
boolean hadSurface = mSurface.isValid();
try {
@@ -1771,7 +1771,7 @@
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 @@
+ 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 @@
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 @@
+ 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 @@
}
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 48bcc09..77452ca 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -341,6 +341,20 @@
}
/**
+ * 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 @@
* 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 @@
* 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 @@
: (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 9dd118c..073aac5 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 @@
* 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 @@
@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 @@
@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 @@
}
@Override
- public LayoutParams generateLayoutParams(AttributeSet attrs) {
- return new MarginLayoutParams(getContext(), attrs);
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mDefaultPaddingEnd = getPaddingEnd();
+ mDefaultBackground = getBackground();
}
- @Override
- protected LayoutParams generateDefaultLayoutParams() {
- return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
- }
-
- @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 a56eba6..46f76de 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 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 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 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 @@
jmethodID contextHubServiceMsgReceiptCallback;
jmethodID contextHubServiceAddAppInstance;
+ jmethodID contextHubServiceDeleteAppInstance;
};
struct context_hub_info_s {
@@ -93,10 +100,53 @@
};
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 @@
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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- send_query_for_apps();
+ sendQueryForApps(ALL_APPS);
} else {
ALOGW("No Context Hub Module present");
}
@@ -346,7 +532,8 @@
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 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));
+
+ if (!additionalData) {
+ additionalDataLen = 0; // clamp
+ }
+ int msgLen = 1 + additionalDataLen;
+
+ int8_t *msg = new int8_t[msgLen];
+
+ 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);
+ }
+ }
+}
+
+static int handle_os_message(uint32_t msgType, uint32_t hubHandle,
+ const uint8_t *msg, int msgLen) {
+ int retVal = -1;
+
+ ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d",
+ hubHandle, msgType, msgLen);
+
+ struct status_response_t rsp;
switch(msgType) {
- case CONTEXT_HUB_APPS_ENABLE:
- retVal = 0;
- break;
- case CONTEXT_HUB_APPS_DISABLE:
- retVal = 0;
- break;
+ 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_LOAD_APP:
- 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_UNLOAD_APP:
- retVal = 0;
- break;
+ case CONTEXT_HUB_QUERY_MEMORY:
+ // Deferring this use
+ retVal = 0;
+ break;
- case CONTEXT_HUB_QUERY_APPS:
- retVal = handle_query_apps_response(msg, msgLen, hubHandle);
- 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;
- case CONTEXT_HUB_QUERY_MEMORY:
- retVal = 0;
- break;
-
- default:
- retVal = -1;
- break;
-
+ default:
+ retVal = -1;
+ break;
}
return retVal;
@@ -420,10 +755,12 @@
}
}
+
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 @@
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 @@
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 @@
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 @@
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 @@
env->DeleteLocalRef(jmemBuf);
+ delete[] connectedSensors;
return jHub;
}
@@ -622,33 +971,96 @@
jbyte *data = env->GetByteArrayElements(data_, 0);
int dataBufferLength = env->GetArrayLength(data_);
+ if (numHeaderElements < MSG_HEADER_SIZE) {
+ ALOGW("Malformed header len");
+ return -1;
+ }
- if (numHeaderElements >= MSG_HEADER_SIZE) {
- bool setAddressSuccess;
- int hubId;
- hub_message_t msg;
+ 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 (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 0000000..b7153ba
--- /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 0000000..992e43e
--- /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 91eee7d..45eb981 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 e87bb81..674a0d7 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 f0cfd2b..473796a 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 6b064c1..3590ac8 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 d4732f8..48aca28 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -1193,3 +1193,5 @@
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 9c2e8e9..76e9f5a 100644
--- a/docs/html/distribute/stories/apps.jd
+++ b/docs/html/distribute/stories/apps.jd
@@ -29,5 +29,5 @@
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 0000000..f1f388e
--- /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 0000000..2ee813d
--- /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 0000000..4cbf817
--- /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 0000000..1292139
--- /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 0000000..02222d3
--- /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
new file mode 100644
index 0000000..60cb851
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/aftenposten.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/el-mundo.png b/docs/html/images/cards/distribute/stories/el-mundo.png
new file mode 100644
index 0000000..23db783
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/el-mundo.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/segundamano.png b/docs/html/images/cards/distribute/stories/segundamano.png
new file mode 100644
index 0000000..60e873c
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/segundamano.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/tapps.png b/docs/html/images/cards/distribute/stories/tapps.png
new file mode 100644
index 0000000..e01e3ad
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/tapps.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/witch-puzzle.png b/docs/html/images/cards/distribute/stories/witch-puzzle.png
new file mode 100644
index 0000000..c336f1b
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/witch-puzzle.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/aftenposten-icon.png b/docs/html/images/distribute/stories/aftenposten-icon.png
new file mode 100644
index 0000000..60cb851
--- /dev/null
+++ b/docs/html/images/distribute/stories/aftenposten-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/el-mundo-icon.png b/docs/html/images/distribute/stories/el-mundo-icon.png
new file mode 100644
index 0000000..23db783
--- /dev/null
+++ b/docs/html/images/distribute/stories/el-mundo-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/japanese-witch-puzzle.png b/docs/html/images/distribute/stories/japanese-witch-puzzle.png
new file mode 100644
index 0000000..6a7ef13
--- /dev/null
+++ b/docs/html/images/distribute/stories/japanese-witch-puzzle.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/segundamano-icon.png b/docs/html/images/distribute/stories/segundamano-icon.png
new file mode 100644
index 0000000..60e873c
--- /dev/null
+++ b/docs/html/images/distribute/stories/segundamano-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-candy-hills.png b/docs/html/images/distribute/stories/tapps-candy-hills.png
new file mode 100644
index 0000000..14dcb94
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-candy-hills.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-1.png b/docs/html/images/distribute/stories/tapps-icon-orig-1.png
new file mode 100644
index 0000000..44af423
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-2.png b/docs/html/images/distribute/stories/tapps-icon-orig-2.png
new file mode 100644
index 0000000..1b36255
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-3.png b/docs/html/images/distribute/stories/tapps-icon-orig-3.png
new file mode 100644
index 0000000..2f393f8
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-3.png
Binary files differ
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
new file mode 100644
index 0000000..fecab6e
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-1-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-1.png b/docs/html/images/distribute/stories/tapps-icon-var-1.png
new file mode 100644
index 0000000..77bd02a
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-1.png
Binary files differ
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
new file mode 100644
index 0000000..84166c4
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-2-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-2.png b/docs/html/images/distribute/stories/tapps-icon-var-2.png
new file mode 100644
index 0000000..939c2fd
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-2.png
Binary files differ
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
new file mode 100644
index 0000000..4aa782d
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-3-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-3.png b/docs/html/images/distribute/stories/tapps-icon-var-3.png
new file mode 100644
index 0000000..1e44fdf
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-logic-pic.png b/docs/html/images/distribute/stories/tapps-logic-pic.png
new file mode 100644
index 0000000..5029f79
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-logic-pic.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-logo.png b/docs/html/images/distribute/stories/tapps-logo.png
new file mode 100644
index 0000000..e01e3ad
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-logo.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-1.png b/docs/html/images/distribute/stories/tapps-screen-orig-1.png
new file mode 100644
index 0000000..d54e75c
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-2.png b/docs/html/images/distribute/stories/tapps-screen-orig-2.png
new file mode 100644
index 0000000..a2d18e3
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-3.png b/docs/html/images/distribute/stories/tapps-screen-orig-3.png
new file mode 100644
index 0000000..e01fe20
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-1.png b/docs/html/images/distribute/stories/tapps-screen-var-1.png
new file mode 100644
index 0000000..b930350
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-2.png b/docs/html/images/distribute/stories/tapps-screen-var-2.png
new file mode 100644
index 0000000..9ccb8a6
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-3.png b/docs/html/images/distribute/stories/tapps-screen-var-3.png
new file mode 100644
index 0000000..8eb58e1
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-villains-corp.png b/docs/html/images/distribute/stories/tapps-villains-corp.png
new file mode 100644
index 0000000..6e037da
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-villains-corp.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/witch-puzzle-icon.png b/docs/html/images/distribute/stories/witch-puzzle-icon.png
new file mode 100644
index 0000000..c336f1b
--- /dev/null
+++ b/docs/html/images/distribute/stories/witch-puzzle-icon.png
Binary files differ
diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd
index 3e95f3e..ff11e8e 100644
--- a/docs/html/preview/setup-sdk.jd
+++ b/docs/html/preview/setup-sdk.jd
@@ -77,32 +77,10 @@
<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 08c610f..e08db15 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 c9ce1d5..84d5fab 100644
--- a/docs/html/topic/performance/launch-time.jd
+++ b/docs/html/topic/performance/launch-time.jd
@@ -112,7 +112,7 @@
</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 @@
</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 49021bc..f9274e1 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.h
+++ b/libs/hwui/PropertyValuesAnimatorSet.h
@@ -60,7 +60,7 @@
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 @@
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 7d5939c..81cc93d 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -264,7 +264,6 @@
*/
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 8d4a151..31c7a32 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -3498,7 +3498,7 @@
* @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 0f7dc9a..b262d97 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -181,10 +181,15 @@
* @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 5ede1d5..9fafda4 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -505,27 +505,31 @@
}
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 b59afba..0114103 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 47e616e..9464c67 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 28e9a45..1928f92 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 @@
// 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 @@
// 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 @@
* @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 @@
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 @@
}
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 @@
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 0000000..778ccbc
--- /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 0000000..aaca663
--- /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/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
index 1f24ab0..8abfcf6 100644
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ b/packages/SystemUI/res/layout/battery_detail.xml
@@ -25,7 +25,7 @@
android:id="@+id/charge_and_estimation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="72dp"
+ android:paddingStart="16dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/colorAccent" />
diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index c062b6d..f6ca862 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -22,19 +22,9 @@
android:background="@drawable/btn_borderless_rect"
android:gravity="center">
- <ImageView
- android:id="@*android:id/up"
- android:layout_width="56dp"
- android:layout_height="56dp"
- android:layout_marginEnd="16dp"
- android:padding="16dp"
- android:clickable="true"
- android:background="?android:attr/selectableItemBackground"
- android:contentDescription="@*android:string/action_bar_up_description"
- android:src="?android:attr/homeAsUpIndicator" />
-
<TextView
android:id="@android:id/title"
+ android:paddingStart="16dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
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 3b8b909..6673d6e 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 e1cbbc5..ae4f3cf 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 3ed0711..5324968 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 af2a286..9eceeac 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 @@
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/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index a40e5b7..c63be9c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -63,7 +63,6 @@
private boolean mScanState;
private boolean mClosingDetail;
private boolean mFullyExpanded;
- private View mQsDetailHeaderBack;
private BaseStatusBarHeader mHeader;
private boolean mTriggeredExpand;
private int mOpenX;
@@ -92,7 +91,6 @@
mDetailDoneButton = (TextView) findViewById(android.R.id.button1);
mQsDetailHeader = findViewById(R.id.qs_detail_header);
- mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
@@ -109,7 +107,6 @@
mQsPanel.closeDetail();
}
};
- mQsDetailHeaderBack.setOnClickListener(doneListener);
mDetailDoneButton.setOnClickListener(doneListener);
}
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 0000000..9a3549e
--- /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 b53a999..63f726b 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 @@
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 @@
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 67699737..06c8b68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -280,7 +280,7 @@
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());
@@ -327,16 +327,16 @@
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/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9bc5426..fb7afc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -883,9 +883,9 @@
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();
}
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 ca7f905..15e235d 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.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 @@
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 85303f4..21db64f 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.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 @@
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 @@
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 @@
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 @@
@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 @@
protected void updateVisibilities() {
updateAlarmVisibilities();
+ updateDateTimePosition();
mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
? View.VISIBLE : View.INVISIBLE);
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
@@ -274,6 +272,11 @@
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 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/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d8b1a62..3df7590 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 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 7de3879..e00674a 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 @@
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 @@
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/tuner/TunerZenModePanel.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
index cc0ffb0..1ea23bb 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
@@ -54,7 +54,6 @@
mHeaderSwitch = findViewById(R.id.tuner_zen_switch);
mHeaderSwitch.setVisibility(View.VISIBLE);
mHeaderSwitch.setOnClickListener(this);
- mHeaderSwitch.findViewById(com.android.internal.R.id.up).setVisibility(View.GONE);
((TextView) mHeaderSwitch.findViewById(android.R.id.title)).setText(
R.string.quick_settings_dnd_label);
mZenModePanel = (ZenModePanel) findViewById(R.id.zen_mode_panel);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 45e3e7e..ba59c2f0 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -33,73 +33,61 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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 4762a67..1f0dbfe 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 @@
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 03843d1..5807502 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 @@
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 @@
// 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);
+ // 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);
+ 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);
+ 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 @@
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 @@
}
}
- // 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 92b55db..12310e3 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 @@
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 @@
*/
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 @@
* 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 @@
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);
-
- if (mCurrentUpstreamIface != null) {
- for (String ifname : networkState.linkProperties.getAllInterfaceNames()) {
- if (mCurrentUpstreamIface.equals(ifname)) {
- return true;
+ 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);
+ }
+
+ // 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;
+ }
+ }
+ }
+
+ // 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;
}
-
- void processNetworkLost(Network network) {
- if (network != null) {
- mNetworkMap.remove(network);
- }
- }
+ return false;
}
class TetherMasterSM extends StateMachine {
@@ -1120,8 +1213,7 @@
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 @@
}
protected void chooseUpstreamType(boolean tryCell) {
+ final ConnectivityManager cm = getConnectivityManager();
int upType = ConnectivityManager.TYPE_NONE;
String iface = null;
@@ -1292,8 +1385,7 @@
}
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 @@
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 @@
}
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 @@
}
}
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 @@
ifaceName);
}
}
+
+ protected void handleNewUpstreamNetworkState(NetworkState ns) {
+ mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
+ }
}
private final AtomicInteger mSimBcastGenerationNumber = new AtomicInteger(0);
@@ -1582,24 +1685,55 @@
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 f15fdd5..b22a084 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 @@
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/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 098b39e..1cff926 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.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 @@
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 @@
grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CAMERA_PERMISSIONS, userId);
}
}
@@ -656,6 +667,7 @@
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 01b3dc2..02c6472 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 @@
// 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 a3cf9c8..6a56fa6 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 @@
*/
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 @@
// keep details around for dumpsys.
mHistoricalSessions.put(session.sessionId, session);
}
+ mAllocatedSessions.put(session.sessionId, true);
}
}
}
@@ -768,8 +773,8 @@
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 1ca6148..78fa3a3 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.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.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 @@
}
}
- int[] stats = performDexOpt(coreApps, false,
+ int[] stats = performDexOptUpgrade(coreApps, false,
getCompilerFilterForReason(REASON_CORE_APP));
final int elapsedTimeSeconds =
@@ -7325,7 +7325,7 @@
}
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 @@
* 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 @@
}
}
+ // 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 @@
} 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 @@
+ 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 a5ace56..0000000
--- 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 a9018b3..5f8cbbf 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.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 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 @@
/**
* 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 @@
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 @@
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 @@
@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 @@
@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 @@
@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 @@
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
@@ -1728,8 +1696,6 @@
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
@@ -1750,8 +1716,6 @@
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 void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts();
}
@@ -1788,9 +1750,6 @@
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 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 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 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 long getRateLimitResetTime(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
return getNextResetTimeLocked();
}
@@ -1880,8 +1829,6 @@
public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
verifyCaller(packageName, userId);
- mPendingTasks.waitOnAllTasks();
-
Preconditions.checkNotNull(shortcutId);
if (DEBUG) {
@@ -1914,8 +1861,6 @@
public void resetThrottling() {
enforceSystemOrShell();
- mPendingTasks.waitOnAllTasks();
-
resetThrottlingInner(getCallingUserId());
}
@@ -1948,9 +1893,6 @@
if (DEBUG) {
Slog.d(TAG, "onApplicationActive: package=" + packageName + " userid=" + userId);
}
-
- mPendingTasks.waitOnAllTasks();
-
enforceResetThrottlingPermission();
resetPackageThrottling(packageName, userId);
}
@@ -2113,14 +2055,6 @@
@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 @@
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2238,8 +2170,6 @@
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkNotNull(shortcutIds, "shortcutIds");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
final ShortcutLauncher launcher =
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
@@ -2260,8 +2190,6 @@
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 @@
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2318,8 +2244,6 @@
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- mPendingTasks.waitOnAllTasks();
-
synchronized (mLock) {
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2380,18 +2304,9 @@
if (DEBUG) {
Slog.d(TAG, "onSystemLocaleChangedNoLock: " + mLocaleChangeSequenceNumber.get());
}
- mPendingTasks.addTask(() -> handleLocaleChanged());
+ injectPostToHandler(() -> handleLocaleChanged());
}
}
-
- @Override
- public void onPackageBroadcast(Intent intent) {
- if (DEBUG) {
- Slog.d(TAG, "onPackageBroadcast");
- }
- mPendingTasks.addTask(() -> ShortcutService.this.onPackageBroadcast(
- new Intent(intent)));
- }
}
void handleLocaleChanged() {
@@ -2408,49 +2323,58 @@
}
}
- 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() {
+
+ private boolean isUserUnlocked() {
+ return mUserManager.isUserUnlocked(getChangingUserId());
}
- final String action = intent.getAction();
-
- 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);
-
- 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);
-
- } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
- handlePackageDataCleared(packageName, userId);
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ if (!isUserUnlocked()) return;
+ handlePackageUpdateFinished(packageName, getChangingUserId());
}
- }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ if (!isUserUnlocked()) return;
+ handlePackageRemoved(packageName, getChangingUserId());
+ }
+
+ @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 @@
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 @@
enforceShell();
- mPendingTasks.waitOnAllTasks();
-
final int status = (new MyShellCommand()).exec(this, in, out, err, args, resultReceiver);
resultReceiver.send(status, null);
@@ -3176,6 +3095,10 @@
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 @@
@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 @@
@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 @@
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 2e32fe3..c764833 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 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 @@
&& (DEBUG_SHOW_EVERY_TIME || !mConfirmed)
&& userSetupComplete
&& !mVrModeEnabled
+ && !navBarEmpty
&& !UserManager.isDeviceInDemoMode(mContext)) {
mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
}
@@ -152,12 +153,13 @@
}
}
- 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 3f71ba4..fbc727d 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 @@
// 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 @@
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 @@
&& 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 77e8b1f..40ee5d8 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 @@
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 2b58156..3aefc08 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 @@
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 @@
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/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index 855a2b6..c351e73 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 @@
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 @@
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 01c19d0..1be57bc 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 @@
// 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 @@
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 c7673d1..bf6c2ff 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
});
// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
});
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 fcf7ea2..eb4db7a 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 @@
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 bf1ed98..0000000
--- 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 26ef0cb..df81d7f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5538,5 +5538,22 @@
}
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 8166e00..f01e4c0 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -105,6 +105,7 @@
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 2168b0e..167e1a7 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1158,4 +1158,12 @@
* @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 d32f071..88847ee 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.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()));