Merge "Add READ_DEVICE_CONFIG permission to SystemUI to allow access to DeviceConfig API. Permission checks in DeviceConfig API will be added later."
diff --git a/api/current.txt b/api/current.txt
index da8790b..12b4d4b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5421,14 +5421,14 @@
ctor @Deprecated public Notification.Action.Builder(int, CharSequence, android.app.PendingIntent);
ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, android.app.PendingIntent);
ctor public Notification.Action.Builder(android.app.Notification.Action);
- method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
- method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
- method public android.app.Notification.Action build();
- method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender);
+ method @NonNull public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
+ method @NonNull public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
+ method @NonNull public android.app.Notification.Action build();
+ method @NonNull public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender);
method public android.os.Bundle getExtras();
- method public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean);
- method public android.app.Notification.Action.Builder setContextual(boolean);
- method public android.app.Notification.Action.Builder setSemanticAction(int);
+ method @NonNull public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean);
+ method @NonNull public android.app.Notification.Action.Builder setContextual(boolean);
+ method @NonNull public android.app.Notification.Action.Builder setSemanticAction(int);
}
public static interface Notification.Action.Extender {
@@ -11825,15 +11825,15 @@
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- ctor public PermissionGroupInfo();
- ctor public PermissionGroupInfo(android.content.pm.PermissionGroupInfo);
+ ctor @Deprecated public PermissionGroupInfo();
+ ctor @Deprecated public PermissionGroupInfo(@NonNull android.content.pm.PermissionGroupInfo);
method public int describeContents();
- method public CharSequence loadDescription(android.content.pm.PackageManager);
+ method @Nullable public CharSequence loadDescription(@NonNull android.content.pm.PackageManager);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.PermissionGroupInfo> CREATOR;
field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
- field public int descriptionRes;
+ field @StringRes public int descriptionRes;
field public int flags;
- field public CharSequence nonLocalizedDescription;
+ field @Nullable public CharSequence nonLocalizedDescription;
field public int priority;
}
@@ -14113,14 +14113,14 @@
public class HardwareRenderer {
ctor public HardwareRenderer();
method public void clearContent();
- method public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest();
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest();
method public void destroy();
method public boolean isOpaque();
method public void notifyFramePending();
method public void setContentRoot(@Nullable android.graphics.RenderNode);
method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
method public void setLightSourceGeometry(float, float, float, float);
- method public void setName(String);
+ method public void setName(@NonNull String);
method public void setOpaque(boolean);
method public void setStopped(boolean);
method public void setSurface(@Nullable android.view.Surface);
@@ -14132,9 +14132,9 @@
}
public final class HardwareRenderer.FrameRenderRequest {
- method public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable);
- method public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long);
- method public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean);
method public int syncAndDraw();
}
@@ -14953,8 +14953,8 @@
public final class RenderNode {
ctor public RenderNode(@Nullable String);
- method public android.graphics.RecordingCanvas beginRecording(int, int);
- method public android.graphics.RecordingCanvas beginRecording();
+ method @NonNull public android.graphics.RecordingCanvas beginRecording(int, int);
+ method @NonNull public android.graphics.RecordingCanvas beginRecording();
method public long computeApproximateMemoryUsage();
method public void discardDisplayList();
method public void endRecording();
@@ -15007,7 +15007,7 @@
method public boolean setPivotX(float);
method public boolean setPivotY(float);
method public boolean setPosition(int, int, int, int);
- method public boolean setPosition(android.graphics.Rect);
+ method public boolean setPosition(@NonNull android.graphics.Rect);
method public boolean setProjectBackwards(boolean);
method public boolean setProjectionReceiver(boolean);
method public boolean setRotationX(float);
@@ -15446,38 +15446,38 @@
method public float getGradientCenterY();
method public float getGradientRadius();
method public int getGradientType();
- method public int getInnerRadius();
+ method @Px public int getInnerRadius();
method public float getInnerRadiusRatio();
method public int getOpacity();
method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
method public int getShape();
- method public int getThickness();
+ method @Px public int getThickness();
method public float getThicknessRatio();
method public boolean getUseLevel();
method public void setAlpha(int);
method public void setColor(@ColorInt int);
method public void setColor(@Nullable android.content.res.ColorStateList);
method public void setColorFilter(@Nullable android.graphics.ColorFilter);
- method public void setColors(@ColorInt int[]);
- method public void setColors(@ColorInt int[], @Nullable float[]);
+ method public void setColors(@Nullable @ColorInt int[]);
+ method public void setColors(@Nullable @ColorInt int[], @Nullable float[]);
method public void setCornerRadii(@Nullable float[]);
method public void setCornerRadius(float);
method public void setDither(boolean);
method public void setGradientCenter(float, float);
method public void setGradientRadius(float);
method public void setGradientType(int);
- method public void setInnerRadius(int);
- method public void setInnerRadiusRatio(float);
+ method public void setInnerRadius(@Px int);
+ method public void setInnerRadiusRatio(@FloatRange(from=0.0f, fromInclusive=false) float);
method public void setOrientation(android.graphics.drawable.GradientDrawable.Orientation);
- method public void setPadding(int, int, int, int);
+ method public void setPadding(@Px int, @Px int, @Px int, @Px int);
method public void setShape(int);
method public void setSize(int, int);
method public void setStroke(int, @ColorInt int);
method public void setStroke(int, android.content.res.ColorStateList);
method public void setStroke(int, @ColorInt int, float, float);
method public void setStroke(int, android.content.res.ColorStateList, float, float);
- method public void setThickness(int);
- method public void setThicknessRatio(float);
+ method public void setThickness(@Px int);
+ method public void setThicknessRatio(@FloatRange(from=0.0f, fromInclusive=false) float);
method public void setUseLevel(boolean);
field public static final int LINE = 2; // 0x2
field public static final int LINEAR_GRADIENT = 0; // 0x0
@@ -15690,10 +15690,10 @@
public class StateListDrawable extends android.graphics.drawable.DrawableContainer {
ctor public StateListDrawable();
method public void addState(int[], android.graphics.drawable.Drawable);
- method public int findStateDrawableIndex(int[]);
+ method public int findStateDrawableIndex(@NonNull int[]);
method public int getStateCount();
- method public android.graphics.drawable.Drawable getStateDrawable(int);
- method public int[] getStateSet(int);
+ method @Nullable public android.graphics.drawable.Drawable getStateDrawable(int);
+ method @NonNull public int[] getStateSet(int);
}
public class TransitionDrawable extends android.graphics.drawable.LayerDrawable implements android.graphics.drawable.Drawable.Callback {
@@ -16562,10 +16562,10 @@
public static class BiometricPrompt.Builder {
ctor public BiometricPrompt.Builder(android.content.Context);
method @NonNull public android.hardware.biometrics.BiometricPrompt build();
- method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setAllowDeviceCredential(boolean);
+ method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setConfirmationRequired(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence);
+ method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDeviceCredentialAllowed(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener);
- method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setRequireConfirmation(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setTitle(@NonNull CharSequence);
}
@@ -22859,6 +22859,7 @@
method public float getBearing();
method public float getBearingAccuracyDegrees();
method public long getElapsedRealtimeNanos();
+ method public long getElapsedRealtimeUncertaintyNanos();
method public android.os.Bundle getExtras();
method public double getLatitude();
method public double getLongitude();
@@ -22871,6 +22872,7 @@
method public boolean hasAltitude();
method public boolean hasBearing();
method public boolean hasBearingAccuracy();
+ method public boolean hasElapsedRealtimeUncertaintyNanos();
method public boolean hasSpeed();
method public boolean hasSpeedAccuracy();
method public boolean hasVerticalAccuracy();
@@ -22886,6 +22888,7 @@
method public void setBearing(float);
method public void setBearingAccuracyDegrees(float);
method public void setElapsedRealtimeNanos(long);
+ method public void setElapsedRealtimeUncertaintyNanos(long);
method public void setExtras(android.os.Bundle);
method public void setLatitude(double);
method public void setLongitude(double);
@@ -56788,7 +56791,7 @@
method public boolean isFillViewport();
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
- method public void scrollToDescendant(android.view.View);
+ method public void scrollToDescendant(@NonNull android.view.View);
method public void setBottomEdgeEffectColor(@ColorInt int);
method public void setEdgeEffectColor(@ColorInt int);
method public void setFillViewport(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 8dedd2c..7cd8c14 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25,6 +25,7 @@
field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE";
field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
+ field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
field public static final String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
@@ -163,6 +164,7 @@
field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD";
field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
+ field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
@@ -1413,7 +1415,7 @@
field public static final String ACTION_PRE_BOOT_COMPLETED = "android.intent.action.PRE_BOOT_COMPLETED";
field public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
field public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
- field public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
+ field @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES) public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = "android.intent.action.REVIEW_APP_PERMISSION_USAGE";
field public static final String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
field public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE";
@@ -1707,9 +1709,9 @@
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- field @StringRes public int backgroundRequestDetailResourceId;
- field @StringRes public int backgroundRequestResourceId;
- field @StringRes public int requestDetailResourceId;
+ field @StringRes public final int backgroundRequestDetailResourceId;
+ field @StringRes public final int backgroundRequestResourceId;
+ field @StringRes public final int requestDetailResourceId;
field @StringRes public int requestRes;
}
@@ -9635,16 +9637,16 @@
public final class WebViewDelegate {
method public void addWebViewAssetPath(android.content.Context);
- method public void callDrawGlFunction(android.graphics.Canvas, long);
- method public void callDrawGlFunction(@NonNull android.graphics.Canvas, long, @Nullable Runnable);
- method public boolean canInvokeDrawGlFunctor(android.view.View);
- method public void detachDrawGlFunctor(android.view.View, long);
+ method @Deprecated public void callDrawGlFunction(android.graphics.Canvas, long);
+ method @Deprecated public void callDrawGlFunction(@NonNull android.graphics.Canvas, long, @Nullable Runnable);
+ method @Deprecated public boolean canInvokeDrawGlFunctor(android.view.View);
+ method @Deprecated public void detachDrawGlFunctor(android.view.View, long);
method public void drawWebViewFunctor(@NonNull android.graphics.Canvas, int);
method public android.app.Application getApplication();
method public String getDataDirectorySuffix();
method public String getErrorString(android.content.Context, int);
method public int getPackageId(android.content.res.Resources, String);
- method public void invokeDrawGlFunctor(android.view.View, long, boolean);
+ method @Deprecated public void invokeDrawGlFunctor(android.view.View, long, boolean);
method public boolean isMultiProcessEnabled();
method public boolean isTraceTagEnabled();
method public void setOnTraceEnabledChangeListener(android.webkit.WebViewDelegate.OnTraceEnabledChangeListener);
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 7d828d8..92db23b 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -276,6 +276,7 @@
public abstract boolean isActivityStartsLoggingEnabled();
/** Returns true if the background activity starts is enabled. */
public abstract boolean isBackgroundActivityStartsEnabled();
+ public abstract boolean isPackageNameWhitelistedForBgActivityStarts(String packageName);
public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
/** Input dispatch timeout to a window, start the ANR process. */
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 17f645d..3ecb587 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -125,7 +125,7 @@
public static final int RESULT_ALTERNATE = 1;
/**
- * @deprecated see {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)}
+ * @deprecated see {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)}
*
* Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
* if enrolled) for the current user of the device. The caller is expected to launch this
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e0cf561..f690f5d 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1629,6 +1629,7 @@
*
* @see Notification.Action#extras
*/
+ @NonNull
public Builder addExtras(Bundle extras) {
if (extras != null) {
mExtras.putAll(extras);
@@ -1652,6 +1653,7 @@
* @param remoteInput a {@link RemoteInput} to add to the action
* @return this object for method chaining
*/
+ @NonNull
public Builder addRemoteInput(RemoteInput remoteInput) {
if (mRemoteInputs == null) {
mRemoteInputs = new ArrayList<RemoteInput>();
@@ -1669,6 +1671,7 @@
* @return this object for method chaining
* The default value is {@code true}
*/
+ @NonNull
public Builder setAllowGeneratedReplies(boolean allowGeneratedReplies) {
mAllowGeneratedReplies = allowGeneratedReplies;
return this;
@@ -1682,6 +1685,7 @@
* {@code SEMANTIC_ACTION_} prefixes
* @return this object for method chaining
*/
+ @NonNull
public Builder setSemanticAction(@SemanticAction int semanticAction) {
mSemanticAction = semanticAction;
return this;
@@ -1692,6 +1696,7 @@
* dependent on the notification message body. An example of a contextual action could
* be an action opening a map application with an address shown in the notification.
*/
+ @NonNull
public Builder setContextual(boolean isContextual) {
mIsContextual = isContextual;
return this;
@@ -1701,6 +1706,7 @@
* Apply an extender to this action builder. Extenders may be used to add
* metadata or change options on this builder.
*/
+ @NonNull
public Builder extend(Extender extender) {
extender.extend(this);
return this;
@@ -1728,6 +1734,7 @@
* object.
* @return the built action
*/
+ @NonNull
public Action build() {
checkContextualActionNullFields();
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index ad614b1..14c58e7 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -23,13 +23,7 @@
"name": "FrameworksServicesTests",
"options": [
{
- "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsServiceTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ "include-filter": "com.android.server.appop"
}
]
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index efbd098..095d014 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10632,18 +10632,18 @@
}
/**
- * Whitelists a set of packages that are allowed to access cross-profile calendar APIs.
+ * Allows a set of packages to access cross-profile calendar APIs.
*
* <p>Called by a profile owner of a managed profile.
*
- * <p>Calling with a null value for the set disables the restriction so that all packages
- * are allowed to access cross-profile calendar APIs. Calling with an empty set disallows
- * all packages from accessing cross-profile calendar APIs. If this method isn't called,
- * no package will be allowed to access cross-profile calendar APIs by default.
+ * <p>Calling with a {@code null} value for the set disables the restriction so that all
+ * packages are allowed to access cross-profile calendar APIs. Calling with an empty set
+ * disallows all packages from accessing cross-profile calendar APIs. If this method isn't
+ * called, no package is allowed to access cross-profile calendar APIs by default.
*
- * @param admin which {@link DeviceAdminReceiver} this request is associated with.
- * @param packageNames set of packages to be whitelisted.
- * @throws SecurityException if {@code admin} is not a profile owner.
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @param packageNames set of packages to be whitelisted
+ * @throws SecurityException if {@code admin} is not a profile owner
*
* @see #getCrossProfileCalendarPackages(ComponentName)
*/
@@ -10661,15 +10661,15 @@
}
/**
- * Gets a set of package names that are whitelisted to access cross-profile calendar APIs.
+ * Gets a set of package names that are allowed to access cross-profile calendar APIs.
*
* <p>Called by a profile owner of a managed profile.
*
- * @param admin which {@link DeviceAdminReceiver} this request is associated with.
- * @return the set of names of packages that were previously whitelisted via
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @return the set of names of packages that were previously allowed via
* {@link #setCrossProfileCalendarPackages(ComponentName, Set)}, or an
- * empty set if none have been whitelisted.
- * @throws SecurityException if {@code admin} is not a profile owner.
+ * empty set if none have been allowed
+ * @throws SecurityException if {@code admin} is not a profile owner
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
*/
@@ -10699,8 +10699,8 @@
* that user, and get a {@link DevicePolicyManager} from this context.
*
* @param packageName the name of the package
- * @return {@code true} if the package is allowed to access cross-profile calendar APIs.
- * {@code false} otherwise.
+ * @return {@code true} if the package is allowed to access cross-profile calendar APIs,
+ * {@code false} otherwise
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
* @see #getCrossProfileCalendarPackages(ComponentName)
@@ -10720,15 +10720,15 @@
}
/**
- * Gets a set of package names that are whitelisted to access cross-profile calendar APIs.
+ * Gets a set of package names that are allowed to access cross-profile calendar APIs.
*
* <p>To query for a specific user, use
* {@link Context#createPackageContextAsUser(String, int, UserHandle)} to create a context for
* that user, and get a {@link DevicePolicyManager} from this context.
*
- * @return the set of names of packages that were previously whitelisted via
+ * @return the set of names of packages that were previously allowed via
* {@link #setCrossProfileCalendarPackages(ComponentName, Set)}, or an
- * empty set if none have been whitelisted.
+ * empty set if none have been allowed
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
* @see #getCrossProfileCalendarPackages(ComponentName)
@@ -10820,12 +10820,12 @@
/**
* Starts an activity to view calendar events in the managed profile.
*
- * @param eventId the id of the event to be viewed.
- * @param start the start time of the event.
- * @param end the end time of the event.
- * @param allDay if the event is an all-day event.
+ * @param eventId the id of the event to be viewed
+ * @param start the start time of the event
+ * @param end the end time of the event
+ * @param allDay if the event is an all-day event
* @param flags flags to be set for the intent
- * @return {@code true} if the activity is started successfully. {@code false} otherwise.
+ * @return {@code true} if the activity is started successfully, {@code false} otherwise
*
* @see CalendarContract#startViewCalendarEventInManagedProfile(Context, String, long, long,
* long, boolean, int)
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d3b8e29..0715572 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2124,6 +2124,7 @@
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES)
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES =
"android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a006f23..e516ed6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -45,6 +45,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringRes;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityTaskManager;
@@ -3260,10 +3261,21 @@
private boolean parsePermissionGroup(Package owner, int flags, Resources res,
XmlResourceParser parser, String[] outError)
throws XmlPullParserException, IOException {
- PermissionGroup perm = new PermissionGroup(owner);
-
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestPermissionGroup);
+
+ int requestDetailResourceId = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
+ int backgroundRequestResourceId = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
+ 0);
+ int backgroundRequestDetailResourceId = sa.getResourceId(
+ com.android.internal.R.styleable
+ .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
+
+ PermissionGroup perm = new PermissionGroup(owner, requestDetailResourceId,
+ backgroundRequestResourceId, backgroundRequestDetailResourceId);
+
if (!parsePackageItemInfo(owner, perm.info, outError,
"<permission-group>", sa, true /*nameRequired*/,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
@@ -3282,14 +3294,6 @@
0);
perm.info.requestRes = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_request, 0);
- perm.info.requestDetailResourceId = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
- perm.info.backgroundRequestResourceId = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
- 0);
- perm.info.backgroundRequestDetailResourceId = sa.getResourceId(
- com.android.internal.R.styleable
- .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
perm.info.flags = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
perm.info.priority = sa.getInt(
@@ -7676,9 +7680,12 @@
@UnsupportedAppUsage
public final PermissionGroupInfo info;
- public PermissionGroup(Package _owner) {
- super(_owner);
- info = new PermissionGroupInfo();
+ public PermissionGroup(Package owner, @StringRes int requestDetailResourceId,
+ @StringRes int backgroundRequestResourceId,
+ @StringRes int backgroundRequestDetailResourceId) {
+ super(owner);
+ info = new PermissionGroupInfo(requestDetailResourceId, backgroundRequestResourceId,
+ backgroundRequestDetailResourceId);
}
public PermissionGroup(Package _owner, PermissionGroupInfo _info) {
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 3a87eca..e65e742 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -16,12 +16,20 @@
package android.content.pm;
+import static android.content.res.Resources.ID_NULL;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Information you can retrieve about a particular security permission
* group known to the system. This corresponds to information collected from the
@@ -33,7 +41,7 @@
* permission's description. From the "description" attribute or,
* if not set, 0.
*/
- public int descriptionRes;
+ public @StringRes int descriptionRes;
/**
* A string resource identifier (in the package's resources) used to request the permissions.
@@ -54,7 +62,7 @@
* @hide
*/
@SystemApi
- public @StringRes int requestDetailResourceId;
+ public final @StringRes int requestDetailResourceId;
/**
* A string resource identifier (in the package's resources) used when requesting background
@@ -66,7 +74,7 @@
* @hide
*/
@SystemApi
- public @StringRes int backgroundRequestResourceId;
+ public final @StringRes int backgroundRequestResourceId;
/**
* A string resource identifier (in the package's resources) used as subtitle when requesting
@@ -78,7 +86,7 @@
* @hide
*/
@SystemApi
- public @StringRes int backgroundRequestDetailResourceId;
+ public final @StringRes int backgroundRequestDetailResourceId;
/**
* The description string provided in the AndroidManifest file, if any. You
@@ -86,7 +94,7 @@
* is in a resource. You probably want
* {@link PermissionInfo#loadDescription} instead.
*/
- public CharSequence nonLocalizedDescription;
+ public @Nullable CharSequence nonLocalizedDescription;
/**
* Flag for {@link #flags}, corresponding to <code>personalInfo</code>
@@ -94,21 +102,48 @@
*/
public static final int FLAG_PERSONAL_INFO = 1<<0;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ FLAG_PERSONAL_INFO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Flags {}
+
/**
* Additional flags about this group as given by
* {@link android.R.attr#permissionGroupFlags}.
*/
- public int flags;
+ public @Flags int flags;
/**
* Prioritization of this group, for visually sorting with other groups.
*/
public int priority;
- public PermissionGroupInfo() {
+ /**
+ * @hide
+ */
+ public PermissionGroupInfo(@StringRes int requestDetailResourceId,
+ @StringRes int backgroundRequestResourceId,
+ @StringRes int backgroundRequestDetailResourceId) {
+ this.requestDetailResourceId = requestDetailResourceId;
+ this.backgroundRequestResourceId = backgroundRequestResourceId;
+ this.backgroundRequestDetailResourceId = backgroundRequestDetailResourceId;
}
- public PermissionGroupInfo(PermissionGroupInfo orig) {
+ /**
+ * @deprecated Should only be created by the system.
+ */
+ @Deprecated
+ public PermissionGroupInfo() {
+ this(ID_NULL, ID_NULL, ID_NULL);
+ }
+
+ /**
+ * @deprecated Should only be created by the system.
+ */
+ @Deprecated
+ public PermissionGroupInfo(@NonNull PermissionGroupInfo orig) {
super(orig);
descriptionRes = orig.descriptionRes;
requestRes = orig.requestRes;
@@ -131,7 +166,7 @@
* @return Returns a CharSequence containing the permission's description.
* If there is no description, null is returned.
*/
- public CharSequence loadDescription(PackageManager pm) {
+ public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) {
if (nonLocalizedDescription != null) {
return nonLocalizedDescription;
}
@@ -166,7 +201,7 @@
dest.writeInt(priority);
}
- public static final @android.annotation.NonNull Creator<PermissionGroupInfo> CREATOR =
+ public static final @NonNull Creator<PermissionGroupInfo> CREATOR =
new Creator<PermissionGroupInfo>() {
public PermissionGroupInfo createFromParcel(Parcel source) {
return new PermissionGroupInfo(source);
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 1cb7eb0..27c04b4 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -128,7 +128,7 @@
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
*/
int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index 459ec62..3602a33 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -136,7 +136,7 @@
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
*/
public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 6cbab47..b025508 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -121,7 +121,7 @@
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
* @hide
*/
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index c64e48f..e751b2c 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -204,7 +204,7 @@
* "Cancel" button, but may be also used to show an alternative method for authentication,
* such as screen that asks for a backup password.
*
- * Note that this should not be set if {@link #setAllowDeviceCredential(boolean)
+ * Note that this should not be set if {@link #setDeviceCredentialAllowed(boolean)}(boolean)
* is set to true.
*
* @param text
@@ -245,7 +245,7 @@
*
* @param requireConfirmation
*/
- @NonNull public Builder setRequireConfirmation(boolean requireConfirmation) {
+ @NonNull public Builder setConfirmationRequired(boolean requireConfirmation) {
mBundle.putBoolean(KEY_REQUIRE_CONFIRMATION, requireConfirmation);
return this;
}
@@ -261,12 +261,12 @@
* Note that {@link #setNegativeButton(CharSequence, Executor,
* DialogInterface.OnClickListener)} should not be set if this is set to true.
*
- * @param enable When true, the prompt will fall back to ask for the user's device
+ * @param allowed When true, the prompt will fall back to ask for the user's device
* credentials (PIN, pattern, or password).
* @return
*/
- @NonNull public Builder setAllowDeviceCredential(boolean enable) {
- mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, enable);
+ @NonNull public Builder setDeviceCredentialAllowed(boolean allowed) {
+ mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, allowed);
return this;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 45219d6..ec9bdfd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8017,9 +8017,9 @@
/**
* Whether or not face unlock always requires user confirmation, meaning {@link
- * android.hardware.biometrics.BiometricPrompt.Builder#setRequireConfirmation(boolean)}
+ * android.hardware.biometrics.BiometricPrompt.Builder#setConfirmationRequired(boolean)}
* is always 'true'. This overrides the behavior that apps choose in the
- * setRequireConfirmation API.
+ * setConfirmationRequired API.
* @hide
*/
public static final String FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
@@ -11453,6 +11453,15 @@
"background_activity_starts_enabled";
/**
+ * The packages temporarily whitelisted to be able so start activities from background.
+ * The list of packages is {@code ":"} colon delimited.
+ *
+ * @hide
+ */
+ public static final String BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST =
+ "background_activity_starts_package_names_whitelist";
+
+ /**
* @hide
* @see com.android.server.appbinding.AppBindingConstants
*/
diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
index 40333bf..2814300 100644
--- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
+++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
@@ -52,6 +52,10 @@
/**
* The action for the intent used to define the content suggestions service.
+ *
+ * <p>To be supported, the service must also require the
+ * * {@link android.Manifest.permission#BIND_CONTENT_SUGGESTIONS_SERVICE} permission so
+ * * that other applications can not abuse it.
*/
public static final String SERVICE_INTERFACE =
"android.service.contentsuggestions.ContentSuggestionsService";
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index fac699e..43786f7 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -46,7 +46,7 @@
DEFAULT_FLAGS = new HashMap<>();
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
- DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
+ DEFAULT_FLAGS.put("settings_network_and_internet_v2", "true");
DEFAULT_FLAGS.put("settings_slice_injection", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put("settings_wifi_mac_randomization", "true");
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index ef69b63..3d3d941 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -79,7 +79,10 @@
/**
* Returns {@code true} if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor})
* and {@code false} otherwise.
+ *
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public boolean canInvokeDrawGlFunctor(View containerView) {
return true;
}
@@ -90,7 +93,9 @@
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor,
boolean waitForCompletion) {
ViewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion);
@@ -105,7 +110,9 @@
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
* @throws IllegalArgumentException if the canvas is not hardware accelerated
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
@@ -126,7 +133,9 @@
* @param releasedRunnable Called when this nativeDrawGLFunctor is no longer referenced by this
* canvas, so is safe to be destroyed.
* @throws IllegalArgumentException if the canvas is not hardware accelerated
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
@Nullable Runnable releasedRunnable) {
if (!(canvas instanceof RecordingCanvas)) {
@@ -139,7 +148,7 @@
/**
* Call webview draw functor. See API in draw_fn.h.
- * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}).
+ * @param canvas a {@link RecordingCanvas}.
* @param functor created by AwDrawFn_CreateFunctor in draw_fn.h.
*/
public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) {
@@ -156,7 +165,9 @@
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) {
ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
if (nativeDrawGLFunctor != 0 && viewRootImpl != null) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 457be34..a3e89c8 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1474,7 +1474,7 @@
*
* @param child the View to scroll to
*/
- public void scrollToDescendant(View child) {
+ public void scrollToDescendant(@NonNull View child) {
if (!mIsLayoutDirty) {
child.getDrawingRect(mTempRect);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ae3e714..4c4393d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3139,6 +3139,14 @@
<permission android:name="android.permission.BIND_CONTENT_CAPTURE_SERVICE"
android:protectionLevel="signature" />
+ <!-- Must be required by a android.service.contentsuggestions.ContentSuggestionsService,
+ to ensure that only the system can bind to it.
+ @SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by a android.service.autofill.augmented.AugmentedAutofillService,
to ensure that only the system can bind to it.
@SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
@@ -4455,6 +4463,11 @@
@hide -->
<permission android:name="android.permission.MANAGE_SENSOR_PRIVACY"
android:protectionLevel="signature" />
+ <!-- @SystemApi Permission that protects the {@link Intent#ACTION_REVIEW_ACCESSIBILITY_SERVICES}
+ intent.
+ @hide -->
+ <permission android:name="android.permission.REVIEW_ACCESSIBILITY_SERVICES"
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an activity to replace the app name and icon displayed in share targets
in the sharesheet for the Q-release and later.
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ebc6be7..ad1403d 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -132,6 +132,7 @@
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
Settings.Global.BROADCAST_BG_CONSTANTS,
Settings.Global.BROADCAST_FG_CONSTANTS,
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 18eafa6..2e56e09 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1718,6 +1718,11 @@
* <p>Modifies the bitmap to have the specified {@link ColorSpace}, without
* affecting the underlying allocation backing the bitmap.</p>
*
+ * <p>This affects how the framework will interpret the color at each pixel. A bitmap
+ * with {@link Config#ALPHA_8} never has a color space, since a color space does not
+ * affect the alpha channel. Other {@code Config}s must always have a non-null
+ * {@code ColorSpace}.</p>
+ *
* @throws IllegalArgumentException If the specified color space is {@code null}, not
* {@link ColorSpace.Model#RGB RGB}, has a transfer function that is not an
* {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}, or whose
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index e623354..7345ea4 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -193,7 +193,7 @@
*
* @param name The debug name to use for this HardwareRenderer instance
*/
- public void setName(String name) {
+ public void setName(@NonNull String name) {
nSetName(mNativeProxy, name);
}
@@ -330,7 +330,7 @@
*
* @return this instance
*/
- public FrameRenderRequest setVsyncTime(long vsyncTime) {
+ public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
mFrameInfo.setVsync(vsyncTime, vsyncTime);
mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
return this;
@@ -351,7 +351,7 @@
*
* @return this instance
*/
- public FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
+ public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
@NonNull Runnable frameCommitCallback) {
setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback));
return this;
@@ -372,7 +372,7 @@
* completion.
* @return this instance
*/
- public FrameRenderRequest setWaitForPresent(boolean shouldWait) {
+ public @NonNull FrameRenderRequest setWaitForPresent(boolean shouldWait) {
mWaitForPresent = shouldWait;
return this;
}
@@ -406,7 +406,7 @@
* @return An instance of {@link FrameRenderRequest}. The instance may be reused for every
* frame, so the caller should not hold onto it for longer than a single render request.
*/
- public FrameRenderRequest createRenderRequest() {
+ public @NonNull FrameRenderRequest createRenderRequest() {
mRenderRequest.reset();
return mRenderRequest;
}
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 30466e1..c0e0a24 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -166,7 +166,9 @@
* @param drawGLFunction A native function pointer
*
* @hide
+ * @deprecated Use {@link #drawWebViewFunctor(int)}
*/
+ @Deprecated
public void callDrawGLFunction2(long drawGLFunction) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
}
@@ -184,7 +186,9 @@
* canvas's display list has been released.
*
* @hide
+ * @deprecated Use {@link #drawWebViewFunctor(int)}
*/
+ @Deprecated
public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
}
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 0244942..c3bcbb4 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -338,7 +338,7 @@
* @see #endRecording()
* @see #hasDisplayList()
*/
- public RecordingCanvas beginRecording(int width, int height) {
+ public @NonNull RecordingCanvas beginRecording(int width, int height) {
if (mCurrentRecordingCanvas != null) {
throw new IllegalStateException(
"Recording currently in progress - missing #endRecording() call?");
@@ -358,7 +358,7 @@
* @see #endRecording()
* @see #hasDisplayList()
*/
- public RecordingCanvas beginRecording() {
+ public @NonNull RecordingCanvas beginRecording() {
return beginRecording(nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
}
@@ -1285,7 +1285,7 @@
* @param position The position rectangle in pixels
* @return True if the value changed, false if the new value was the same as the previous value.
*/
- public boolean setPosition(Rect position) {
+ public boolean setPosition(@NonNull Rect position) {
return nSetLeftTopRightBottom(mNativeRenderNode,
position.left, position.top, position.right, position.bottom);
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1894e32..e58e802 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -17,9 +17,11 @@
package android.graphics.drawable;
import android.annotation.ColorInt;
+import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.Px;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
@@ -670,7 +672,7 @@
* @see #mutate()
* @see #setColor(int)
*/
- public void setColors(@ColorInt int[] colors) {
+ public void setColors(@Nullable @ColorInt int[] colors) {
setColors(colors, null);
}
@@ -690,7 +692,7 @@
* @see #mutate()
* @see #setColors(int[])
*/
- public void setColors(@ColorInt int[] colors, @Nullable float[] offsets) {
+ public void setColors(@Nullable @ColorInt int[] colors, @Nullable float[] offsets) {
mGradientState.setGradientColors(colors);
mGradientState.mPositions = offsets;
mGradientIsDirty = true;
@@ -877,7 +879,11 @@
* @see #getInnerRadiusRatio()
* @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
*/
- public void setInnerRadiusRatio(float innerRadiusRatio) {
+ public void setInnerRadiusRatio(
+ @FloatRange(from = 0.0f, fromInclusive = false) float innerRadiusRatio) {
+ if (innerRadiusRatio <= 0) {
+ throw new IllegalArgumentException("Ratio must be greater than zero");
+ }
mGradientState.mInnerRadiusRatio = innerRadiusRatio;
mPathIsDirty = true;
invalidateSelf();
@@ -899,7 +905,7 @@
* @see #getInnerRadius()
* @attr ref android.R.styleable#GradientDrawable_innerRadius
*/
- public void setInnerRadius(int innerRadius) {
+ public void setInnerRadius(@Px int innerRadius) {
mGradientState.mInnerRadius = innerRadius;
mPathIsDirty = true;
invalidateSelf();
@@ -911,7 +917,7 @@
* @see #setInnerRadius(int)
* @attr ref android.R.styleable#GradientDrawable_innerRadius
*/
- public int getInnerRadius() {
+ public @Px int getInnerRadius() {
return mGradientState.mInnerRadius;
}
@@ -921,7 +927,11 @@
* @see #getThicknessRatio()
* @attr ref android.R.styleable#GradientDrawable_thicknessRatio
*/
- public void setThicknessRatio(float thicknessRatio) {
+ public void setThicknessRatio(
+ @FloatRange(from = 0.0f, fromInclusive = false) float thicknessRatio) {
+ if (thicknessRatio <= 0) {
+ throw new IllegalArgumentException("Ratio must be greater than zero");
+ }
mGradientState.mThicknessRatio = thicknessRatio;
mPathIsDirty = true;
invalidateSelf();
@@ -942,7 +952,7 @@
*
* @attr ref android.R.styleable#GradientDrawable_thickness
*/
- public void setThickness(int thickness) {
+ public void setThickness(@Px int thickness) {
mGradientState.mThickness = thickness;
mPathIsDirty = true;
invalidateSelf();
@@ -954,7 +964,7 @@
* @see #setThickness(int)
* @attr ref android.R.styleable#GradientDrawable_thickness
*/
- public int getThickness() {
+ public @Px int getThickness() {
return mGradientState.mThickness;
}
@@ -970,7 +980,7 @@
* @attr ref android.R.styleable#GradientDrawablePadding_right
* @attr ref android.R.styleable#GradientDrawablePadding_bottom
*/
- public void setPadding(int left, int top, int right, int bottom) {
+ public void setPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
if (mGradientState.mPadding == null) {
mGradientState.mPadding = new Rect();
}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 2855227..f67188c 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -256,7 +256,7 @@
* @see #getStateCount()
* @see #getStateDrawable(int)
*/
- public int[] getStateSet(int index) {
+ public @NonNull int[] getStateSet(int index) {
return mStateListState.mStateSets[index];
}
@@ -268,7 +268,7 @@
* @see #getStateCount()
* @see #getStateSet(int)
*/
- public Drawable getStateDrawable(int index) {
+ public @Nullable Drawable getStateDrawable(int index) {
return mStateListState.getChild(index);
}
@@ -280,7 +280,7 @@
* @see #getStateDrawable(int)
* @see #getStateSet(int)
*/
- public int findStateDrawableIndex(int[] stateSet) {
+ public int findStateDrawableIndex(@NonNull int[] stateSet) {
return mStateListState.indexOfStateSet(stateSet);
}
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 17e2509..ed74333 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -113,6 +113,10 @@
* Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
*/
private static final int HAS_BEARING_ACCURACY_MASK = 128;
+ /**
+ * Bit mask for mFieldsMask indicating the presence of mElapsedRealtimeUncertaintyNanos.
+ */
+ private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256;
// Cached data to make bearing/distance computations more efficient for the case
// where distanceTo and bearingTo are called in sequence. Assume this typically happens
@@ -130,6 +134,9 @@
private long mTime = 0;
@UnsupportedAppUsage
private long mElapsedRealtimeNanos = 0;
+ // Estimate of the relative precision of the alignment of this SystemClock
+ // timestamp, with the reported measurements in nanoseconds (68% confidence).
+ private long mElapsedRealtimeUncertaintyNanos = 0;
private double mLatitude = 0.0;
private double mLongitude = 0.0;
private double mAltitude = 0.0f;
@@ -171,6 +178,7 @@
mProvider = l.mProvider;
mTime = l.mTime;
mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
+ mElapsedRealtimeUncertaintyNanos = l.mElapsedRealtimeUncertaintyNanos;
mFieldsMask = l.mFieldsMask;
mLatitude = l.mLatitude;
mLongitude = l.mLongitude;
@@ -191,6 +199,7 @@
mProvider = null;
mTime = 0;
mElapsedRealtimeNanos = 0;
+ mElapsedRealtimeUncertaintyNanos = 0;
mFieldsMask = 0;
mLatitude = 0;
mLongitude = 0;
@@ -586,6 +595,37 @@
}
/**
+ * Get estimate of the relative precision of the alignment of the
+ * ElapsedRealtimeNanos timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ *
+ * @return uncertainty of elapsed real-time of fix, in nanoseconds.
+ */
+ public long getElapsedRealtimeUncertaintyNanos() {
+ return mElapsedRealtimeUncertaintyNanos;
+ }
+
+ /**
+ * Set estimate of the relative precision of the alignment of the
+ * ElapsedRealtimeNanos timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ *
+ * @param time uncertainty of the elapsed real-time of fix, in nanoseconds.
+ */
+ public void setElapsedRealtimeUncertaintyNanos(long time) {
+ mElapsedRealtimeUncertaintyNanos = time;
+ mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
+ }
+
+ /**
+ * True if this location has a elapsed realtime accuracy.
+ */
+ public boolean hasElapsedRealtimeUncertaintyNanos() {
+ return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
+ }
+
+
+ /**
* Get the latitude, in degrees.
*
* <p>All locations generated by the {@link LocationManager}
@@ -1062,6 +1102,10 @@
s.append(" et=");
TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
}
+ if (hasElapsedRealtimeUncertaintyNanos()) {
+ s.append(" etAcc=");
+ TimeUtils.formatDuration(mElapsedRealtimeUncertaintyNanos / 1000000L, s);
+ }
if (hasAltitude()) s.append(" alt=").append(mAltitude);
if (hasSpeed()) s.append(" vel=").append(mSpeed);
if (hasBearing()) s.append(" bear=").append(mBearing);
@@ -1092,6 +1136,7 @@
Location l = new Location(provider);
l.mTime = in.readLong();
l.mElapsedRealtimeNanos = in.readLong();
+ l.mElapsedRealtimeUncertaintyNanos = in.readLong();
l.mFieldsMask = in.readByte();
l.mLatitude = in.readDouble();
l.mLongitude = in.readDouble();
@@ -1122,6 +1167,7 @@
parcel.writeString(mProvider);
parcel.writeLong(mTime);
parcel.writeLong(mElapsedRealtimeNanos);
+ parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
parcel.writeByte(mFieldsMask);
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
diff --git a/packages/SystemUI/res-keyguard/layout/type_clock.xml b/packages/SystemUI/res-keyguard/layout/type_clock.xml
index f4a7376..89bbc09 100644
--- a/packages/SystemUI/res-keyguard/layout/type_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/type_clock.xml
@@ -21,10 +21,10 @@
>
<com.android.keyguard.clock.TypographicClock
android:id="@+id/type_clock"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="50dp"
+ android:paddingStart="50dp"
+ android:textAlignment="viewStart"
style="@style/widget_big"
android:textSize="40dp"
/>
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 38f469e..67293c5 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -18,8 +18,8 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Date format for display: should match the lockscreen in /policy. -->
- <string name="system_ui_date_pattern">@*android:string/system_ui_date_pattern</string>
+ <string name="system_ui_date_pattern" translatable="false">@*android:string/system_ui_date_pattern</string>
<!-- Date format for the always on display. -->
- <item type="string" name="system_ui_aod_date_pattern">eeeMMMd</item>
+ <item type="string" name="system_ui_aod_date_pattern" translatable="false">eeeMMMd</item>
</resources>
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index a18686d..9b70272 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -16,6 +16,7 @@
package com.android.server.contentsuggestions;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -73,6 +74,13 @@
throw new PackageManager.NameNotFoundException(
"Could not get service for " + serviceComponent);
}
+ if (!Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE.equals(si.permission)) {
+ Slog.w(TAG, "ContentSuggestionsService from '" + si.packageName
+ + "' does not require permission "
+ + Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE);
+ throw new SecurityException("Service does not require permission "
+ + Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE);
+ }
return si;
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 18e9906..bbd51ad 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1176,7 +1176,7 @@
@GuardedBy("mLock")
public boolean isUseableForUserLocked(int userId) {
- return userId == mCurrentUserId && mUseable;
+ return isCurrentProfileLocked(userId) && mUseable;
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 415a892..f9fcef6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -27,6 +27,8 @@
import android.provider.DeviceConfig.OnPropertyChangedListener;
import android.provider.Settings;
import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -235,6 +237,8 @@
// Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED
volatile boolean mFlagBackgroundActivityStartsEnabled;
+ volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
+
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -273,6 +277,10 @@
Settings.Global.getUriFor(
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);
+ private static final Uri BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI =
+ Settings.Global.getUriFor(
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+
private final OnPropertyChangedListener mOnDeviceConfigChangedListener =
new OnPropertyChangedListener() {
@Override
@@ -293,9 +301,12 @@
mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this);
+ mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI,
+ false, this);
updateConstants();
updateActivityStartsLoggingEnabled();
updateBackgroundActivityStartsEnabled();
+ updateBackgroundActivityStartsPackageNamesWhitelist();
DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(),
mOnDeviceConfigChangedListener);
@@ -325,6 +336,8 @@
updateActivityStartsLoggingEnabled();
} else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
updateBackgroundActivityStartsEnabled();
+ } else if (BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI.equals(uri)) {
+ updateBackgroundActivityStartsPackageNamesWhitelist();
}
}
@@ -414,6 +427,21 @@
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1) == 1;
}
+ private void updateBackgroundActivityStartsPackageNamesWhitelist() {
+ final String setting = Settings.Global.getString(mResolver,
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+ if (TextUtils.isEmpty(setting)) {
+ return;
+ }
+ ArraySet<String> newSet = new ArraySet<>();
+ SimpleStringSplitter splitter = new SimpleStringSplitter(':');
+ splitter.setString(setting);
+ while (splitter.hasNext()) {
+ newSet.add(splitter.next());
+ }
+ mPackageNamesWhitelistedForBgActivityStarts = newSet;
+ }
+
private void updateMaxCachedProcesses() {
String maxCachedProcessesFlag = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MAX_CACHED_PROCESSES);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ccb9d82..0a68ce0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17862,6 +17862,10 @@
return mConstants.mFlagActivityStartsLoggingEnabled;
}
+ public boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
+ return mConstants.mPackageNamesWhitelistedForBgActivityStarts.contains(packageName);
+ }
+
public boolean isBackgroundActivityStartsEnabled() {
return mConstants.mFlagBackgroundActivityStartsEnabled;
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 280bc02..d723c7b 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -146,7 +146,7 @@
* Whether history is enabled.
*/
@GuardedBy("mInMemoryLock")
- private int mMode = AppOpsManager.HISTORICAL_MODE_DISABLED;
+ private int mMode = AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE;
/**
* This granularity has been chosen to allow clean delineation for intervals
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index f2e2782..a53797d 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -7,13 +7,7 @@
"name": "FrameworksServicesTests",
"options": [
{
- "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsServiceTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ "include-filter": "com.android.server.appop"
}
]
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 71ec5b0..9ab9975 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -142,6 +142,7 @@
// these need to match ElapsedRealtimeFlags enum in types.hal
private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
+ private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
// IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
private static final int GPS_DELETE_EPHEMERIS = 0x0001;
@@ -768,15 +769,18 @@
float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
long timestamp = location.getTime();
- int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
+ int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
+ | (location.hasElapsedRealtimeUncertaintyNanos()
+ ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
+ long elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
native_inject_best_location(
gnssLocationFlags, latitudeDegrees, longitudeDegrees,
altitudeMeters, speedMetersPerSec, bearingDegrees,
horizontalAccuracyMeters, verticalAccuracyMeters,
speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
- elapsedRealtimeFlags, elapsedRealtimeNanos);
+ elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
}
/** Returns true if the location request is too frequent. */
@@ -2170,7 +2174,8 @@
double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
float horizontalAccuracyMeters, float verticalAccuracyMeters,
float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
- long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);
+ long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
+ long elapsedRealtimeUncertaintyNanos);
private native void native_inject_location(double latitude, double longitude, float accuracy);
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index f52f3a3..e241ba6 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -599,6 +599,8 @@
}
}
}
+
+ mPackageHealthObserver.onBootCompleted();
});
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index d24f217..d8f07fe 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -26,6 +26,8 @@
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
+import android.os.Environment;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
@@ -39,6 +41,12 @@
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
@@ -50,14 +58,19 @@
public final class RollbackPackageHealthObserver implements PackageHealthObserver {
private static final String TAG = "RollbackPackageHealthObserver";
private static final String NAME = "rollback-observer";
- private Context mContext;
- private Handler mHandler;
+ private static final int INVALID_ROLLBACK_ID = -1;
+ private final Context mContext;
+ private final Handler mHandler;
+ private final File mLastStagedRollbackIdFile;
RollbackPackageHealthObserver(Context context) {
mContext = context;
HandlerThread handlerThread = new HandlerThread("RollbackPackageHealthObserver");
handlerThread.start();
mHandler = handlerThread.getThreadHandler();
+ File dataDir = new File(Environment.getDataDirectory(), "rollback-observer");
+ dataDir.mkdirs();
+ mLastStagedRollbackIdFile = new File(dataDir, "last-staged-rollback-id");
PackageWatchdog.getInstance(mContext).registerHealthObserver(this);
}
@@ -112,15 +125,19 @@
int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
RollbackManager.STATUS_FAILURE);
if (status == RollbackManager.STATUS_SUCCESS) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
if (rollback.isStaged()) {
int rollbackId = rollback.getRollbackId();
BroadcastReceiver listener =
- listenForStagedSessionReady(rollbackManager, rollbackId);
- handleStagedSessionChange(rollbackManager, rollbackId, listener);
+ listenForStagedSessionReady(rollbackManager, rollbackId,
+ moduleMetadataPackage);
+ handleStagedSessionChange(rollbackManager, rollbackId, listener,
+ moduleMetadataPackage);
+ } else {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
}
} else {
StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
@@ -152,6 +169,71 @@
PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
}
+ /** Verifies the rollback state after a reboot. */
+ public void onBootCompleted() {
+ int rollbackId = popLastStagedRollbackId();
+ if (rollbackId == INVALID_ROLLBACK_ID) {
+ // No staged rollback before reboot
+ return;
+ }
+
+ RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ RollbackInfo rollback = null;
+ for (RollbackInfo info : rollbackManager.getRecentlyCommittedRollbacks()) {
+ if (rollbackId == info.getRollbackId()) {
+ rollback = info;
+ break;
+ }
+ }
+
+ if (rollback == null) {
+ Slog.e(TAG, "rollback info not found for last staged rollback: " + rollbackId);
+ return;
+ }
+
+ String moduleMetadataPackageName = getModuleMetadataPackageName();
+ if (moduleMetadataPackageName == null) {
+ // Only log mainline staged rollbacks
+ return;
+ }
+
+ // Use the version of the metadata package that was installed before
+ // we rolled back for logging purposes.
+ VersionedPackage moduleMetadataPackage = null;
+ for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
+ if (moduleMetadataPackageName.equals(packageRollback.getPackageName())) {
+ moduleMetadataPackage = packageRollback.getVersionRolledBackFrom();
+ break;
+ }
+ }
+
+ if (moduleMetadataPackage == null) {
+ // Only log mainline staged rollbacks
+ return;
+ }
+
+ int sessionId = rollback.getCommittedSessionId();
+ PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
+ if (sessionInfo == null) {
+ Slog.e(TAG, "On boot completed, could not load session id " + sessionId);
+ return;
+ }
+ if (sessionInfo.isStagedSessionApplied()) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ } else if (sessionInfo.isStagedSessionReady()) {
+ // TODO: What do for staged session ready but not applied
+ } else {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ }
+ }
+
private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager,
VersionedPackage failedPackage, VersionedPackage moduleMetadataPackage) {
for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) {
@@ -174,12 +256,20 @@
return null;
}
- private VersionedPackage getModuleMetadataPackage() {
+ private String getModuleMetadataPackageName() {
String packageName = mContext.getResources().getString(
R.string.config_defaultModuleMetadataProvider);
if (TextUtils.isEmpty(packageName)) {
return null;
}
+ return packageName;
+ }
+
+ private VersionedPackage getModuleMetadataPackage() {
+ String packageName = getModuleMetadataPackageName();
+ if (packageName == null) {
+ return null;
+ }
try {
return new VersionedPackage(packageName, mContext.getPackageManager().getPackageInfo(
@@ -191,12 +281,12 @@
}
private BroadcastReceiver listenForStagedSessionReady(RollbackManager rollbackManager,
- int rollbackId) {
+ int rollbackId, VersionedPackage moduleMetadataPackage) {
BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleStagedSessionChange(rollbackManager,
- rollbackId, this /* BroadcastReceiver */);
+ rollbackId, this /* BroadcastReceiver */, moduleMetadataPackage);
}
};
IntentFilter sessionUpdatedFilter =
@@ -206,7 +296,7 @@
}
private void handleStagedSessionChange(RollbackManager rollbackManager, int rollbackId,
- BroadcastReceiver listener) {
+ BroadcastReceiver listener, VersionedPackage moduleMetadataPackage) {
PackageInstaller packageInstaller =
mContext.getPackageManager().getPackageInstaller();
List<RollbackInfo> recentRollbacks =
@@ -220,11 +310,52 @@
packageInstaller.getSessionInfo(sessionId);
if (sessionInfo.isStagedSessionReady()) {
mContext.unregisterReceiver(listener);
+ saveLastStagedRollbackId(rollbackId);
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
} else if (sessionInfo.isStagedSessionFailed()) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
mContext.unregisterReceiver(listener);
}
}
}
}
+
+ private void saveLastStagedRollbackId(int stagedRollbackId) {
+ try {
+ FileOutputStream fos = new FileOutputStream(mLastStagedRollbackIdFile);
+ PrintWriter pw = new PrintWriter(fos);
+ pw.println(stagedRollbackId);
+ pw.flush();
+ FileUtils.sync(fos);
+ pw.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to save last staged rollback id", e);
+ mLastStagedRollbackIdFile.delete();
+ }
+ }
+
+ private int popLastStagedRollbackId() {
+ int rollbackId = INVALID_ROLLBACK_ID;
+ if (!mLastStagedRollbackIdFile.exists()) {
+ return rollbackId;
+ }
+
+ try {
+ rollbackId = Integer.parseInt(
+ IoUtils.readFileAsString(mLastStagedRollbackIdFile.getAbsolutePath()).trim());
+ } catch (IOException | NumberFormatException e) {
+ Slog.e(TAG, "Failed to retrieve last staged rollback id", e);
+ }
+ mLastStagedRollbackIdFile.delete();
+ return rollbackId;
+ }
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index bb1e001..e53fde9 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -474,7 +474,13 @@
int wallpaperId;
if (wallpaper.equals(mFallbackWallpaper)) {
- extractDefaultImageWallpaperColors();
+ synchronized (mLock) {
+ if (mFallbackWallpaper.primaryColors != null) return;
+ }
+ final WallpaperColors colors = extractDefaultImageWallpaperColors();
+ synchronized (mLock) {
+ mFallbackWallpaper.primaryColors = colors;
+ }
return;
}
@@ -499,23 +505,7 @@
}
} else if (defaultImageWallpaper) {
// There is no crop and source file because this is default image wallpaper.
- try (final InputStream is =
- WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM)) {
- if (is != null) {
- try {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
- if (bitmap != null) {
- colors = WallpaperColors.fromBitmap(bitmap);
- bitmap.recycle();
- }
- } catch (OutOfMemoryError e) {
- Slog.w(TAG, "Can't decode default wallpaper stream", e);
- }
- }
- } catch (IOException e) {
- Slog.w(TAG, "Can't close default wallpaper stream", e);
- }
+ colors = extractDefaultImageWallpaperColors();
}
if (colors == null) {
@@ -535,37 +525,41 @@
}
}
- private void extractDefaultImageWallpaperColors() {
+ private WallpaperColors extractDefaultImageWallpaperColors() {
+ if (DEBUG) Slog.d(TAG, "Extract default image wallpaper colors");
+
synchronized (mLock) {
- if (mFallbackWallpaper.primaryColors != null) return;
+ if (mCacheDefaultImageWallpaperColors != null) return mCacheDefaultImageWallpaperColors;
}
- if (DEBUG) Slog.d(TAG, "Extract default image wallpaper colors");
WallpaperColors colors = null;
- final InputStream is = WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM);
- if (is != null) {
- try {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
- if (bitmap != null) {
- colors = WallpaperColors.fromBitmap(bitmap);
- bitmap.recycle();
- }
- } catch (OutOfMemoryError e) {
- Slog.w(TAG, "Can't decode default wallpaper stream", e);
- } finally {
- IoUtils.closeQuietly(is);
+ try (InputStream is = WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM)) {
+ if (is == null) {
+ Slog.w(TAG, "Can't open default wallpaper stream");
+ return null;
}
+
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
+ if (bitmap != null) {
+ colors = WallpaperColors.fromBitmap(bitmap);
+ bitmap.recycle();
+ }
+ } catch (OutOfMemoryError e) {
+ Slog.w(TAG, "Can't decode default wallpaper stream", e);
+ } catch (IOException e) {
+ Slog.w(TAG, "Can't close default wallpaper stream", e);
}
if (colors == null) {
Slog.e(TAG, "Extract default image wallpaper colors failed");
- return;
+ } else {
+ synchronized (mLock) {
+ mCacheDefaultImageWallpaperColors = colors;
+ }
}
- synchronized (mLock) {
- mFallbackWallpaper.primaryColors = colors;
- }
+ return colors;
}
/**
@@ -815,6 +809,12 @@
private final ComponentName mImageWallpaper;
/**
+ * Default image wallpaper shall never changed after system service started, caching it when we
+ * first read the image file.
+ */
+ private WallpaperColors mCacheDefaultImageWallpaperColors;
+
+ /**
* Name of the default wallpaper component; might be different from mImageWallpaper
*/
private final ComponentName mDefaultWallpaperComponent;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 9f04166..23bed7b 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1009,6 +1009,12 @@
if (mService.isDeviceOwner(callingPackage)) {
return false;
}
+ // don't abort if the callingPackage is temporarily whitelisted
+ if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
+ Slog.w(TAG, "Background activity start for " + callingPackage
+ + " temporarily whitelisted. This will not be supported in future Q builds.");
+ return false;
+ }
// anything that has fallen through would currently be aborted
Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
+ "; callingUid: " + callingUid
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d747198..3255bc6 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5210,6 +5210,10 @@
return mAmInternal.isBackgroundActivityStartsEnabled();
}
+ boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
+ return mAmInternal.isPackageNameWhitelistedForBgActivityStarts(packageName);
+ }
+
void enableScreenAfterBoot(boolean booted) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
SystemClock.uptimeMillis());
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index d39f20c..298b664 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -491,6 +491,10 @@
SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
}
+ if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+ SET(ElapsedRealtimeUncertaintyNanos, location.elapsedRealtime.timeUncertaintyNs);
+ }
+
return object.get();
}
@@ -521,7 +525,8 @@
jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
- jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos) {
+ jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+ jlong elapsedRealtimeUncertaintyNanos) {
GnssLocation_V2_0 location;
location.v1_0 = createGnssLocation_V1_0(
gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
@@ -531,6 +536,7 @@
location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
+ location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
return location;
}
@@ -1887,7 +1893,8 @@
jfloat bearingAccuracyDegrees,
jlong timestamp,
jint elapsedRealtimeFlags,
- jlong elapsedRealtimeNanos) {
+ jlong elapsedRealtimeNanos,
+ jlong elapsedRealtimeUncertaintyNanos) {
if (gnssHal_V2_0 != nullptr) {
GnssLocation_V2_0 location = createGnssLocation_V2_0(
gnssLocationFlags,
@@ -1902,7 +1909,8 @@
bearingAccuracyDegrees,
timestamp,
elapsedRealtimeFlags,
- elapsedRealtimeNanos);
+ elapsedRealtimeNanos,
+ elapsedRealtimeUncertaintyNanos);
auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
if (!result.isOk() || !result) {
@@ -2813,7 +2821,7 @@
android_location_GnssLocationProvider_read_nmea)},
{"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_time)},
- {"native_inject_best_location", "(IDDDFFFFFFJIJ)V", reinterpret_cast<void *>(
+ {"native_inject_best_location", "(IDDDFFFFFFJIJJ)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_best_location)},
{"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_location)},
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 72357ce..133e9f8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.pm;
+import static android.content.res.Resources.ID_NULL;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
@@ -454,7 +456,7 @@
pkg.applicationInfo = new ApplicationInfo();
pkg.permissions.add(new PackageParser.Permission(pkg));
- pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg));
+ pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL));
final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 606ab31..d02db7b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -561,7 +561,7 @@
runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
}
/**
@@ -576,7 +576,7 @@
"disallowed_unsupportedUsecase_aborted", true,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
}
/**
@@ -591,61 +591,66 @@
runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false,
Process.NFC_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingUidHasVisibleWindow_notAborted", false,
UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingUidProcessStateTop_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_realCallingUidHasVisibleWindow_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_realCallingUidProcessStateTop_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_hasForegroundActivities_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- true, false, false, false, false);
+ true, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsRecents_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, true, false, false, false);
+ false, true, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsWhitelisted_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, true, false, false);
+ false, false, true, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsInstrumentingWithBackgroundActivityStartPrivileges_notAborted",
false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, true, false);
+ false, false, false, true, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingPackageNameIsDeviceOwner_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, true);
+ false, false, false, false, true, false);
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "disallowed_callingPackageNameIsTempWhitelisted_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+ false, false, false, false, false, true);
}
private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -654,7 +659,7 @@
boolean hasForegroundActivities, boolean callerIsRecents,
boolean callerIsTempWhitelisted,
boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
- boolean isCallingPackageNameDeviceOwner) {
+ boolean isCallingPackageNameDeviceOwner, boolean isCallingPackageTempWhitelisted) {
// window visibility
doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
.isAnyNonToastWindowVisibleForUid(callingUid);
@@ -680,11 +685,15 @@
// caller is instrumenting with background activity starts privileges
callerApp.setInstrumenting(callerIsInstrumentingWithBackgroundActivityStartPrivileges,
callerIsInstrumentingWithBackgroundActivityStartPrivileges);
- // calling package name is whitelisted
+ // calling package name is the device owner
doReturn(isCallingPackageNameDeviceOwner).when(mService).isDeviceOwner(any());
+ // calling package name is temporarily whitelisted
+ doReturn(isCallingPackageTempWhitelisted).when(mService)
+ .isPackageNameWhitelistedForBgActivityStarts("com.whatever.dude");
final ActivityOptions options = spy(ActivityOptions.makeBasic());
ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
+ .setCallingPackage("com.whatever.dude")
.setCaller(caller)
.setCallingUid(callingUid)
.setRealCallingUid(realCallingUid)
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 9d46300..67477cf 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3829,6 +3829,42 @@
*/
public static final String CARRIER_ID = "carrier_id";
+ /**
+ * The skip 464xlat flag. Flag works as follows.
+ * {@link #SKIP_464XLAT_DEFAULT}: the APN will skip only APN is IMS and no internet.
+ * {@link #SKIP_464XLAT_DISABLE}: the APN will NOT skip 464xlat
+ * {@link #SKIP_464XLAT_ENABLE}: the APN will skip 464xlat
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final String SKIP_464XLAT = "skip_464xlat";
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_DEFAULT = -1;
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_DISABLE = 0;
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_ENABLE = 1;
+
+
/** @hide */
@IntDef({
UNEDITED,
@@ -3839,6 +3875,16 @@
})
@Retention(RetentionPolicy.SOURCE)
public @interface EditStatus {}
+
+ /** @hide */
+ @IntDef({
+ SKIP_464XLAT_DEFAULT,
+ SKIP_464XLAT_DISABLE,
+ SKIP_464XLAT_ENABLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Skip464XlatStatus {}
+
}
/**
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 4fdfcbe0..48c07e8 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -22,6 +22,7 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.TelephonyManager.PrefNetworkMode;
import com.android.internal.telephony.RILConstants;
@@ -170,7 +171,8 @@
};
@UnsupportedAppUsage
- public static int getRafFromNetworkType(int type) {
+ @TelephonyManager.NetworkTypeBitMask
+ public static int getRafFromNetworkType(@PrefNetworkMode int type) {
switch (type) {
case RILConstants.NETWORK_MODE_WCDMA_PREF:
return GSM | WCDMA;
@@ -279,6 +281,7 @@
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @PrefNetworkMode
public static int getNetworkTypeFromRaf(int raf) {
raf = getAdjustedRaf(raf);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index aaf5f33..0b003dc 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -6861,12 +6861,12 @@
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @param subId the id of the subscription to set the preferred network type for.
- * @param networkType the preferred network type, defined in RILConstants.java.
+ * @param networkType the preferred network type
* @return true on success; false on any failure.
* @hide
*/
@UnsupportedAppUsage
- public boolean setPreferredNetworkType(int subId, int networkType) {
+ public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
@@ -10366,6 +10366,10 @@
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the
* calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+ *
+ * Note: with only carrier privileges, it is not allowed to switch from multi-sim
+ * to single-sim
+ *
* @param numOfSims number of live SIMs we want to switch to
* @throws android.os.RemoteException
*/
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 9d072f0..be6f383 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -61,6 +61,7 @@
private static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*";
private static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*";
private static final String V6_FORMAT_REGEX = "^\\[ApnSettingV6\\]\\s*";
+ private static final String V7_FORMAT_REGEX = "^\\[ApnSettingV7\\]\\s*";
/**
* Default value for mtu if it's not set. Moved from PhoneConstants.
@@ -286,6 +287,8 @@
private boolean mPermanentFailed = false;
private final int mCarrierId;
+ private final int mSkip464Xlat;
+
/**
* Returns the MTU size of the mobile interface to which the APN connected.
*
@@ -623,6 +626,17 @@
return mCarrierId;
}
+ /**
+ * Returns the skip464xlat flag for this APN.
+ *
+ * @return SKIP_464XLAT_DEFAULT, SKIP_464XLAT_DISABLE or SKIP_464XLAT_ENABLE
+ * @hide
+ */
+ @Carriers.Skip464XlatStatus
+ public int getSkip464Xlat() {
+ return mSkip464Xlat;
+ }
+
private ApnSetting(Builder builder) {
this.mEntryName = builder.mEntryName;
this.mApnName = builder.mApnName;
@@ -651,6 +665,7 @@
this.mMvnoMatchData = builder.mMvnoMatchData;
this.mApnSetId = builder.mApnSetId;
this.mCarrierId = builder.mCarrierId;
+ this.mSkip464Xlat = builder.mSkip464Xlat;
}
/**
@@ -662,7 +677,7 @@
int authType, int mApnTypeBitmask, int protocol, int roamingProtocol,
boolean carrierEnabled, int networkTypeBitmask, int profileId,
boolean modemCognitive, int maxConns, int waitTime, int maxConnsTime, int mtu,
- int mvnoType, String mvnoMatchData, int apnSetId, int carrierId) {
+ int mvnoType, String mvnoMatchData, int apnSetId, int carrierId, int skip464xlat) {
return new Builder()
.setId(id)
.setOperatorNumeric(operatorNumeric)
@@ -691,6 +706,7 @@
.setMvnoMatchData(mvnoMatchData)
.setApnSetId(apnSetId)
.setCarrierId(carrierId)
+ .setSkip464Xlat(skip464xlat)
.buildWithoutCheck();
}
@@ -708,7 +724,8 @@
mmsc, mmsProxyAddress, mmsProxyPort, user, password, authType, mApnTypeBitmask,
protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, profileId,
modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType, mvnoMatchData,
- Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+ Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID,
+ Carriers.SKIP_464XLAT_DEFAULT);
}
/**
@@ -767,7 +784,8 @@
cursor.getString(cursor.getColumnIndexOrThrow(
Telephony.Carriers.MVNO_MATCH_DATA)),
cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)));
+ cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.SKIP_464XLAT)));
}
/**
@@ -780,7 +798,7 @@
apn.mProtocol, apn.mRoamingProtocol, apn.mCarrierEnabled, apn.mNetworkTypeBitmask,
apn.mProfileId, apn.mPersistent, apn.mMaxConns, apn.mWaitTime,
apn.mMaxConnsTime, apn.mMtu, apn.mMvnoType, apn.mMvnoMatchData, apn.mApnSetId,
- apn.mCarrierId);
+ apn.mCarrierId, apn.mSkip464Xlat);
}
/**
@@ -829,6 +847,13 @@
* <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
* <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>
*
+ * v7 format:
+ * [ApnSettingV7] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
+ * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
+ * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
+ * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
+ * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>, <skip464xlat>
+ *
* Note that the strings generated by {@link #toString()} do not contain the username
* and password and thus cannot be read by this method.
*
@@ -841,7 +866,10 @@
int version;
// matches() operates on the whole string, so append .* to the regex.
- if (data.matches(V6_FORMAT_REGEX + ".*")) {
+ if (data.matches(V7_FORMAT_REGEX + ".*")) {
+ version = 7;
+ data = data.replaceFirst(V7_FORMAT_REGEX, "");
+ } else if (data.matches(V6_FORMAT_REGEX + ".*")) {
version = 6;
data = data.replaceFirst(V6_FORMAT_REGEX, "");
} else if (data.matches(V5_FORMAT_REGEX + ".*")) {
@@ -887,6 +915,7 @@
String mvnoMatchData = "";
int apnSetId = Carriers.NO_APN_SET_ID;
int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+ int skip464xlat = Carriers.SKIP_464XLAT_DEFAULT;
if (version == 1) {
typeArray = new String[a.length - 13];
System.arraycopy(a, 13, typeArray, 0, a.length - 13);
@@ -933,6 +962,12 @@
if (a.length > 28) {
carrierId = Integer.parseInt(a[28]);
}
+ if (a.length > 29) {
+ try {
+ skip464xlat = Integer.parseInt(a[29]);
+ } catch (NumberFormatException e) {
+ }
+ }
}
// If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be
@@ -948,7 +983,7 @@
getProtocolIntFromString(protocol), getProtocolIntFromString(roamingProtocol),
carrierEnabled, networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime,
maxConnsTime, mtu, getMvnoTypeIntFromString(mvnoType), mvnoMatchData, apnSetId,
- carrierId);
+ carrierId, skip464xlat);
}
/**
@@ -984,7 +1019,7 @@
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV6] ")
+ sb.append("[ApnSettingV7] ")
.append(mEntryName)
.append(", ").append(mId)
.append(", ").append(mOperatorNumeric)
@@ -1012,6 +1047,7 @@
sb.append(", ").append(mNetworkTypeBitmask);
sb.append(", ").append(mApnSetId);
sb.append(", ").append(mCarrierId);
+ sb.append(", ").append(mSkip464Xlat);
return sb.toString();
}
@@ -1105,7 +1141,8 @@
&& Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
&& Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
/**
@@ -1151,7 +1188,8 @@
&& Objects.equals(mMvnoType, other.mMvnoType)
&& Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
/**
@@ -1179,7 +1217,8 @@
&& xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
&& Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
// Equal or one is null.
@@ -1226,6 +1265,7 @@
apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
apnValue.put(Telephony.Carriers.CARRIER_ID, mCarrierId);
+ apnValue.put(Telephony.Carriers.SKIP_464XLAT, mSkip464Xlat);
return apnValue;
}
@@ -1385,6 +1425,7 @@
dest.writeInt(mNetworkTypeBitmask);
dest.writeInt(mApnSetId);
dest.writeInt(mCarrierId);
+ dest.writeInt(mSkip464Xlat);
}
private static ApnSetting readFromParcel(Parcel in) {
@@ -1408,11 +1449,12 @@
final int networkTypeBitmask = in.readInt();
final int apnSetId = in.readInt();
final int carrierId = in.readInt();
+ final int skip464xlat = in.readInt();
return makeApnSetting(id, operatorNumeric, entryName, apnName,
- proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
- protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
- 0, 0, 0, 0, mvnoType, null, apnSetId, carrierId);
+ proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
+ protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
+ 0, 0, 0, 0, mvnoType, null, apnSetId, carrierId, skip464xlat);
}
public static final @android.annotation.NonNull Parcelable.Creator<ApnSetting> CREATOR =
@@ -1489,6 +1531,7 @@
private String mMvnoMatchData;
private int mApnSetId;
private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+ private int mSkip464Xlat = Carriers.SKIP_464XLAT_DEFAULT;
/**
* Default constructor for Builder.
@@ -1831,6 +1874,17 @@
}
/**
+ * Sets skip464xlat flag for this APN.
+ *
+ * @param skip464xlat skip464xlat for this APN
+ * @hide
+ */
+ public Builder setSkip464Xlat(@Carriers.Skip464XlatStatus int skip464xlat) {
+ this.mSkip464Xlat = skip464xlat;
+ return this;
+ }
+
+ /**
* Builds {@link ApnSetting} from this builder.
*
* @return {@code null} if {@link #setApnName(String)} or {@link #setEntryName(String)}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 4780f30..7e183db 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -379,6 +379,83 @@
// Check that the data has expired after the expiration time (with a buffer of 1 second)
Thread.sleep(expirationTime / 2);
assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+
+ } finally {
+ DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
+ DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
+ Long.toString(defaultExpirationTime), false /* makeDefault*/);
+ RollbackTestUtils.dropShellPermissionIdentity();
+ }
+ }
+
+ /**
+ * Test that changing time on device does not affect the duration of time that we keep
+ * rollback available
+ */
+ @Test
+ public void testTimeChangeDoesNotAffectLifetime() throws Exception {
+ long expirationTime = TimeUnit.SECONDS.toMillis(30);
+ long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
+ RollbackManager rm = RollbackTestUtils.getRollbackManager();
+
+ try {
+ RollbackTestUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.MANAGE_ROLLBACKS,
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.SET_TIME);
+
+ DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
+ DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
+ Long.toString(expirationTime), false /* makeDefault*/);
+
+ // Pull the new expiration time from DeviceConfig
+ rm.reloadPersistedData();
+
+ // Install app A with rollback enabled
+ RollbackTestUtils.uninstall(TEST_APP_A);
+ RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+ RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+ assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+ Thread.sleep(expirationTime / 2);
+
+ // Install app B with rollback enabled
+ RollbackTestUtils.uninstall(TEST_APP_B);
+ RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
+ RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
+ assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ // 1 second buffer
+ Thread.sleep(1000);
+
+ try {
+ // Change the time
+ RollbackTestUtils.forwardTimeBy(expirationTime);
+
+ // 1 second buffer to allow Rollback Manager to handle time change before loading
+ // persisted data
+ Thread.sleep(1000);
+
+ // Load timestamps from storage
+ rm.reloadPersistedData();
+
+ // Wait until rollback for app A has expired
+ // This will trigger an expiration run that should expire app A but not B
+ Thread.sleep(expirationTime / 2);
+ assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+
+ // Rollback for app B should not be expired
+ RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TEST_APP_B);
+ assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollback);
+
+ // Wait until rollback for app B has expired
+ Thread.sleep(expirationTime / 2);
+ assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B));
+ } finally {
+ RollbackTestUtils.forwardTimeBy(-expirationTime);
+ }
} finally {
DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
index e8cbd60..ed8a533 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -63,6 +64,17 @@
return rm;
}
+ private static void setTime(long millis) {
+ Context context = InstrumentationRegistry.getContext();
+ AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ am.setTime(millis);
+ }
+
+ static void forwardTimeBy(long offsetMillis) {
+ setTime(System.currentTimeMillis() + offsetMillis);
+ Log.i(TAG, "Forwarded time on device by " + offsetMillis + " millis");
+ }
+
/**
* Returns the version of the given package installed on device.
* Returns -1 if the package is not currently installed.
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 295e3de..52707c2 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -196,8 +196,10 @@
if "implements" in raw:
self.implements = raw[raw.index("implements")+1]
+ self.implements_all = [self.implements]
else:
self.implements = None
+ self.implements_all = []
else:
raise ValueError("Unknown signature format: " + sig_format)
@@ -224,7 +226,7 @@
class Package():
- NAME = re.compile("package(?: .*)? ([A-Za-z.]+)")
+ NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")
def __init__(self, line, raw, blame):
self.line = line
@@ -364,12 +366,12 @@
self.parse_matching_paren("<", ">")
extends = self.parse_extends()
clazz.extends = extends[0] if extends else None
- implements = self.parse_implements()
- clazz.implements = implements[0] if implements else None
+ clazz.implements_all = self.parse_implements()
# The checks assume that interfaces are always found in implements, which isn't true for
# subinterfaces.
- if not implements and "interface" in clazz.split:
- clazz.implements = clazz.extends
+ if not clazz.implements_all and "interface" in clazz.split:
+ clazz.implements_all = [clazz.extends]
+ clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
self.parse_token("{")
self.parse_eof()
@@ -1249,6 +1251,7 @@
def verify_collections(clazz):
"""Verifies that collection types are interfaces."""
if clazz.fullname == "android.os.Bundle": return
+ if clazz.fullname == "android.os.Parcel": return
bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
"java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
@@ -1284,9 +1287,9 @@
error(clazz, m, "S1", "Methods must not throw generic exceptions")
if t in ["android.os.RemoteException"]:
- if clazz.name == "android.content.ContentProviderClient": continue
- if clazz.name == "android.os.Binder": continue
- if clazz.name == "android.os.IBinder": continue
+ if clazz.fullname == "android.content.ContentProviderClient": continue
+ if clazz.fullname == "android.os.Binder": continue
+ if clazz.fullname == "android.os.IBinder": continue
error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
@@ -1653,8 +1656,8 @@
def verify_closable(clazz):
"""Verifies that classes are AutoClosable."""
- if clazz.implements == "java.lang.AutoCloseable": return
- if clazz.implements == "java.io.Closeable": return
+ if "java.lang.AutoCloseable" in clazz.implements_all: return
+ if "java.io.Closeable" in clazz.implements_all: return
for m in clazz.methods:
if len(m.args) > 0: continue
@@ -1853,6 +1856,9 @@
def verify_pfd(clazz):
"""Verify that android APIs use PFD over FD."""
+ if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
+ return
+
examine = clazz.ctors + clazz.methods
for m in examine:
if m.typ == "java.io.FileDescriptor":
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
index f34492d..5cb43db 100644
--- a/tools/apilint/apilint_test.py
+++ b/tools/apilint/apilint_test.py
@@ -242,6 +242,10 @@
cls = self._cls("class Class {")
return apilint.Field(cls, 1, raw, '', sig_format=2)
+ def test_parse_package(self):
+ pkg = apilint.Package(999, "package wifi.p2p {", None)
+ self.assertEquals("wifi.p2p", pkg.name)
+
def test_class(self):
cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {")
self.assertTrue('deprecated' in cls.split)