Merge "Ensure only test print services enabled - framework" into oc-dev
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index c99a1e4..266fa7e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -18,7 +18,6 @@
import android.os.PooledStringWriter;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.service.autofill.FillContext;
import android.service.autofill.FillRequest;
import android.text.TextUtils;
import android.util.Log;
@@ -31,7 +30,6 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import java.util.ArrayList;
@@ -39,18 +37,18 @@
import java.util.List;
/**
- * Assist data automatically created by the platform's implementation of Assist and Autofill.
+ * Assist data automatically created by the platform's implementation of assist and autofill.
*
- * <p>The structure is used for Assist purposes when created by
+ * <p>The structure is used for assist purposes when created by
* {@link android.app.Activity#onProvideAssistData}, {@link View#onProvideStructure(ViewStructure)},
* or {@link View#onProvideVirtualStructure(ViewStructure)}.
*
- * <p>The structure is used for Autofill purposes when created by
+ * <p>The structure is used for autofill purposes when created by
* {@link View#onProvideAutofillStructure(ViewStructure, int)},
* or {@link View#onProvideAutofillVirtualStructure(ViewStructure, int)}.
*
- * <p>For performance reasons, some properties of the Assist data might be available just for Assist
- * or Autofill purposes; in those case, the property availability will be document in its javadoc.
+ * <p>For performance reasons, some properties of the assist data might be available just for assist
+ * or autofill purposes; in those case, the property availability will be document in its javadoc.
*/
public class AssistStructure implements Parcelable {
static final String TAG = "AssistStructure";
@@ -958,10 +956,10 @@
/**
* Gets the id that can be used to autofill the view contents.
*
- * <p>It's relevant set when the {@link AssistStructure} is used for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes.
*
* @return id that can be used to autofill the view contents, or {@code null} if the
- * structure was created for Assist purposes.
+ * structure was created for assist purposes.
*/
@Nullable public AutofillId getAutofillId() {
return mAutofillId;
@@ -970,10 +968,10 @@
/**
* Gets the the type of value that can be used to autofill the view contents.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes.
*
* @return autofill type as defined by {@link View#getAutofillType()},
- * or {@link View#AUTOFILL_TYPE_NONE} if the structure was created for Assist purposes.
+ * or {@link View#AUTOFILL_TYPE_NONE} if the structure was created for assist purposes.
*/
public @View.AutofillType int getAutofillType() {
return mAutofillType;
@@ -983,11 +981,11 @@
* Describes the content of a view so that a autofill service can fill in the appropriate
* data.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
+ * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
* not for Assist - see {@link View#getAutofillHints()} for more info.
*
* @return The autofill hints for this view, or {@code null} if the structure was created
- * for Assist purposes.
+ * for assist purposes.
*/
@Nullable public String[] getAutofillHints() {
return mAutofillHints;
@@ -996,11 +994,11 @@
/**
* Gets the the value of this view.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
- * not for Assist purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+ * not for assist purposes.
*
* @return the autofill value of this view, or {@code null} if the structure was created
- * for Assist purposes.
+ * for assist purposes.
*/
@Nullable public AutofillValue getAutofillValue() {
return mAutofillValue;
@@ -1017,11 +1015,11 @@
* <p>Typically used by nodes whose {@link View#getAutofillType()} is a list to indicate
* the meaning of each possible value in the list.
*
- * <p>It's relevant when the {@link AssistStructure} is used for Autofill purposes, not
- * for Assist purposes.
+ * <p>It's relevant when the {@link AssistStructure} is used for autofill purposes, not
+ * for assist purposes.
*
* @return the options that can be used to autofill this view, or {@code null} if the
- * structure was created for Assist purposes.
+ * structure was created for assist purposes.
*/
@Nullable public CharSequence[] getAutofillOptions() {
return mAutofillOptions;
@@ -1106,8 +1104,8 @@
* or scaling. The returned Matrix object is owned by ViewNode; do not modify it.
* Returns null if there is no transformation applied to the view.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public Matrix getTransformation() {
return mMatrix;
@@ -1118,8 +1116,8 @@
* characterstics, as set by {@link ViewStructure#setElevation
* ViewStructure.setElevation(float)}.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public float getElevation() {
return mElevation;
@@ -1130,8 +1128,8 @@
* of the view's contents, as set by {@link ViewStructure#setAlpha
* ViewStructure.setAlpha(float)}.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public float getAlpha() {
return mAlpha;
@@ -1260,7 +1258,7 @@
* document.
*
* <strong>WARNING:</strong> a {@link android.service.autofill.AutofillService} should only
- * use this domain for Autofill purposes when it trusts the app generating it (i.e., the app
+ * use this domain for autofill purposes when it trusts the app generating it (i.e., the app
* defined by {@link AssistStructure#getActivityComponent()}).
*
* @return domain-only part of the document. For example, if the full URL is
@@ -1273,11 +1271,11 @@
/**
* Returns the HTML properties associated with this view.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
- * not for Assist purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+ * not for assist purposes.
*
* @return the HTML properties associated with this view, or {@code null} if the
- * structure was created for Assist purposes.
+ * structure was created for assist purposes.
*/
@Nullable public HtmlInfo getHtmlInfo() {
return mHtmlInfo;
@@ -1301,8 +1299,8 @@
/**
* If {@link #getText()} is non-null, this is where the current selection starts.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int getTextSelectionStart() {
return mText != null ? mText.mTextSelectionStart : -1;
@@ -1313,8 +1311,8 @@
* If there is no selection, returns the same value as {@link #getTextSelectionStart()},
* indicating the cursor position.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int getTextSelectionEnd() {
return mText != null ? mText.mTextSelectionEnd : -1;
@@ -1337,8 +1335,8 @@
* Note that the text may also contain style spans that modify the color of specific
* parts of the text.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int getTextBackgroundColor() {
return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
@@ -1350,8 +1348,8 @@
* Note that the text may also contain style spans that modify the size of specific
* parts of the text.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public float getTextSize() {
return mText != null ? mText.mTextSize : 0;
@@ -1365,8 +1363,8 @@
* Note that the text may also contain style spans that modify the style of specific
* parts of the text.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int getTextStyle() {
return mText != null ? mText.mTextStyle : 0;
@@ -1378,8 +1376,8 @@
* into the text string where that line starts. May return null if there is no line
* information.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int[] getTextLineCharOffsets() {
return mText != null ? mText.mLineCharOffsets : null;
@@ -1391,8 +1389,8 @@
* where that text appears in the view. May return null if there is no line
* information.
*
- * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
- * not for Autofill purposes.
+ * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+ * not for autofill purposes.
*/
public int[] getTextLineBaselines() {
return mText != null ? mText.mLineBaselines : null;
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 4cee2df..99700df 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -18,7 +18,11 @@
import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.pm.PackageManager.ComponentInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManager.PackageInfoFlags;
+import android.content.pm.PackageManager.ResolveInfoFlags;
import android.os.Bundle;
import android.util.SparseArray;
@@ -133,16 +137,40 @@
public abstract boolean isPermissionsReviewRequired(String packageName, int userId);
/**
- * Gets all of the information we know about a particular package.
- *
- * @param packageName The package name to find.
- * @param userId The user under which to check.
- *
- * @return An {@link ApplicationInfo} containing information about the
- * package, or {@code null} if no application exists with that
- * package name.
+ * Retrieve all of the information we know about a particular package/application.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getPackageInfo(String, int)
*/
- public abstract ApplicationInfo getApplicationInfo(String packageName, int userId);
+ public abstract PackageInfo getPackageInfo(String packageName,
+ @PackageInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all of the information we know about a particular package/application.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getApplicationInfo(String, int)
+ */
+ public abstract ApplicationInfo getApplicationInfo(String packageName,
+ @ApplicationInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all of the information we know about a particular activity class.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getActivityInfo(ComponentName, int)
+ */
+ public abstract ActivityInfo getActivityInfo(ComponentName component,
+ @ComponentInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all activities that can be performed for the given intent.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#queryIntentActivities(Intent, int)
+ */
+ public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
+ @ResolveInfoFlags int flags, int filterCallingUid, int userId);
/**
* Interface to {@link com.android.server.pm.PackageManagerService#getHomeActivitiesAsUser}.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 417a95f..88c1627 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,7 +16,10 @@
package android.content.res;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.DisplayInfo;
import com.android.internal.util.XmlUtils;
@@ -42,12 +45,6 @@
import java.util.ArrayList;
import java.util.Locale;
-import static android.view.Surface.ROTATION_UNDEFINED;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_90;
-import static android.view.Surface.ROTATION_180;
-import static android.view.Surface.ROTATION_270;
-
/**
* This class describes all device configuration information that can
* impact the resources the application retrieves. This includes both
@@ -603,13 +600,6 @@
*/
public int orientation;
- /**
- * The rotation used at the time orientation was determined.
- * TODO(b/36812336): Move rotation out of {@link Configuration}.
- * {@hide}
- */
- private int rotation;
-
/** Constant for {@link #uiMode}: bits that encode the mode type. */
public static final int UI_MODE_TYPE_MASK = 0x0f;
/** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
@@ -897,7 +887,6 @@
navigation = o.navigation;
navigationHidden = o.navigationHidden;
orientation = o.orientation;
- rotation = o.rotation;
screenLayout = o.screenLayout;
colorMode = o.colorMode;
uiMode = o.uiMode;
@@ -1001,14 +990,6 @@
case ORIENTATION_PORTRAIT: sb.append(" port"); break;
default: sb.append(" orien="); sb.append(orientation); break;
}
- switch (rotation) {
- case ROTATION_UNDEFINED: sb.append(" ?rotation"); break;
- case ROTATION_0: sb.append(" rot0"); break;
- case ROTATION_90: sb.append(" rot90"); break;
- case ROTATION_180: sb.append(" rot180"); break;
- case ROTATION_270: sb.append(" rot270"); break;
- default: sb.append(" rot="); sb.append(rotation); break;
- }
switch ((uiMode&UI_MODE_TYPE_MASK)) {
case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
@@ -1096,7 +1077,6 @@
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
- rotation = ROTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_UNDEFINED;
colorMode = COLOR_MODE_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
@@ -1205,11 +1185,6 @@
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
- if (delta.rotation != ROTATION_UNDEFINED
- && rotation != delta.rotation) {
- changed |= ActivityInfo.CONFIG_ORIENTATION;
- rotation = delta.rotation;
- }
if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
&& (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
@@ -1404,10 +1379,6 @@
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
- if ((compareUndefined || delta.rotation != ROTATION_UNDEFINED)
- && rotation != delta.rotation) {
- changed |= ActivityInfo.CONFIG_ORIENTATION;
- }
if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
(SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
&& getScreenLayoutNoDirection(screenLayout) !=
@@ -1544,7 +1515,6 @@
dest.writeInt(navigation);
dest.writeInt(navigationHidden);
dest.writeInt(orientation);
- dest.writeInt(rotation);
dest.writeInt(screenLayout);
dest.writeInt(colorMode);
dest.writeInt(uiMode);
@@ -1581,7 +1551,6 @@
navigation = source.readInt();
navigationHidden = source.readInt();
orientation = source.readInt();
- rotation = source.readInt();
screenLayout = source.readInt();
colorMode = source.readInt();
uiMode = source.readInt();
@@ -1666,8 +1635,6 @@
if (n != 0) return n;
n = this.orientation - that.orientation;
if (n != 0) return n;
- n = this.rotation - that.rotation;
- if (n != 0) return n;
n = this.colorMode - that.colorMode;
if (n != 0) return n;
n = this.screenLayout - that.screenLayout;
@@ -1799,24 +1766,6 @@
/**
* @hide
*
- * Setter for orientation converts from {@link Surface} values to internal representation.
- */
- public void setRotation(int rotation) {
- this.rotation = rotation;
- }
-
- /**
- * @hide
- *
- * Getter for orientation. Converts from internal representation to {@link Surface} values.
- */
- public int getRotation() {
- return rotation != ROTATION_UNDEFINED ? rotation : ROTATION_0;
- }
-
- /**
- * @hide
- *
* Clears the locale without changing layout direction.
*/
public void clearLocales() {
@@ -2051,23 +2000,6 @@
break;
}
- switch (config.rotation) {
- case ROTATION_0:
- parts.add("rot0");
- break;
- case ROTATION_90:
- parts.add("rot90");
- break;
- case ROTATION_180:
- parts.add("rot180");
- break;
- case ROTATION_270:
- parts.add("rot270");
- break;
- default:
- break;
- }
-
switch (config.uiMode & Configuration.UI_MODE_TYPE_MASK) {
case Configuration.UI_MODE_TYPE_APPLIANCE:
parts.add("appliance");
@@ -2262,10 +2194,6 @@
delta.orientation = change.orientation;
}
- if (base.rotation != change.rotation) {
- base.rotation = change.rotation;
- }
-
if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
(change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
@@ -2337,7 +2265,6 @@
private static final String XML_ATTR_NAVIGATION = "nav";
private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
private static final String XML_ATTR_ORIENTATION = "ori";
- private static final String XML_ATTR_ROTATION = "rot";
private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
private static final String XML_ATTR_COLOR_MODE = "clrMod";
private static final String XML_ATTR_UI_MODE = "ui";
@@ -2397,8 +2324,6 @@
DENSITY_DPI_UNDEFINED);
configOut.appBounds =
Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
- configOut.rotation = XmlUtils.readIntAttribute(parser, XML_ATTR_ROTATION,
- ROTATION_UNDEFINED);
// For persistence, we don't care about assetsSeq, so do not read it out.
}
@@ -2475,10 +2400,6 @@
config.appBounds.flattenToString());
}
- if (config.rotation != ROTATION_UNDEFINED) {
- XmlUtils.writeIntAttribute(xml, XML_ATTR_ROTATION, config.rotation);
- }
-
// For persistence, we do not care about assetsSeq, so do not write it out.
}
}
diff --git a/core/java/android/net/NetworkBadging.java b/core/java/android/net/NetworkBadging.java
index 6de28b7..c119b63 100644
--- a/core/java/android/net/NetworkBadging.java
+++ b/core/java/android/net/NetworkBadging.java
@@ -66,15 +66,7 @@
*/
@NonNull public static Drawable getWifiIcon(
@IntRange(from=0, to=4) int signalLevel, @Badging int badging, @Nullable Theme theme) {
- Resources resources = Resources.getSystem();
- if (badging == BADGING_NONE) {
- return resources.getDrawable(getWifiSignalResource(signalLevel), theme);
- }
- Drawable[] layers = new Drawable[] {
- resources.getDrawable(getBadgedWifiSignalResource(signalLevel), theme),
- resources.getDrawable(getWifiBadgeResource(badging), theme)
- };
- return new LayerDrawable(layers);
+ return Resources.getSystem().getDrawable(getWifiSignalResource(signalLevel), theme);
}
/**
@@ -134,31 +126,4 @@
throw new IllegalArgumentException("Invalid signal level: " + signalLevel);
}
}
-
- /**
- * Returns the wifi quality badge resource id for the the given badging balue.
- *
- * <p>This badge should be displayed with the badge signal resource retrieved from
- * {@link #getBadgedWifiSignalResource(int)}.
- *
- * @param badging {@see NetworkBadging#Badging} from {@link ScoredNetwork#calculateBadge(int)}.
- * @return the @DrawableRes for the icon or {@link View#NO_ID} for
- * {@link NetworkBadging#BADGING_NONE}
- * @throws IllegalArgumentException for an invalid badging value.
- * @hide
- */
- @DrawableRes private static int getWifiBadgeResource(@Badging int badging) {
- switch (badging) {
- case BADGING_NONE:
- return View.NO_ID;
- case BADGING_SD:
- return com.android.internal.R.drawable.ic_signal_wifi_badged_sd;
- case BADGING_HD:
- return com.android.internal.R.drawable.ic_signal_wifi_badged_hd;
- case BADGING_4K:
- return com.android.internal.R.drawable.ic_signal_wifi_badged_4k;
- default:
- throw new IllegalArgumentException("No resource found for badge: " + badging);
- }
- }
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index ecc4dec..635df4c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -201,7 +201,7 @@
* New in version 22:
* - BLE scan result background count, BLE unoptimized scan time
*/
- static final String CHECKIN_VERSION = "22";
+ static final String CHECKIN_VERSION = "23";
/**
* Old version, we hit 9 and ran out of room, need to remove.
@@ -3051,6 +3051,7 @@
boolean wifiOnly) {
final long rawUptime = SystemClock.uptimeMillis() * 1000;
final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealtimeMs = (rawRealtime + 500) / 1000;
final long batteryUptime = getBatteryUptime(rawUptime);
final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
@@ -3437,7 +3438,6 @@
final int count = bleTimer.getCountLocked(which);
final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
- final long rawRealtimeMs = (rawRealtime + 500) / 1000;
// 'actualTime' are unpooled and always since reset (regardless of 'which')
final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
final long actualTimeBg = bleTimerBg != null ?
@@ -3486,11 +3486,11 @@
if (u.getAggregatedPartialWakelockTimer() != null) {
final Timer timer = u.getAggregatedPartialWakelockTimer();
- // Convert from microseconds to milliseconds with rounding
- final long totTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ // Times are since reset (regardless of 'which')
+ final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
final Timer bgTimer = timer.getSubTimer();
final long bgTimeMs = bgTimer != null ?
- (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+ bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
}
@@ -3527,7 +3527,7 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = timer.getSubTimer();
final long bgTime = bgTimer != null ?
- (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+ bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
if (totalTime != 0) {
dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"",
@@ -3543,7 +3543,7 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = timer.getSubTimer();
final long bgTime = bgTimer != null ?
- (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+ bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
if (totalTime != 0) {
dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
@@ -3574,7 +3574,6 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = se.getSensorBackgroundTime();
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
- final long rawRealtimeMs = (rawRealtime + 500) / 1000;
// 'actualTime' are unpooled and always since reset (regardless of 'which')
final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
final long bgActualTime = bgTimer != null ?
@@ -3715,6 +3714,7 @@
int reqUid, boolean wifiOnly) {
final long rawUptime = SystemClock.uptimeMillis() * 1000;
final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealtimeMs = (rawRealtime + 500) / 1000;
final long batteryUptime = getBatteryUptime(rawUptime);
final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
@@ -4655,7 +4655,6 @@
final int count = bleTimer.getCountLocked(which);
final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
- final long rawRealtimeMs = (rawRealtime + 500) / 1000;
// 'actualTime' are unpooled and always since reset (regardless of 'which')
final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
final long actualTimeMsBg = bleTimerBg != null ?
@@ -4823,10 +4822,10 @@
final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
// Convert from microseconds to milliseconds with rounding
actualTotalPartialWakelock =
- (aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ aggTimer.getTotalDurationMsLocked(rawRealtimeMs);
final Timer bgAggTimer = aggTimer.getSubTimer();
actualBgPartialWakelock = bgAggTimer != null ?
- (bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+ bgAggTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
}
if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
@@ -4894,7 +4893,7 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = timer.getSubTimer();
final long bgTime = bgTimer != null ?
- (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+ bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
sb.setLength(0);
sb.append(prefix);
@@ -4928,7 +4927,7 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = timer.getSubTimer();
final long bgTime = bgTimer != null ?
- (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+ bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
sb.setLength(0);
sb.append(prefix);
@@ -4987,7 +4986,6 @@
final int count = timer.getCountLocked(which);
final Timer bgTimer = se.getSensorBackgroundTime();
final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
- final long rawRealtimeMs = (rawRealtime + 500) / 1000;
// 'actualTime' are unpooled and always since reset (regardless of 'which')
final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
final long bgActualTime = bgTimer != null ?
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 286e790..51d6514 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -96,7 +96,7 @@
int flags, out Rect outFrame, out Rect outOverscanInsets,
out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
out Rect outOutsets, out Rect outBackdropFrame,
- inout MergedConfiguration mergedConfiguration, out Surface outSurface);
+ out MergedConfiguration outMergedConfiguration, out Surface outSurface);
/*
* Notify the window manager that an application is relaunching and
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 0ad591b..8bb3fa9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -129,17 +129,11 @@
public static final int SCALING_MODE_NO_SCALE_CROP = 3;
/** @hide */
- @IntDef({ROTATION_UNDEFINED, ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+ @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
@Retention(RetentionPolicy.SOURCE)
public @interface Rotation {}
/**
- * Rotation constant: undefined
- * @hide
- */
- public static final int ROTATION_UNDEFINED = -1;
-
- /**
* Rotation constant: 0 degree rotation (natural orientation)
*/
public static final int ROTATION_0 = 0;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 19ae253..a9c85f0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1139,6 +1139,10 @@
/**
* Autofill type for views that cannot be autofilled.
+ *
+ * <p>Typically used when the view is read-only; for example, a text label.
+ *
+ * @see #getAutofillType()
*/
public static final int AUTOFILL_TYPE_NONE = 0;
@@ -1148,6 +1152,8 @@
* <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
* {@link AutofillValue#forText(CharSequence)}, and the value passed to autofill a
* {@link View} can be fetched through {@link AutofillValue#getTextValue()}.
+ *
+ * @see #getAutofillType()
*/
public static final int AUTOFILL_TYPE_TEXT = 1;
@@ -1157,6 +1163,8 @@
* <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
* {@link AutofillValue#forToggle(boolean)}, and the value passed to autofill a
* {@link View} can be fetched through {@link AutofillValue#getToggleValue()}.
+ *
+ * @see #getAutofillType()
*/
public static final int AUTOFILL_TYPE_TOGGLE = 2;
@@ -1170,6 +1178,8 @@
*
* <p>The available options in the selection list are typically provided by
* {@link android.app.assist.AssistStructure.ViewNode#getAutofillOptions()}.
+ *
+ * @see #getAutofillType()
*/
public static final int AUTOFILL_TYPE_LIST = 3;
@@ -1182,6 +1192,8 @@
* <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
* {@link AutofillValue#forDate(long)}, and the values passed to
* autofill a {@link View} can be fetched through {@link AutofillValue#getDateValue()}.
+ *
+ * @see #getAutofillType()
*/
public static final int AUTOFILL_TYPE_DATE = 4;
@@ -1198,26 +1210,41 @@
/**
* Automatically determine whether a view is important for autofill.
+ *
+ * @see #isImportantForAutofill()
+ * @see #setImportantForAutofill(int)
*/
public static final int IMPORTANT_FOR_AUTOFILL_AUTO = 0x0;
/**
* The view is important for autofill, and its children (if any) will be traversed.
+ *
+ * @see #isImportantForAutofill()
+ * @see #setImportantForAutofill(int)
*/
public static final int IMPORTANT_FOR_AUTOFILL_YES = 0x1;
/**
* The view is not important for autofill, but its children (if any) will be traversed.
+ *
+ * @see #isImportantForAutofill()
+ * @see #setImportantForAutofill(int)
*/
public static final int IMPORTANT_FOR_AUTOFILL_NO = 0x2;
/**
* The view is important for autofill, but its children (if any) will not be traversed.
+ *
+ * @see #isImportantForAutofill()
+ * @see #setImportantForAutofill(int)
*/
public static final int IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS = 0x4;
/**
* The view is not important for autofill, and its children (if any) will not be traversed.
+ *
+ * @see #isImportantForAutofill()
+ * @see #setImportantForAutofill(int)
*/
public static final int IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS = 0x8;
@@ -7366,23 +7393,70 @@
}
/**
- * Called when assist structure is being retrieved from a view as part of an autofill request.
+ * Populates a {@link ViewStructure} to fullfil an autofill request.
*
- * <p>This method already provides most of what's needed for autofill, but should be overridden
- * when:
+ * <p>The structure should contain at least the following properties:
* <ul>
- * <li>The view contents does not include PII (Personally Identifiable Information), so it
- * can call {@link ViewStructure#setDataIsSensitive(boolean)} passing {@code false}.
- * <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
- * {@link ViewStructure#setAutofillOptions(CharSequence[])},
- * or {@link ViewStructure#setWebDomain(String)}.
- * <li> The {@code left} and {@code top} values set in
- * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
- * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
+ * <li>Autofill id ({@link ViewStructure#setAutofillId(AutofillId, int)}).
+ * <li>Autofill type ({@link ViewStructure#setAutofillType(int)}).
+ * <li>Autofill value ({@link ViewStructure#setAutofillValue(AutofillValue)}).
+ * <li>Whether the data is sensitive ({@link ViewStructure#setDataIsSensitive(boolean)}).
* </ul>
*
- * @param structure Fill in with structured view data. The default implementation
- * fills in all data that can be inferred from the view itself.
+ * <p>It's also recommended to set the following properties - the more properties the structure
+ * has, the higher the changes of an {@link android.service.autofill.AutofillService} properly
+ * using the structure:
+ *
+ * <ul>
+ * <li>Autofill hints ({@link ViewStructure#setAutofillHints(String[])}).
+ * <li>Autofill options ({@link ViewStructure#setAutofillOptions(CharSequence[])}) when the
+ * view can only be filled with predefined values (typically used when the autofill type
+ * is {@link #AUTOFILL_TYPE_LIST}).
+ * <li>Resource id ({@link ViewStructure#setId(int, String, String, String)}).
+ * <li>Class name ({@link ViewStructure#setClassName(String)}).
+ * <li>Content description ({@link ViewStructure#setContentDescription(CharSequence)}).
+ * <li>Visual properties such as visibility ({@link ViewStructure#setVisibility(int)}),
+ * dimensions ({@link ViewStructure#setDimens(int, int, int, int, int, int)}), and
+ * opacity ({@link ViewStructure#setOpaque(boolean)}).
+ * <li>For views representing text fields, text properties such as the text itself
+ * ({@link ViewStructure#setText(CharSequence)}), text hints
+ * ({@link ViewStructure#setHint(CharSequence)}, input type
+ * ({@link ViewStructure#setInputType(int)}),
+ * <li>For views representing HTML nodes, its web domain
+ * ({@link ViewStructure#setWebDomain(String)}) and HTML properties
+ * (({@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}).
+ * </ul>
+ *
+ * <p>The default implementation of this method already sets most of these properties based on
+ * related {@link View} methods (for example, the autofill id is set using
+ * {@link #getAutofillId()}, the autofill type set using {@link #getAutofillType()}, etc.),
+ * and views in the standard Android widgets library also override it to set their
+ * relevant properties (for example, {@link android.widget.TextView} already sets the text
+ * properties), so it's recommended to only override this method
+ * (and call {@code super.onProvideAutofillStructure()}) when:
+ *
+ * <ul>
+ * <li>The view contents does not include PII (Personally Identifiable Information), so it
+ * can call {@link ViewStructure#setDataIsSensitive(boolean)} passing {@code false}.
+ * <li>The view can only be autofilled with predefined options, so it can call
+ * {@link ViewStructure#setAutofillOptions(CharSequence[])}.
+ * </ul>
+ *
+ * <p><b>NOTE:</b> the {@code left} and {@code top} values set in
+ * {@link ViewStructure#setDimens(int, int, int, int, int, int)} must be relative to the next
+ * {@link ViewGroup#isImportantForAutofill()} predecessor view included in the structure.
+ *
+ * <p>Views support the Autofill Framework mainly by:
+ * <ul>
+ * <li>Providing the metadata defining what the view means and how it can be autofilled.
+ * <li>Notifying the Android System when the view value changed by calling
+ * {@link AutofillManager#notifyValueChanged(View)}.
+ * <li>Implementing the methods that autofill the view.
+ * </ul>
+ * <p>This method is responsible for the former; {@link #autofill(AutofillValue)} is responsible
+ * for the latter.
+ *
+ * @param structure fill in with structured view data for autofill purposes.
* @param flags optional flags.
*
* @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
@@ -7510,32 +7584,56 @@
}
/**
- * Called when assist structure is being retrieved from a view as part of an autofill request
- * to generate additional virtual structure under this view.
+ * Populates a {@link ViewStructure} containing virtual children to fullfil an autofill
+ * request.
+ *
+ * <p>This method should be used when the view manages a virtual structure under this view. For
+ * example, a view that draws input fields using {@link #draw(Canvas)}.
*
* <p>When implementing this method, subclasses must follow the rules below:
*
- * <ol>
- * <li>Also implement {@link #autofill(SparseArray)} to autofill the virtual
- * children.
- * <li>Call
- * {@link android.view.autofill.AutofillManager#notifyViewEntered} and
- * {@link android.view.autofill.AutofillManager#notifyViewExited(View, int)}
- * when the focus inside the view changed.
- * <li>Call {@link android.view.autofill.AutofillManager#notifyValueChanged(View, int,
- * AutofillValue)} when the value of a child changed.
- * <li>Call {@link AutofillManager#commit()} when the autofill context
- * of the view structure changed and you want the current autofill interaction if such
- * to be commited.
- * <li>Call {@link AutofillManager#cancel()} when the autofill context
- * of the view structure changed and you want the current autofill interaction if such
- * to be cancelled.
- * <li> The {@code left} and {@code top} values set in
- * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
- * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
- * </ol>
+ * <ul>
+ * <li>Add virtual children by calling the {@link ViewStructure#newChild(int)} or
+ * {@link ViewStructure#asyncNewChild(int)} methods, where the {@code id} is an unique id
+ * identifying the children in the virtual structure.
+ * <li>The children hierarchy can have multiple levels if necessary, but ideally it should
+ * exclude intermediate levels that are irrelevant for autofill; that would improve the
+ * autofill performance.
+ * <li>Also implement {@link #autofill(SparseArray)} to autofill the virtual
+ * children.
+ * <li>Set the autofill properties of the child structure as defined by
+ * {@link #onProvideAutofillStructure(ViewStructure, int)}, using
+ * {@link ViewStructure#setAutofillId(AutofillId, int)} to set its autofill id.
+ * <li>Call {@link android.view.autofill.AutofillManager#notifyViewEntered(View, int, Rect)}
+ * and/or {@link android.view.autofill.AutofillManager#notifyViewExited(View, int)}
+ * when the focused virtual child changed.
+ * <li>Call
+ * {@link android.view.autofill.AutofillManager#notifyValueChanged(View, int, AutofillValue)}
+ * when the value of a virtual child changed.
+ * <li>Call {@link AutofillManager#commit()} when the autofill context of the view structure
+ * changed and the current context should be committed (for example, when the user tapped
+ * a {@code SUBMIT} button in an HTML page).
+ * <li>Call {@link AutofillManager#cancel()} when the autofill context of the view structure
+ * changed and the current context should be canceled (for example, when the user tapped
+ * a {@code CANCEL} button in an HTML page).
+ * <li>Provide ways for users to manually request autofill by calling
+ * {@link AutofillManager#requestAutofill(View, int, Rect)}.
+ * <li>The {@code left} and {@code top} values set in
+ * {@link ViewStructure#setDimens(int, int, int, int, int, int)} must be relative to the
+ * next {@link ViewGroup#isImportantForAutofill()} predecessor view included in the
+ * structure.
+ * </ul>
*
- * @param structure Fill in with structured view data.
+ * <p>Views with virtual children support the Autofill Framework mainly by:
+ * <ul>
+ * <li>Providing the metadata defining what the virtual children mean and how they can be
+ * autofilled.
+ * <li>Implementing the methods that autofill the virtual children.
+ * </ul>
+ * <p>This method is responsible for the former; {@link #autofill(SparseArray)} is responsible
+ * for the latter.
+ *
+ * @param structure fill in with virtual children data for autofill purposes.
* @param flags optional flags.
*
* @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
@@ -7546,15 +7644,21 @@
/**
* Automatically fills the content of this view with the {@code value}.
*
- * <p>By default does nothing, but views should override it (and {@link #getAutofillType()},
- * {@link #getAutofillValue()}, and {@link #onProvideAutofillStructure(ViewStructure, int)}
- * to support the Autofill Framework.
+ * <p>Views support the Autofill Framework mainly by:
+ * <ul>
+ * <li>Providing the metadata defining what the view means and how it can be autofilled.
+ * <li>Implementing the methods that autofill the view.
+ * </ul>
+ * <p>{@link #onProvideAutofillStructure(ViewStructure, int)} is responsible for the former,
+ * this method is responsible for latter.
*
- * <p>Typically, it is implemented by:
- *
+ * <p>This method does nothing by default, but when overridden it typically:
* <ol>
- * <li>Calling the proper getter method on {@link AutofillValue} to fetch the actual value.
- * <li>Passing the actual value to the equivalent setter in the view.
+ * <li>Checks if the provided value matches the expected type (which is defined by
+ * {@link #getAutofillType()}).
+ * <li>Checks if the view is editable - if it isn't, it should return right away.
+ * <li>Call the proper getter method on {@link AutofillValue} to fetch the actual value.
+ * <li>Pass the actual value to the equivalent setter in the view.
* </ol>
*
* <p>For example, a text-field view could implement the method this way:
@@ -7573,7 +7677,7 @@
* </pre>
*
* <p>If the value is updated asynchronously the next call to
- * {@link AutofillManager#notifyValueChanged(View)} must happen <u>after</u> the value was
+ * {@link AutofillManager#notifyValueChanged(View)} must happen <b>after</b> the value was
* changed to the autofilled value. If not, the view will not be considered autofilled.
*
* @param value value to be autofilled.
@@ -7582,11 +7686,19 @@
}
/**
- * Automatically fills the content of a virtual views.
+ * Automatically fills the content of the virtual children within this view.
*
- * <p>See {@link #autofill(AutofillValue)} and
- * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
- * <p>To indicate that a virtual view was autofilled
+ * <p>Views with virtual children support the Autofill Framework mainly by:
+ * <ul>
+ * <li>Providing the metadata defining what the virtual children mean and how they can be
+ * autofilled.
+ * <li>Implementing the methods that autofill the virtual children.
+ * </ul>
+ * <p>{@link #onProvideAutofillVirtualStructure(ViewStructure, int)} is responsible for the
+ * former, this method is responsible for the latter - see {@link #autofill(AutofillValue)} and
+ * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info about autofill.
+ *
+ * <p><b>NOTE:</b> to indicate that a virtual view was autofilled,
* <code>?android:attr/autofilledHighlight</code> should be drawn over it until the data
* changes.
*
@@ -7598,9 +7710,9 @@
}
/**
- * Gets the unique identifier of this view on the screen for Autofill purposes.
+ * Gets the unique identifier of this view in the screen, for autofill purposes.
*
- * @return The View's Autofill id.
+ * @return The View's autofill id.
*/
public final AutofillId getAutofillId() {
if (mAutofillId == null) {
@@ -7612,11 +7724,18 @@
}
/**
- * Describes the autofill type that should be used on calls to
- * {@link #autofill(AutofillValue)} and {@link #autofill(SparseArray)}.
+ * Describes the autofill type of this view, so an
+ * {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue}
+ * when autofilling the view.
*
- * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it (and
- * {@link #autofill(AutofillValue)} to support the Autofill Framework.
+ * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it to properly
+ * support the Autofill Framework.
+ *
+ * @return either {@link #AUTOFILL_TYPE_NONE}, {@link #AUTOFILL_TYPE_TEXT},
+ * {@link #AUTOFILL_TYPE_LIST}, {@link #AUTOFILL_TYPE_DATE}, or {@link #AUTOFILL_TYPE_TOGGLE}.
+ *
+ * @see #onProvideAutofillStructure(ViewStructure, int)
+ * @see #autofill(AutofillValue)
*/
public @AutofillType int getAutofillType() {
return AUTOFILL_TYPE_NONE;
@@ -7648,9 +7767,11 @@
/**
* Gets the {@link View}'s current autofill value.
*
- * <p>By default returns {@code null}, but views should override it (and
- * {@link #autofill(AutofillValue)}, and {@link #getAutofillType()} to support the Autofill
- * Framework.
+ * <p>By default returns {@code null}, but views should override it to properly support the
+ * Autofill Framework.
+ *
+ * @see #onProvideAutofillStructure(ViewStructure, int)
+ * @see #autofill(AutofillValue)
*/
@Nullable
public AutofillValue getAutofillValue() {
@@ -7658,9 +7779,10 @@
}
/**
- * Gets the mode for determining whether this View is important for autofill.
+ * Gets the mode for determining whether this view is important for autofill.
*
- * <p>See {@link #setImportantForAutofill(int)} for more info about this mode.
+ * <p>See {@link #setImportantForAutofill(int)} and {@link #isImportantForAutofill()} for more
+ * info about this mode.
*
* @return {@link #IMPORTANT_FOR_AUTOFILL_AUTO} by default, or value passed to
* {@link #setImportantForAutofill(int)}.
@@ -7681,20 +7803,29 @@
}
/**
- * Sets the mode for determining whether this View is important for autofill.
- *
- * <p>This property controls how this view is presented to the autofill components
- * which help users to fill credentials, addresses, etc. For example, views
- * that contain labels and input fields are useful for autofill components to
- * determine the user context and provide values for the inputs. Note that the
- * user can always override this by manually triggering autotill which would
- * expose the view to the autofill provider.
+ * Sets the mode for determining whether this view is considered important for autofill.
*
* <p>The platform determines the importance for autofill automatically but you
- * can use this method to customize the behavior. See the autofill modes below
- * for more details.
+ * can use this method to customize the behavior. For example:
*
- * <p>See {@link #setImportantForAutofill(int)} for more info about this mode.
+ * <ol>
+ * <li>When the view contents is irrelevant for autofill (for example, a text field used in a
+ * "Captcha" challenge), it should be {@link #IMPORTANT_FOR_AUTOFILL_NO}.
+ * <li>When both the view and its children are irrelevant for autofill (for example, the root
+ * view of an activity containing a spreadhseet editor), it should be
+ * {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}.
+ * <li>When the view content is relevant for autofill but its children aren't (for example,
+ * a credit card expiration date represented by a custom view that overrides the proper
+ * autofill methods and has 2 children representing the month and year), it should
+ * be {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS}.
+ * </ol>
+ *
+ * <p><b>NOTE:</strong> setting the mode as does {@link #IMPORTANT_FOR_AUTOFILL_NO} or
+ * {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS} does not guarantee the view (and its
+ * children) will be always be considered not important; for example, when the user explicitly
+ * makes an autofill request, all views are considered important. See
+ * {@link #isImportantForAutofill()} for more details about how the View's importance for
+ * autofill is used.
*
* @param mode {@link #IMPORTANT_FOR_AUTOFILL_AUTO}, {@link #IMPORTANT_FOR_AUTOFILL_YES},
* {@link #IMPORTANT_FOR_AUTOFILL_NO}, {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS},
@@ -7710,40 +7841,51 @@
/**
* Hints the Android System whether the {@link android.app.assist.AssistStructure.ViewNode}
- * associated with this View should be included in a {@link ViewStructure} used for
- * autofill purposes.
+ * associated with this view is considered important for autofill purposes.
*
* <p>Generally speaking, a view is important for autofill if:
* <ol>
- * <li>The view can-be autofilled by an {@link android.service.autofill.AutofillService}.
- * <li>The view contents can help an {@link android.service.autofill.AutofillService} to
- * autofill other views.
+ * <li>The view can be autofilled by an {@link android.service.autofill.AutofillService}.
+ * <li>The view contents can help an {@link android.service.autofill.AutofillService}
+ * determine how other views can be autofilled.
* <ol>
*
* <p>For example, view containers should typically return {@code false} for performance reasons
- * (since the important info is provided by their children), but if the container is actually
- * whose children are part of a compound view, it should return {@code true} (and then override
- * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
- * {@link #onProvideAutofillStructure(ViewStructure, int)} so its children are not included in
- * the structure). On the other hand, views representing labels or editable fields should
- * typically return {@code true}, but in some cases they could return {@code false} (for
- * example, if they're part of a "Captcha" mechanism).
+ * (since the important info is provided by their children), but if its properties have relevant
+ * information (for example, a resource id called {@code credentials}, it should return
+ * {@code true}. On the other hand, views representing labels or editable fields should
+ * typically return {@code true}, but in some cases they could return {@code false}
+ * (for example, if they're part of a "Captcha" mechanism).
*
- * <p>By default, this method returns {@code true} if {@link #getImportantForAutofill()} returns
- * {@link #IMPORTANT_FOR_AUTOFILL_YES}, {@code false } if it returns
- * {@link #IMPORTANT_FOR_AUTOFILL_NO}, and use some heuristics to define the importance when it
- * returns {@link #IMPORTANT_FOR_AUTOFILL_AUTO}. Hence, it should rarely be overridden - Views
- * should use {@link #setImportantForAutofill(int)} instead.
+ * <p>The value returned by this method depends on the value returned by
+ * {@link #getImportantForAutofill()}:
*
- * <p><strong>Note:</strong> returning {@code false} does not guarantee the view will be
- * excluded from the structure; for example, if the user explicitly requested autofill, the
- * View might be always included.
+ * <ol>
+ * <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_YES} or
+ * {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS}, then it returns {@code true}
+ * <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_NO} or
+ * {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}, then it returns {@code false}
+ * <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_AUTO}, then it uses some simple heuristics
+ * that can return {@code true} in some cases (like a container with a resource id),
+ * but {@code false} in most.
+ * <li>otherwise, it returns {@code false}.
+ * </ol>
*
- * <p>This decision applies just for the view, not its children - if the view children are not
- * important for autofill, the view should override
- * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
- * {@link #onProvideAutofillStructure(ViewStructure, int)} (instead of calling
- * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} for each child).
+ * <p>When a view is considered important for autofill:
+ * <ul>
+ * <li>The view might automatically trigger an autofill request when focused on.
+ * <li>The contents of the view are included in the {@link ViewStructure} used in an autofill
+ * request.
+ * </ul>
+ *
+ * <p>On the other hand, when a view is considered not important for autofill:
+ * <ul>
+ * <li>The view never automatically triggers autofill requests, but it can trigger a manual
+ * request through {@link AutofillManager#requestAutofill(View)}.
+ * <li>The contents of the view are not included in the {@link ViewStructure} used in an
+ * autofill request, unless the request has the
+ * {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag.
+ * </ul>
*
* @return whether the view is considered important for autofill.
*
@@ -7753,6 +7895,7 @@
* @see #IMPORTANT_FOR_AUTOFILL_NO
* @see #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS
* @see #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
+ * @see AutofillManager#requestAutofill(View)
*/
public final boolean isImportantForAutofill() {
// Check parent mode to ensure we're not hidden.
@@ -7877,29 +8020,38 @@
}
/**
- * Dispatch creation of {@link ViewStructure} down the hierarchy.
+ * Dispatches creation of a {@link ViewStructure}s for autofill purposes down the hierarchy,
+ * when an Assist structure is being created as part of an autofill request.
*
* <p>The default implementation does the following:
- *
* <ul>
* <li>Sets the {@link AutofillId} in the structure.
* <li>Calls {@link #onProvideAutofillStructure(ViewStructure, int)}.
* <li>Calls {@link #onProvideAutofillVirtualStructure(ViewStructure, int)}.
* </ul>
*
- * <p>When overridden, it must either call
- * {@code super.dispatchProvideAutofillStructure(structure, flags)} or explicitly
- * set the {@link AutofillId} in the structure (for example, by calling
- * {@code structure.setAutofillId(getAutofillId())}).
+ * <p>Typically, this method should only be overridden by subclasses that provide a view
+ * hierarchy (such as {@link ViewGroup}) - other classes should override
+ * {@link #onProvideAutofillStructure(ViewStructure, int)} or
+ * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} instead.
*
- * <p>When providing your implementation you need to decide how to handle
- * the {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag which instructs you
- * to report all views to the structure regardless if {@link #isImportantForAutofill()}
- * returns true. We encourage you respect the importance property for a better
- * user experience in your app. If the flag is not set then you should filter out
- * not important views to optimize autofill performance in your app.
+ * <p>When overridden, it must:
*
- * @param structure Fill in with structured view data.
+ * <ul>
+ * <li>Either call
+ * {@code super.dispatchProvideAutofillStructure(structure, flags)} or explicitly
+ * set the {@link AutofillId} in the structure (for example, by calling
+ * {@code structure.setAutofillId(getAutofillId())}).
+ * <li>Decide how to handle the {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag - when
+ * set, all views in the structure should be considered important for autofill,
+ * regardless of what {@link #isImportantForAutofill()} returns. We encourage you to
+ * respect this flag to provide a better user experience - this flag is typically used
+ * when an user explicitly requested autofill. If the flag is not set,
+ * then only views marked as important for autofill should be included in the
+ * structure - skipping non-important views optimizes the overall autofill performance.
+ * </ul>
+ *
+ * @param structure fill in with structured view data for autofill purposes.
* @param flags optional flags.
*
* @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 19e0c95..2605b4a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1845,12 +1845,8 @@
final boolean isViewVisible = viewVisibility == View.VISIBLE;
final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
- final int contextConfigSeq = mContext.getResources().getConfiguration().seq;
- final int lastConfigSeq = mLastReportedMergedConfiguration.getMergedConfiguration().seq;
- final boolean staleConfig = lastConfigSeq != 0 && contextConfigSeq != lastConfigSeq;
-
- if (mFirst || windowShouldResize || insetsChanged || staleConfig || viewVisibilityChanged
- || params != null || mForceNextWindowRelayout) {
+ if (mFirst || windowShouldResize || insetsChanged ||
+ viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
mForceNextWindowRelayout = false;
if (isViewVisible) {
@@ -6087,13 +6083,7 @@
if (params != null) {
if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
}
-
- if (mPendingMergedConfiguration.getMergedConfiguration().seq == 0) {
- mPendingMergedConfiguration.setTo(mLastReportedMergedConfiguration);
- }
-
- int initialConfigSeq = mPendingMergedConfiguration.getMergedConfiguration().seq;
-
+ mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
//Log.d(mTag, ">>>>>> CALLING relayout");
if (params != null && mOrigWindowType != params.type) {
// For compatibility with old apps, don't crash here.
@@ -6112,10 +6102,6 @@
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame,
mPendingMergedConfiguration, mSurface);
- if (initialConfigSeq == mPendingMergedConfiguration.getMergedConfiguration().seq) {
- mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
- }
-
mPendingAlwaysConsumeNavBar =
(relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index ddfe697..0ecd20d 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -269,6 +269,9 @@
* Create a new child {@link ViewStructure} in this view, putting into the list of
* children at <var>index</var>.
*
+ * <p><b>NOTE: </b>you must pre-allocate space for the child first, by calling either
+ * {@link #addChildCount(int)} or {@link #setChildCount(int)}.
+ *
* @return Returns an fresh {@link ViewStructure} ready to be filled in.
*/
public abstract ViewStructure newChild(int index);
@@ -279,6 +282,10 @@
* to build its content (and children etc). Once done, some thread must call
* {@link #asyncCommit} to tell the containing {@link ViewStructure} that the async
* population is done.
+ *
+ * <p><b>NOTE: </b>you must pre-allocate space for the child first, by calling either
+ * {@link #addChildCount(int)} or {@link #setChildCount(int)}.
+ *
* @return Returns an fresh {@link ViewStructure} ready to be filled in.
*/
public abstract ViewStructure asyncNewChild(int index);
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index cfd1445..1e8207a 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -16,8 +16,6 @@
package android.widget;
-import static android.os.Build.VERSION_CODES.O;
-
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -293,22 +291,10 @@
* @param timeInMillis the target day in milliseconds
* @param animate whether to smooth scroll to the new position
* @param setSelected whether to set the specified day as selected
- *
- * @throws IllegalArgumentException if the build version is greater than
- * {@link android.os.Build.VERSION_CODES#N_MR1} and the provided timeInMillis is before
- * the range start or after the range end.
*/
private void setDate(long timeInMillis, boolean animate, boolean setSelected) {
getTempCalendarForTime(timeInMillis);
- final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
- if (targetSdkVersion >= O) {
- if (mTempCalendar.before(mMinDate) || mTempCalendar.after(mMaxDate)) {
- throw new IllegalArgumentException("timeInMillis must be between the values of "
- + "getMinDate() and getMaxDate()");
- }
- }
-
if (setSelected) {
mSelectedDay.setTimeInMillis(timeInMillis);
}
@@ -367,6 +353,13 @@
public void onRangeChanged() {
mAdapter.setRange(mMinDate, mMaxDate);
+ // Clamp the selected day to the new min/max.
+ if (mSelectedDay.before(mMinDate)) {
+ mSelectedDay.setTimeInMillis(mMinDate.getTimeInMillis());
+ } else if (mSelectedDay.after(mMaxDate)) {
+ mSelectedDay.setTimeInMillis(mMaxDate.getTimeInMillis());
+ }
+
// Changing the min/max date changes the selection position since we
// don't really have stable IDs. Jumps immediately to the new position.
setDate(mSelectedDay.getTimeInMillis(), false, false);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 46942bf..235ebc8 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3518,6 +3518,7 @@
public void removeIsolatedUidLocked(int isolatedUid) {
mIsolatedUids.delete(isolatedUid);
mKernelUidCpuTimeReader.removeUid(isolatedUid);
+ mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
}
public int mapUid(int uid) {
@@ -10351,6 +10352,9 @@
public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
+ mKernelUidCpuFreqTimeReader.removeUid(uid);
+ Slog.d(TAG, "Got freq readings for an isolated uid with"
+ + " no mapping to owning uid: " + uid);
return;
}
final Uid u = getUidStatsLocked(uid);
@@ -11019,6 +11023,7 @@
*/
public void removeUidStatsLocked(int uid) {
mKernelUidCpuTimeReader.removeUid(uid);
+ mKernelUidCpuFreqTimeReader.removeUid(uid);
mUidStats.remove(uid);
}
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index 9fbc4a8..ff521c2 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -72,6 +72,10 @@
}
}
+ public void removeUid(int uid) {
+ mLastUidCpuFreqTimeMs.delete(uid);
+ }
+
@VisibleForTesting
public void readDelta(BufferedReader reader, @Nullable Callback callback) throws IOException {
String line = reader.readLine();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
index 6678f8b..5680d9f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
@@ -1139,9 +1139,18 @@
}
List<Integer> modeList = new ArrayList<Integer>();
for (int mode : modes) {
- modeList.add(mode);
+ // Skip vendor-added modes
+ if (mode <= CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
+ modeList.add(mode);
+ }
}
checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
+ modes = new int[modeList.size()];
+ for (int i = 0; i < modeList.size(); i++) {
+ modes[i] = modeList.get(i);
+ }
+
+ checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
// All camera device must support ON
checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain ON mode",
@@ -1227,7 +1236,17 @@
return new int[0];
}
- List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes));
+ List<Integer> modesList = new ArrayList<Integer>();
+ for (int afMode : afModes) {
+ // Skip vendor-added AF modes
+ if (afMode > CameraCharacteristics.CONTROL_AF_MODE_EDOF) continue;
+ modesList.add(afMode);
+ }
+ afModes = new int[modesList.size()];
+ for (int i = 0; i < modesList.size(); i++) {
+ afModes[i] = modesList.get(i);
+ }
+
if (isHardwareLevelLimitedOrBetter()) {
// Some LEGACY mode devices do not support AF OFF
checkTrueForKey(key, " All camera devices must support OFF mode",
@@ -1417,6 +1436,16 @@
return fpsRanges;
}
+ public static String getAeModeName(int aeMode) {
+ return (aeMode >= AE_MODE_NAMES.length) ? String.format("VENDOR_AE_MODE_%d", aeMode) :
+ AE_MODE_NAMES[aeMode];
+ }
+
+ public static String getAfModeName(int afMode) {
+ return (afMode >= AF_MODE_NAMES.length) ? String.format("VENDOR_AF_MODE_%d", afMode) :
+ AF_MODE_NAMES[afMode];
+ }
+
/**
* Get the highest supported target FPS range.
* Prioritizes maximizing the min FPS, then the max FPS without lowering min FPS.
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 20cc5a6..40a59cf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -136,8 +136,6 @@
private final NetworkScoreManager mNetworkScoreManager;
private final WifiNetworkScoreCache mScoreCache;
- private boolean mNetworkScoringUiEnabled;
- private final ContentObserver mObserver;
@GuardedBy("mLock")
private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
@@ -225,16 +223,6 @@
updateNetworkScores();
}
});
-
- mObserver = new ContentObserver(mWorkHandler) {
- @Override
- public void onChange(boolean selfChange) {
- mNetworkScoringUiEnabled =
- Settings.Global.getInt(
- mContext.getContentResolver(),
- Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
- }
- };
}
/**
@@ -308,12 +296,6 @@
synchronized (mLock) {
registerScoreCache();
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
- false /* notifyForDescendants */,
- mObserver);
- mObserver.onChange(false /* selfChange */); // Set mScoringUiEnabled
-
resumeScanning();
if (!mRegistered) {
mContext.registerReceiver(mReceiver, mFilter);
@@ -360,7 +342,6 @@
}
unregisterAndClearScoreCache();
pauseScanning();
- mContext.getContentResolver().unregisterContentObserver(mObserver);
mWorkHandler.removePendingMessages();
mMainHandler.removePendingMessages();
@@ -580,7 +561,7 @@
requestScoresForNetworkKeys(scoresToRequest);
for (AccessPoint ap : accessPoints) {
- ap.update(mScoreCache, mNetworkScoringUiEnabled);
+ ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */);
}
// Pre-sort accessPoints to speed preference insertion
@@ -678,7 +659,7 @@
updated = true;
if (previouslyConnected != ap.isActive()) reorder = true;
}
- if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
+ if (ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */)) {
reorder = true;
updated = true;
}
@@ -701,7 +682,8 @@
synchronized (mLock) {
boolean updated = false;
for (int i = 0; i < mInternalAccessPoints.size(); i++) {
- if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
+ if (mInternalAccessPoints.get(i).update(
+ mScoreCache, false /* mNetworkScoringUiEnabled */)) {
updated = true;
}
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 086e10c..c526432 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -473,7 +473,7 @@
}
@Test
- public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
+ public void scoreCacheUpdateScoresShouldNotChangeSortOrder() throws InterruptedException {
WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
List<AccessPoint> aps = tracker.getAccessPoints();
assertTrue(aps.size() == 2);
@@ -484,8 +484,8 @@
aps = tracker.getAccessPoints();
assertTrue(aps.size() == 2);
- assertEquals(aps.get(0).getSsidStr(), SSID_2);
- assertEquals(aps.get(1).getSsidStr(), SSID_1);
+ assertEquals(aps.get(0).getSsidStr(), SSID_1);
+ assertEquals(aps.get(1).getSsidStr(), SSID_2);
}
@Test
@@ -511,7 +511,8 @@
}
@Test
- public void scoreCacheUpdateScoresShouldInsertBadgeIntoAccessPoint() throws InterruptedException {
+ public void scoreCacheUpdateScoresShouldNotInsertBadgeIntoAccessPoint()
+ throws InterruptedException {
WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
updateScoresAndWaitForAccessPointsChangedCallback();
@@ -519,9 +520,9 @@
for (AccessPoint ap : aps) {
if (ap.getSsidStr().equals(SSID_1)) {
- assertEquals(BADGE_1, ap.getBadge());
+ assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
} else if (ap.getSsidStr().equals(SSID_2)) {
- assertEquals(BADGE_2, ap.getBadge());
+ assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
}
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 455d9cb..f5d7dd8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2212,11 +2212,7 @@
throw new IllegalStateException("Key is corrupted", e);
}
- // Mac the package name and each of the signatures.
- final String packageName = callingPkg.packageName;
- byte[] packageNameBytes = packageName.getBytes(StandardCharsets.UTF_8);
- m.update(getLengthPrefix(packageNameBytes), 0, 4);
- m.update(packageNameBytes);
+ // Mac each of the developer signatures.
for (int i = 0; i < callingPkg.signatures.length; i++) {
byte[] sig = callingPkg.signatures[i].toByteArray();
m.update(getLengthPrefix(sig), 0, 4);
@@ -2231,7 +2227,7 @@
final String uid = Integer.toString(callingPkg.applicationInfo.uid);
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
- packageName);
+ callingPkg.packageName);
if (!success) {
throw new IllegalStateException("Ssaid settings not accessible");
diff --git a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
index 3fb86d0..1b6fa4c 100644
--- a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
@@ -16,5 +16,5 @@
-->
<resources>
- <dimen name="widget_big_font_size">64dp</dimen>
+ <dimen name="widget_big_font_size">72dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
index 3fb86d0..1b6fa4c 100644
--- a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
@@ -16,5 +16,5 @@
-->
<resources>
- <dimen name="widget_big_font_size">64dp</dimen>
+ <dimen name="widget_big_font_size">72dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 3ca6e69..41c723e 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -41,7 +41,7 @@
<!-- Default clock parameters -->
<dimen name="bottom_text_spacing_digital">-1dp</dimen>
<dimen name="widget_label_font_size">14sp</dimen>
- <dimen name="widget_big_font_size">64dp</dimen>
+ <dimen name="widget_big_font_size">72dp</dimen>
<!-- The y translation to apply at the start in appear animations. -->
<dimen name="appear_y_translation_start">32dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 6fb5d6b..1c1be98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1395,6 +1395,7 @@
if (mIsSummaryWithChildren) {
mChildrenContainer.setDark(dark, fade, delay);
}
+ updateShelfIconColor();
}
public boolean isExpandable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index baf0c2c..c432ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -49,11 +49,11 @@
*/
public class NotificationContentView extends FrameLayout {
- private static final int VISIBLE_TYPE_CONTRACTED = 0;
- private static final int VISIBLE_TYPE_EXPANDED = 1;
- private static final int VISIBLE_TYPE_HEADSUP = 2;
+ public static final int VISIBLE_TYPE_CONTRACTED = 0;
+ public static final int VISIBLE_TYPE_EXPANDED = 1;
+ public static final int VISIBLE_TYPE_HEADSUP = 2;
private static final int VISIBLE_TYPE_SINGLELINE = 3;
- private static final int VISIBLE_TYPE_AMBIENT = 4;
+ public static final int VISIBLE_TYPE_AMBIENT = 4;
private static final int VISIBLE_TYPE_AMBIENT_SINGLELINE = 5;
public static final int UNDEFINED = -1;
@@ -928,7 +928,7 @@
}
}
- private NotificationViewWrapper getVisibleWrapper(int visibleType) {
+ public NotificationViewWrapper getVisibleWrapper(int visibleType) {
switch (visibleType) {
case VISIBLE_TYPE_EXPANDED:
return mExpandedWrapper;
@@ -1085,16 +1085,16 @@
mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
updateAllSingleLineViews();
if (mContractedChild != null) {
- mContractedWrapper.notifyContentUpdated(entry.row);
+ mContractedWrapper.onContentUpdated(entry.row);
}
if (mExpandedChild != null) {
- mExpandedWrapper.notifyContentUpdated(entry.row);
+ mExpandedWrapper.onContentUpdated(entry.row);
}
if (mHeadsUpChild != null) {
- mHeadsUpWrapper.notifyContentUpdated(entry.row);
+ mHeadsUpWrapper.onContentUpdated(entry.row);
}
if (mAmbientChild != null) {
- mAmbientWrapper.notifyContentUpdated(entry.row);
+ mAmbientWrapper.onContentUpdated(entry.row);
}
applyRemoteInput(entry);
updateLegacy();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
index 7a34b6e..cf12e94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
@@ -36,8 +36,8 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
- super.notifyContentUpdated(row);
+ public void onContentUpdated(ExpandableNotificationRow row) {
+ super.onContentUpdated(row);
updateImageTag(row.getStatusBarNotification());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
index 9476eed..20a3d8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
@@ -41,11 +41,11 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
+ public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews(row.getStatusBarNotification());
- super.notifyContentUpdated(row);
+ super.onContentUpdated(row);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 0b9244a..15cca5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -128,8 +128,8 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
- super.notifyContentUpdated(row);
+ public void onContentUpdated(ExpandableNotificationRow row) {
+ super.onContentUpdated(row);
mIsLowPriority = row.isLowPriority();
mTransformLowPriorityTitle = !row.isChildInGroup() && !row.isSummaryWithChildren();
ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 4b08f2b..7eaa290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -36,7 +36,6 @@
import com.android.systemui.util.Assert;
import java.util.HashMap;
-import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
@@ -207,7 +206,8 @@
};
applyRemoteView(result, reInflateFlags, flag, row, redactAmbient,
isNewView, remoteViewClickHandler, callback, entry, privateLayout,
- privateLayout.getContractedChild(),
+ privateLayout.getContractedChild(), privateLayout.getVisibleWrapper(
+ NotificationContentView.VISIBLE_TYPE_CONTRACTED),
runningInflations, applyCallback);
}
@@ -229,7 +229,9 @@
};
applyRemoteView(result, reInflateFlags, flag, row,
redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
- privateLayout, privateLayout.getExpandedChild(), runningInflations,
+ privateLayout, privateLayout.getExpandedChild(),
+ privateLayout.getVisibleWrapper(
+ NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations,
applyCallback);
}
}
@@ -252,7 +254,9 @@
};
applyRemoteView(result, reInflateFlags, flag, row,
redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
- privateLayout, privateLayout.getHeadsUpChild(), runningInflations,
+ privateLayout, privateLayout.getHeadsUpChild(),
+ privateLayout.getVisibleWrapper(
+ NotificationContentView.VISIBLE_TYPE_HEADSUP), runningInflations,
applyCallback);
}
}
@@ -274,8 +278,9 @@
};
applyRemoteView(result, reInflateFlags, flag, row,
redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
- publicLayout, publicLayout.getContractedChild(), runningInflations,
- applyCallback);
+ publicLayout, publicLayout.getContractedChild(),
+ publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED),
+ runningInflations, applyCallback);
}
flag = FLAG_REINFLATE_AMBIENT_VIEW;
@@ -296,7 +301,8 @@
};
applyRemoteView(result, reInflateFlags, flag, row,
redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
- newParent, newParent.getAmbientChild(), runningInflations,
+ newParent, newParent.getAmbientChild(), newParent.getVisibleWrapper(
+ NotificationContentView.VISIBLE_TYPE_AMBIENT), runningInflations,
applyCallback);
}
@@ -316,6 +322,7 @@
RemoteViews.OnClickHandler remoteViewClickHandler,
@Nullable final InflationCallback callback, NotificationData.Entry entry,
NotificationContentView parentLayout, View existingView,
+ NotificationViewWrapper existingWrapper,
final HashMap<Integer, CancellationSignal> runningInflations,
ApplyCallback applyCallback) {
RemoteViews.OnViewAppliedListener listener
@@ -326,6 +333,8 @@
if (isNewView) {
v.setIsRootNamespace(true);
applyCallback.setResultView(v);
+ } else if (existingWrapper != null) {
+ existingWrapper.onReinflated();
}
runningInflations.remove(inflationId);
finishIfDone(result, reInflateFlags, runningInflations, callback, row,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
index 8596cb3..eb211a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification;
import android.content.Context;
-import android.service.notification.StatusBarNotification;
import android.view.View;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -40,11 +39,11 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
+ public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews();
- super.notifyContentUpdated(row);
+ super.onContentUpdated(row);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
index 9631556..f6ee1ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
@@ -70,11 +70,11 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
+ public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews();
- super.notifyContentUpdated(row);
+ super.onContentUpdated(row);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index f0b6b2e..abb4cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -133,11 +133,11 @@
}
@Override
- public void notifyContentUpdated(ExpandableNotificationRow row) {
+ public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveTemplateViews(row.getStatusBarNotification());
- super.notifyContentUpdated(row);
+ super.onContentUpdated(row);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 5cc39cc..4b73613 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -66,6 +66,7 @@
mView = view;
mRow = row;
mDozer = createDozer(ctx);
+ onReinflated();
}
protected NotificationDozeHelper createDozer(Context ctx) {
@@ -92,12 +93,15 @@
* Notifies this wrapper that the content of the view might have changed.
* @param row the row this wrapper is attached to
*/
- public void notifyContentUpdated(ExpandableNotificationRow row) {
+ public void onContentUpdated(ExpandableNotificationRow row) {
mDarkInitialized = false;
- Drawable background = mView.getBackground();
+ }
+
+ public void onReinflated() {
if (shouldClearBackgroundOnReapply()) {
mBackgroundColor = 0;
}
+ Drawable background = mView.getBackground();
if (background instanceof ColorDrawable) {
mBackgroundColor = ((ColorDrawable) background).getColor();
mView.setBackground(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index ff06b5b..b6964a03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -297,7 +297,7 @@
} else {
header.reapply(getContext(), mNotificationHeader);
}
- mNotificationHeaderWrapper.notifyContentUpdated(mContainingNotification);
+ mNotificationHeaderWrapper.onContentUpdated(mContainingNotification);
recreateLowPriorityHeader(builder);
recreateAmbientHeader(builder);
updateHeaderVisibility(false /* animate */);
@@ -316,14 +316,14 @@
mNotificationHeaderAmbient = (ViewGroup) header.apply(getContext(), this);
mNotificationHeaderWrapperAmbient = NotificationViewWrapper.wrap(getContext(),
mNotificationHeaderAmbient, mContainingNotification);
- mNotificationHeaderWrapperAmbient.notifyContentUpdated(mContainingNotification);
+ mNotificationHeaderWrapperAmbient.onContentUpdated(mContainingNotification);
addView(mNotificationHeaderAmbient, 0);
invalidate();
} else {
header.reapply(getContext(), mNotificationHeaderAmbient);
}
resetHeaderVisibilityIfNeeded(mNotificationHeaderAmbient, calculateDesiredHeader());
- mNotificationHeaderWrapperAmbient.notifyContentUpdated(mContainingNotification);
+ mNotificationHeaderWrapperAmbient.onContentUpdated(mContainingNotification);
}
/**
@@ -354,7 +354,7 @@
} else {
header.reapply(getContext(), mNotificationHeaderLowPriority);
}
- mNotificationHeaderWrapperLowPriority.notifyContentUpdated(mContainingNotification);
+ mNotificationHeaderWrapperLowPriority.onContentUpdated(mContainingNotification);
resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, calculateDesiredHeader());
} else {
removeView(mNotificationHeaderLowPriority);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index d44f845..2e547e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -95,4 +95,11 @@
row.setHideSensitive(true, false, 0, 0);
verify(row).updateShelfIconColor();
}
+
+ @Test
+ public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
+ ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
+ row.setDark(true, false, 0);
+ verify(row).updateShelfIconColor();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index fc9b608..917a9f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -53,11 +53,14 @@
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.custom_view_dark);
View v = views.apply(mContext, null);
NotificationViewWrapper wrap = NotificationCustomViewWrapper.wrap(mContext, v, mRow);
- wrap.notifyContentUpdated(mRow);
- Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+ wrap.onContentUpdated(mRow);
+ Assert.assertTrue("No background set, when applying custom background view",
+ wrap.getCustomBackgroundColor() != 0);
views.reapply(mContext, v);
- wrap.notifyContentUpdated(mRow);
- Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+ wrap.onReinflated();
+ wrap.onContentUpdated(mRow);
+ Assert.assertTrue("Reapplying a custom remote view lost it's background!",
+ wrap.getCustomBackgroundColor() != 0);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
index ebeb24c8..9da28a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
@@ -24,6 +24,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
import org.junit.Before;
import org.junit.Test;
@@ -35,7 +36,9 @@
@Test
public void constructor_doesntUseViewContext() throws Exception {
- new TestableNotificationViewWrapper(mContext, null /* view */, null /* row */);
+ new TestableNotificationViewWrapper(mContext,
+ new View(mContext),
+ new NotificationTestHelper(getContext()).createRow());
}
static class TestableNotificationViewWrapper extends NotificationViewWrapper {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f3ecfeb..c958313 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19158,10 +19158,11 @@
final Uri data = intent.getData();
final String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
- final ApplicationInfo aInfo =
- getPackageManagerInternalLocked().getApplicationInfo(
- ssp,
- userId);
+ ApplicationInfo aInfo = null;
+ try {
+ aInfo = AppGlobals.getPackageManager()
+ .getApplicationInfo(ssp, 0 /*flags*/, userId);
+ } catch (RemoteException ignore) {}
if (aInfo == null) {
Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
+ " ssp=" + ssp + " data=" + data);
@@ -24281,7 +24282,6 @@
}
void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
- final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
final boolean updateFrameworkRes = packagesToUpdate.contains("android");
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mLruProcesses.get(i);
@@ -24298,8 +24298,8 @@
final String packageName = app.pkgList.keyAt(j);
if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
try {
- final ApplicationInfo ai = packageManager.getApplicationInfo(
- packageName, app.userId);
+ final ApplicationInfo ai = AppGlobals.getPackageManager()
+ .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
if (ai != null) {
app.thread.scheduleApplicationInfoChanged(ai);
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 4b71cc1..3f825c5 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -859,23 +859,16 @@
ipServingMode = IControlsTethering.STATE_LOCAL_ONLY;
break;
default:
- // Resort to legacy "guessing" behaviour.
- //
- // When the AP comes up and we've been requested to tether it,
- // do so. Otherwise, assume it's a local-only hotspot request.
- //
- // TODO: Once all AP broadcasts are known to include ifname and
- // mode information delete this code path and log an error.
- ipServingMode = mWifiTetherRequested
- ? IControlsTethering.STATE_TETHERED
- : IControlsTethering.STATE_LOCAL_ONLY;
- break;
+ mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
+ return;
}
if (!TextUtils.isEmpty(ifname)) {
changeInterfaceState(ifname, ipServingMode);
} else {
- tetherMatchingInterfaces(ipServingMode, ConnectivityManager.TETHERING_WIFI);
+ mLog.e(String.format(
+ "Cannot enable IP serving in mode %s on missing interface name",
+ ipServingMode));
}
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 6941193..e87d860 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -77,6 +77,9 @@
public TetheringConfiguration(Context ctx) {
tetherableUsbRegexs = ctx.getResources().getStringArray(
com.android.internal.R.array.config_tether_usb_regexs);
+ // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
+ // us an interface name. Careful consideration needs to be given to
+ // implications for Settings and for provisioning checks.
tetherableWifiRegexs = ctx.getResources().getStringArray(
com.android.internal.R.array.config_tether_wifi_regexs);
tetherableBluetoothRegexs = ctx.getResources().getStringArray(
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 29f9f7c..4a5ce12 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -34,6 +34,7 @@
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
@@ -100,7 +101,6 @@
private static final boolean DEBUG = false;
private static final String TAG = "LauncherAppsService";
private final Context mContext;
- private final PackageManager mPm;
private final UserManager mUm;
private final ActivityManagerInternal mActivityManagerInternal;
private final ShortcutServiceInternal mShortcutServiceInternal;
@@ -113,7 +113,6 @@
public LauncherAppsImpl(Context context) {
mContext = context;
- mPm = mContext.getPackageManager();
mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mActivityManagerInternal = Preconditions.checkNotNull(
LocalServices.getService(ActivityManagerInternal.class));
@@ -263,15 +262,17 @@
void verifyCallingPackage(String callingPackage) {
int packageUid = -1;
try {
- packageUid = mPm.getPackageUidAsUser(callingPackage,
+ packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_UNINSTALLED_PACKAGES,
UserHandle.getUserId(getCallingUid()));
- } catch (NameNotFoundException e) {
+ } catch (RemoteException ignore) {
+ }
+ if (packageUid < 0) {
Log.e(TAG, "Package not found: " + callingPackage);
}
- if (packageUid != Binder.getCallingUid()) {
+ if (packageUid != injectBinderCallingUid()) {
throw new SecurityException("Calling package name mismatch");
}
}
@@ -315,13 +316,15 @@
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- return pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ return pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -344,12 +347,15 @@
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = injectClearCallingIdentity();
try {
- List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return new ParceledListSlice<>(apps);
} finally {
injectRestoreCallingIdentity(ident);
@@ -390,13 +396,15 @@
return false;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- PackageInfo info = pm.getPackageInfo(packageName,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ PackageInfo info = pmInt.getPackageInfo(packageName,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return info != null && info.applicationInfo.enabled;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -414,11 +422,13 @@
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ApplicationInfo info = pm.getApplicationInfo(packageName, flags,
- user.getIdentifier());
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
+ callingUid, user.getIdentifier());
return info;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -573,13 +583,15 @@
return false;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ActivityInfo info = pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ActivityInfo info = pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return info != null;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -604,13 +616,15 @@
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.setPackage(component.getPackageName());
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ActivityInfo info = pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ActivityInfo info = pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
if (!info.exported) {
throw new SecurityException("Cannot launch non-exported components "
+ component);
@@ -619,10 +633,10 @@
// Check that the component actually has Intent.CATEGORY_LAUCNCHER
// as calling startActivityAsUser ignores the category and just
// resolves based on the component if present.
- List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
+ List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
final int size = apps.size();
for (int i = 0; i < size; ++i) {
ActivityInfo activityInfo = apps.get(i).activityInfo;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index aad7df3..e62b107 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2186,12 +2186,12 @@
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
String[] grantedPermissions) {
- SettingBase sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
+ PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null) {
return;
}
- PermissionsState permissionsState = sb.getPermissionsState();
+ PermissionsState permissionsState = ps.getPermissionsState();
final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -3516,7 +3516,7 @@
* and {@code 0}</li>
* <li>The calling application has the permission
* {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
- * <li>[TODO] The calling application is the default launcher on the
+ * <li>The calling application is the default launcher on the
* system partition.</li>
* </ol>
*/
@@ -3651,22 +3651,27 @@
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
- flags, userId);
+ flags, Binder.getCallingUid(), userId);
}
@Override
public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
int flags, int userId) {
return getPackageInfoInternal(versionedPackage.getPackageName(),
- versionedPackage.getVersionCode(), flags, userId);
+ versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
}
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out packages
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
- int flags, int userId) {
+ int flags, int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
- final int callingUid = Binder.getCallingUid();
flags = updateFlagsForPackage(flags, userId, packageName);
- enforceCrossUserPermission(callingUid, userId,
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get package info");
// reader
@@ -3678,10 +3683,10 @@
if (matchFactoryOnly) {
final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
if (ps != null) {
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, callingUid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
@@ -3696,10 +3701,10 @@
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
final PackageSetting ps = (PackageSetting) p.mExtras;
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
+ if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
@@ -3707,10 +3712,10 @@
if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) return null;
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, callingUid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
@@ -4071,14 +4076,14 @@
}
private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
- int uid, int userId) {
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
- if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, uid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
if (ps.pkg == null) {
@@ -4101,6 +4106,17 @@
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+ return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
+ }
+
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out applications
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
+ private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForApplication(flags, userId, packageName);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
@@ -4119,10 +4135,10 @@
if (p != null) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) return null;
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
// Note: isEnabledLP() does not apply here - always return info
@@ -4140,7 +4156,7 @@
if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
// Already generates the external package name
return generateApplicationInfoFromSettingsLPw(packageName,
- Binder.getCallingUid(), flags, userId);
+ flags, filterCallingUid, userId);
}
}
return null;
@@ -4570,10 +4586,20 @@
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+ return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
+ }
+
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out activities
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
+ private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
- final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId, component);
- enforceCrossUserPermission(callingUid, userId,
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -4582,7 +4608,7 @@
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
- if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
return null;
}
return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
@@ -4878,9 +4904,13 @@
}
}
- private void updateSequenceNumberLP(String packageName, int[] userList) {
+ private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
for (int i = userList.length - 1; i >= 0; --i) {
final int userId = userList[i];
+ // don't add instant app to the list of updates
+ if (pkgSetting.getInstantApp(userId)) {
+ continue;
+ }
SparseArray<String> changedPackages = mChangedPackages.get(userId);
if (changedPackages == null) {
changedPackages = new SparseArray<>();
@@ -4891,12 +4921,12 @@
sequenceNumbers = new HashMap<>();
mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
}
- final Integer sequenceNumber = sequenceNumbers.get(packageName);
+ final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
if (sequenceNumber != null) {
changedPackages.remove(sequenceNumber);
}
- changedPackages.put(mChangedPackagesSequenceNumber, packageName);
- sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
+ changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
+ sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
}
mChangedPackagesSequenceNumber++;
}
@@ -5338,7 +5368,7 @@
"grantRuntimePermission");
final int uid;
- final SettingBase sb;
+ final PackageSetting ps;
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
@@ -5349,12 +5379,9 @@
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
}
- sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
- if (sb instanceof PackageSetting
- && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
+ ps = (PackageSetting) pkg.mExtras;
+ if (ps == null
+ || filterAppAccessLPr(ps, callingUid, userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -5372,7 +5399,7 @@
uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
- final PermissionsState permissionsState = sb.getPermissionsState();
+ final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(name, userId);
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5394,7 +5421,6 @@
return;
}
- final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps.getInstantApp(userId) && !bp.isInstant()) {
throw new SecurityException("Cannot grant non-ephemeral permission"
+ name + " for package " + packageName);
@@ -5478,7 +5504,11 @@
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
-
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null
+ || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
@@ -5496,12 +5526,7 @@
return;
}
- SettingBase sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
-
- final PermissionsState permissionsState = sb.getPermissionsState();
+ final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(name, userId);
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5654,15 +5679,12 @@
if (bp == null) {
return 0;
}
- final SettingBase sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null
+ || filterAppAccessLPr(ps, callingUid, userId)) {
return 0;
}
- if (sb instanceof PackageSetting
- && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
- return 0;
- }
- PermissionsState permissionsState = sb.getPermissionsState();
+ PermissionsState permissionsState = ps.getPermissionsState();
return permissionsState.getPermissionFlags(name, userId);
}
}
@@ -5676,7 +5698,8 @@
enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"updatePermissionFlags");
@@ -5694,18 +5717,18 @@
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null
+ || filterAppAccessLPr(ps, callingUid, userId)) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
}
- SettingBase sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
-
- PermissionsState permissionsState = sb.getPermissionsState();
+ PermissionsState permissionsState = ps.getPermissionsState();
boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
@@ -5749,11 +5772,11 @@
final int packageCount = mPackages.size();
for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
- SettingBase sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null) {
continue;
}
- PermissionsState permissionsState = sb.getPermissionsState();
+ PermissionsState permissionsState = ps.getPermissionsState();
changed |= permissionsState.updatePermissionFlagsForAllPermissions(
userId, flagMask, flagValues);
}
@@ -6303,7 +6326,7 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId, resolveForStart);
+ flags, callingUid, userId, resolveForStart);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
@@ -6847,15 +6870,16 @@
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
- return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
+ return queryIntentActivitiesInternal(
+ intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
}
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
- String resolvedType, int flags, int userId, boolean resolveForStart) {
+ String resolvedType, int flags, int filterCallingUid, int userId,
+ boolean resolveForStart) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- final int callingUid = Binder.getCallingUid();
- final String instantAppPkgName = getInstantAppPackageName(callingUid);
- enforceCrossUserPermission(callingUid, userId,
+ final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */,
"query intent activities");
final String pkgName = intent.getPackage();
@@ -6867,7 +6891,7 @@
}
}
- flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
+ flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
comp != null || pkgName != null /*onlyExposedExplicitly*/);
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
@@ -9546,6 +9570,8 @@
public void reconcileSecondaryDexFiles(String packageName) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return;
+ } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+ return;
}
mDexManager.reconcileSecondaryDexFiles(packageName);
}
@@ -14323,8 +14349,8 @@
int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
PackageSetting pkgSetting;
- final int uid = Binder.getCallingUid();
- enforceCrossUserPermission(uid, userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"setApplicationHiddenSetting for user " + userId);
@@ -14343,6 +14369,9 @@
if (pkgSetting == null) {
return false;
}
+ if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
+ return false;
+ }
// Do not allow "android" is being disabled
if ("android".equals(packageName)) {
Slog.w(TAG, "Cannot hide package: android");
@@ -14359,7 +14388,7 @@
return false;
}
// Only allow protected packages to hide themselves.
- if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
+ if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
&& mProtectedPackages.isPackageStateProtected(userId, packageName)) {
Slog.w(TAG, "Not hiding protected package: " + packageName);
return false;
@@ -14476,6 +14505,20 @@
if (pkgSetting == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
+ if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
+ // only allow the existing package to be used if it's installed as a full
+ // application for at least one user
+ boolean installAllowed = false;
+ for (int checkUserId : sUserManager.getUserIds()) {
+ installAllowed = !pkgSetting.getInstantApp(checkUserId);
+ if (installAllowed) {
+ break;
+ }
+ }
+ if (!installAllowed) {
+ return PackageManager.INSTALL_FAILED_INVALID_URI;
+ }
+ }
if (!pkgSetting.getInstalled(userId)) {
pkgSetting.setInstalled(true, userId);
pkgSetting.setHidden(false, userId);
@@ -14499,7 +14542,7 @@
}
sendPackageAddedForUser(packageName, pkgSetting, userId);
synchronized (mPackages) {
- updateSequenceNumberLP(packageName, new int[]{ userId });
+ updateSequenceNumberLP(pkgSetting, new int[]{ userId });
}
}
} finally {
@@ -14545,7 +14588,8 @@
public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"setPackagesSuspended for user " + userId);
@@ -14566,7 +14610,8 @@
final int appId;
synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
- if (pkgSetting == null) {
+ if (pkgSetting == null
+ || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
Slog.w(TAG, "Could not find package setting for package \"" + packageName
+ "\". Skipping suspending/un-suspending.");
unactionedPackages.add(packageName);
@@ -14976,6 +15021,10 @@
boolean result = false;
synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
+ return false;
+ }
result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
}
if (result) {
@@ -15076,7 +15125,9 @@
// writer
synchronized (mPackages) {
PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
- if (targetPackageSetting == null) {
+ if (targetPackageSetting == null
+ || filterAppAccessLPr(
+ targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
throw new IllegalArgumentException("Unknown target package: " + targetPackage);
}
@@ -15157,7 +15208,9 @@
if (ps == null) {
throw new IllegalArgumentException("Unknown target package " + packageName);
}
-
+ if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
+ throw new IllegalArgumentException("Unknown target package " + packageName);
+ }
if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
throw new IllegalArgumentException("Calling package " + callerPackageName
+ " is not installer for " + packageName);
@@ -18178,7 +18231,7 @@
}
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
- updateSequenceNumberLP(pkgName, res.newUsers);
+ updateSequenceNumberLP(ps, res.newUsers);
updateInstantAppInstallerLocked(pkgName);
}
}
@@ -18404,8 +18457,7 @@
final int callingUid = Binder.getCallingUid();
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
- final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_INSTANT_APPS);
+ final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
Preconditions.checkNotNull(versionedPackage);
Preconditions.checkNotNull(observer);
Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
@@ -18476,7 +18528,7 @@
final boolean targetIsInstantApp =
ps.getInstantApp(UserHandle.getUserId(callingUid));
doDeletePackage = !targetIsInstantApp
- || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
+ || canViewInstantApps;
}
if (doDeletePackage) {
if (!deleteAllUsers) {
@@ -18779,7 +18831,7 @@
if (pkg != null) {
mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
}
- updateSequenceNumberLP(packageName, info.removedUsers);
+ updateSequenceNumberLP(uninstalledPs, info.removedUsers);
updateInstantAppInstallerLocked(packageName);
}
}
@@ -21135,7 +21187,8 @@
// Limit who can change which apps
if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
// Don't allow apps that don't have permission to modify other apps
- if (!allowedByPermission) {
+ if (!allowedByPermission
+ || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
throw new SecurityException(
"Attempt to change component state; "
+ "pid=" + Binder.getCallingPid()
@@ -21222,7 +21275,7 @@
}
}
scheduleWritePackageRestrictionsLocked(userId);
- updateSequenceNumberLP(packageName, new int[] { userId });
+ updateSequenceNumberLP(pkgSetting, new int[] { userId });
final long callingId = Binder.clearCallingIdentity();
try {
updateInstantAppInstallerLocked(packageName);
@@ -21319,8 +21372,10 @@
true /* requireFullPermission */, true /* checkShell */, "stop package");
// writer
synchronized (mPackages) {
- if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
- allowedByPermission, callingUid, userId)) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (!filterAppAccessLPr(ps, callingUid, userId)
+ && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
+ allowedByPermission, callingUid, userId)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
@@ -21328,11 +21383,16 @@
@Override
public String getInstallerPackageName(String packageName) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return null;
}
// reader
synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return null;
+ }
return mSettings.getInstallerPackageNameLPr(packageName);
}
}
@@ -24081,7 +24141,8 @@
@Override
public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return false;
}
if (packageName == null || ks == null) {
@@ -24089,7 +24150,9 @@
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null) {
+ if (pkg == null
+ || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
+ UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -24104,7 +24167,8 @@
@Override
public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return false;
}
if (packageName == null || ks == null) {
@@ -24112,7 +24176,9 @@
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null) {
+ if (pkg == null
+ || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
+ UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -24429,8 +24495,34 @@
}
@Override
- public ApplicationInfo getApplicationInfo(String packageName, int userId) {
- return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
+ public PackageInfo getPackageInfo(
+ String packageName, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
+ flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public ApplicationInfo getApplicationInfo(
+ String packageName, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public ActivityInfo getActivityInfo(
+ ComponentName component, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getActivityInfoInternal(component, flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public List<ResolveInfo> queryIntentActivities(
+ Intent intent, int flags, int filterCallingUid, int userId) {
+ final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
+ return PackageManagerService.this
+ .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
+ userId, false /*resolveForStart*/);
}
@Override
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
index 7d53310..3e5e57b 100644
--- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
+++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
@@ -233,7 +233,7 @@
private AccessibilityServiceInfo getInfoForTargetService() {
final String currentShortcutServiceString = getTargetServiceComponentNameString(
- mContext, UserHandle.myUserId());
+ mContext, UserHandle.USER_CURRENT);
if (currentShortcutServiceString == null) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a8e0d76..ccc8f63 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1162,8 +1162,6 @@
final int dh = displayInfo.logicalHeight;
config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
Configuration.ORIENTATION_LANDSCAPE;
- config.setRotation(displayInfo.rotation);
-
config.screenWidthDp =
(int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
config.uiMode, mDisplayId) / mDisplayMetrics.density);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fb500bc..233e75b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -858,20 +858,14 @@
final int privateflags = attrs.privateFlags;
boolean displayHasContent = false;
- if (DEBUG_KEEP_SCREEN_ON && (attrFlags & FLAG_KEEP_SCREEN_ON) != 0
- && w != mService.mLastWakeLockHoldingWindow) {
- Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w
- + " has FLAG_KEEP_SCREEN_ON set, hasSurface=" + w.mHasSurface
- + ", canBeSeen=" + canBeSeen);
- }
-
if (w.mHasSurface && canBeSeen) {
if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
mHoldScreen = w.mSession;
mHoldScreenWindow = w;
} else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
- + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!!");
+ + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
+ + Debug.getCallers(10));
}
if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
mScreenBrightness = w.mAttrs.screenBrightness;
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 4da9c06..6d5673e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -77,5 +77,5 @@
static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
- static final boolean DEBUG_KEEP_SCREEN_ON = true;
+ static final boolean DEBUG_KEEP_SCREEN_ON = false;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4b066c0..e5af9d2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -158,6 +158,7 @@
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
+import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -3600,8 +3601,16 @@
// only allow disables from pids which have count on, etc.
@Override
public void showStrictModeViolation(boolean on) {
- int pid = Binder.getCallingPid();
- mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
+ final int pid = Binder.getCallingPid();
+ if (on) {
+ // Show the visualization, and enqueue a second message to tear it
+ // down if we don't hear back from the app.
+ mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid));
+ mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid),
+ DateUtils.SECOND_IN_MILLIS);
+ } else {
+ mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid));
+ }
}
private void showStrictModeViolation(int arg, int pid) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1d08c2e..f74948f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2231,14 +2231,15 @@
mWinAnimator.applyEnterAnimationLocked();
}
- // always report back the new configuration
- final Configuration globalConfig = mService.mRoot.getConfiguration();
- final Configuration overrideConfig = getMergedOverrideConfiguration();
- mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
- if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
- + " reporting new global config: " + globalConfig
- + " merged override config: " + overrideConfig);
- mLastReportedConfiguration.setTo(getConfiguration());
+ if (isConfigChanged()) {
+ final Configuration globalConfig = mService.mRoot.getConfiguration();
+ final Configuration overrideConfig = getMergedOverrideConfiguration();
+ mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
+ if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
+ + " visible with new global config: " + globalConfig
+ + " merged override config: " + overrideConfig);
+ mLastReportedConfiguration.setTo(getConfiguration());
+ }
}
void adjustStartingWindowFlags() {
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 50d7f04..281223e 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -219,10 +219,7 @@
mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception {
- if (!ifnameKnown) {
- verify(mNMService, times(1)).listInterfaces();
- }
+ private void verifyInterfaceServingModeStarted() throws Exception {
verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
verify(mNMService, times(1))
.setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
@@ -238,21 +235,36 @@
mIntents.remove(bcast);
}
- public void workingLocalOnlyHotspot(boolean enrichedApBroadcast) throws Exception {
+ @Test
+ public void failingLocalOnlyHotspotLegacyApBroadcast() throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
// Emulate externally-visible WifiManager effects, causing the
// per-interface state machine to start up, and telling us that
// hotspot mode is to be started.
mTethering.interfaceStatusChanged(mTestIfname, true);
- if (enrichedApBroadcast) {
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY);
- } else {
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
- }
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
mLooper.dispatchAll();
- verifyInterfaceServingModeStarted(enrichedApBroadcast);
+ verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+ verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+ verifyNoMoreInteractions(mConnectivityManager);
+ verifyNoMoreInteractions(mNMService);
+ verifyNoMoreInteractions(mWifiManager);
+ }
+
+ @Test
+ public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception {
+ when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+
+ // Emulate externally-visible WifiManager effects, causing the
+ // per-interface state machine to start up, and telling us that
+ // hotspot mode is to be started.
+ mTethering.interfaceStatusChanged(mTestIfname, true);
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY);
+ mLooper.dispatchAll();
+
+ verifyInterfaceServingModeStarted();
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -293,16 +305,7 @@
}
@Test
- public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception {
- workingLocalOnlyHotspot(false);
- }
-
- @Test
- public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception {
- workingLocalOnlyHotspot(true);
- }
-
- public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception {
+ public void failingWifiTetheringLegacyApBroadcast() throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
@@ -318,14 +321,37 @@
// per-interface state machine to start up, and telling us that
// tethering mode is to be started.
mTethering.interfaceStatusChanged(mTestIfname, true);
- if (enrichedApBroadcast) {
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
- } else {
- sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
- }
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
mLooper.dispatchAll();
- verifyInterfaceServingModeStarted(enrichedApBroadcast);
+ verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+ verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+ verifyNoMoreInteractions(mConnectivityManager);
+ verifyNoMoreInteractions(mNMService);
+ verifyNoMoreInteractions(mWifiManager);
+ }
+
+ @Test
+ public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
+ when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+ when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
+
+ // Emulate pressing the WiFi tethering button.
+ mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+ mLooper.dispatchAll();
+ verify(mWifiManager, times(1)).startSoftAp(null);
+ verifyNoMoreInteractions(mWifiManager);
+ verifyNoMoreInteractions(mConnectivityManager);
+ verifyNoMoreInteractions(mNMService);
+
+ // Emulate externally-visible WifiManager effects, causing the
+ // per-interface state machine to start up, and telling us that
+ // tethering mode is to be started.
+ mTethering.interfaceStatusChanged(mTestIfname, true);
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
+ mLooper.dispatchAll();
+
+ verifyInterfaceServingModeStarted();
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -387,16 +413,6 @@
}
@Test
- public void workingWifiTetheringLegacyApBroadcast() throws Exception {
- workingWifiTethering(false);
- }
-
- @Test
- public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
- workingWifiTethering(true);
- }
-
- @Test
public void failureEnablingIpForwarding() throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
@@ -414,11 +430,9 @@
// per-interface state machine to start up, and telling us that
// tethering mode is to be started.
mTethering.interfaceStatusChanged(mTestIfname, true);
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
- // Activity caused by test_wlan0 becoming available.
- verify(mNMService, times(1)).listInterfaces();
// We verify get/set called twice here: once for setup and once during
// teardown because all events happen over the course of the single
// dispatchAll() above.