diff options
62 files changed, 1045 insertions, 540 deletions
diff --git a/Android.bp b/Android.bp index 1ee7405b42ab..628894016f39 100644 --- a/Android.bp +++ b/Android.bp @@ -69,7 +69,6 @@ java_defaults { "core/java/android/app/ITaskStackListener.aidl", "core/java/android/app/IBackupAgent.aidl", "core/java/android/app/IEphemeralResolver.aidl", - "core/java/android/app/IInputForwarder.aidl", "core/java/android/app/IInstantAppResolver.aidl", "core/java/android/app/IInstrumentationWatcher.aidl", "core/java/android/app/INotificationManager.aidl", diff --git a/api/TEST_MAPPING b/api/TEST_MAPPING index 8a676e994081..2cdf54bbad6f 100644 --- a/api/TEST_MAPPING +++ b/api/TEST_MAPPING @@ -2,6 +2,9 @@ "presubmit": [ { "name": "CtsCurrentApiSignatureTestCases" + }, + { + "name": "GtsUnofficialApisUsageTestCases" } ] } diff --git a/api/current.txt b/api/current.txt index fe52f3ae83cb..1c60efa62be3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9348,25 +9348,7 @@ package android.content { field public static final android.os.Parcelable.Creator<android.content.ComponentName> CREATOR; } - public interface ContentInterface { - method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; - method public int bulkInsert(@NonNull android.net.Uri, @NonNull android.content.ContentValues[]) throws android.os.RemoteException; - method @Nullable public android.os.Bundle call(@NonNull String, @NonNull String, @Nullable String, @Nullable android.os.Bundle) throws android.os.RemoteException; - method @Nullable public android.net.Uri canonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; - method public int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]) throws android.os.RemoteException; - method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String) throws android.os.RemoteException; - method @Nullable public String getType(@NonNull android.net.Uri) throws android.os.RemoteException; - method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues) throws android.os.RemoteException; - method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.os.ParcelFileDescriptor openFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.content.res.AssetFileDescriptor openTypedAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.database.Cursor query(@NonNull android.net.Uri, @Nullable String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws android.os.RemoteException; - method public boolean refresh(@NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws android.os.RemoteException; - method @Nullable public android.net.Uri uncanonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; - method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]) throws android.os.RemoteException; - } - - public abstract class ContentProvider implements android.content.ComponentCallbacks2 android.content.ContentInterface { + public abstract class ContentProvider implements android.content.ComponentCallbacks2 { ctor public ContentProvider(); method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException; method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException; @@ -9419,7 +9401,7 @@ package android.content { method public void writeDataToPipe(@NonNull android.os.ParcelFileDescriptor, @NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable T); } - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; method public int bulkInsert(@NonNull android.net.Uri, @NonNull android.content.ContentValues[]) throws android.os.RemoteException; @@ -9502,8 +9484,8 @@ package android.content { method public void setKeepUpdated(boolean); } - public abstract class ContentResolver implements android.content.ContentInterface { - ctor public ContentResolver(android.content.Context); + public abstract class ContentResolver { + ctor public ContentResolver(@Nullable android.content.Context); method @Nullable public final android.content.ContentProviderClient acquireContentProviderClient(@NonNull android.net.Uri); method @Nullable public final android.content.ContentProviderClient acquireContentProviderClient(@NonNull String); method @Nullable public final android.content.ContentProviderClient acquireUnstableContentProviderClient(@NonNull android.net.Uri); @@ -9568,6 +9550,8 @@ package android.content { method public final void unregisterContentObserver(@NonNull android.database.ContentObserver); method public final int update(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]); method public static void validateSyncExtrasBundle(android.os.Bundle); + method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider); + method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient); field public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*"; field public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; field public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; @@ -38171,38 +38155,26 @@ package android.provider { method public static android.net.Uri buildRootsUri(String); method public static android.net.Uri buildSearchDocumentsUri(String, String, String); method public static android.net.Uri buildTreeDocumentUri(String, String); - method public static android.net.Uri copyDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method public static android.net.Uri createDocument(android.content.ContentInterface, android.net.Uri, String, String) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException; - method public static android.content.IntentSender createWebLinkIntent(android.content.ContentInterface, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException; - method @Deprecated public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException; - method public static boolean deleteDocument(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException; - method public static void ejectRoot(android.content.ContentInterface, android.net.Uri); - method @Deprecated public static void ejectRoot(android.content.ContentResolver, android.net.Uri); - method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri copyDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri createDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull String, @NonNull String) throws java.io.FileNotFoundException; + method @Nullable public static android.content.IntentSender createWebLinkIntent(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @Nullable android.os.Bundle) throws java.io.FileNotFoundException; + method public static boolean deleteDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method public static void ejectRoot(@NonNull android.content.ContentResolver, @NonNull android.net.Uri); + method @Nullable public static android.provider.DocumentsContract.Path findDocumentPath(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; method public static String getDocumentId(android.net.Uri); - method @Nullable public static android.os.Bundle getDocumentMetadata(@NonNull android.content.ContentInterface, @NonNull android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.os.Bundle getDocumentMetadata(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException; - method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentInterface, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException; - method @Deprecated public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException; + method @Nullable public static android.os.Bundle getDocumentMetadata(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.graphics.Bitmap getDocumentThumbnail(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.graphics.Point, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException; method public static String getRootId(android.net.Uri); method public static String getSearchDocumentsQuery(android.net.Uri); method public static String getTreeDocumentId(android.net.Uri); - method public static boolean isChildDocument(@NonNull android.content.ContentInterface, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean isChildDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; + method public static boolean isChildDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; method public static boolean isDocumentUri(android.content.Context, @Nullable android.net.Uri); method public static boolean isRootUri(@NonNull android.content.Context, @Nullable android.net.Uri); method public static boolean isRootsUri(@NonNull android.content.Context, @Nullable android.net.Uri); method public static boolean isTreeUri(android.net.Uri); - method public static android.net.Uri moveDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method public static boolean removeDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method public static android.net.Uri renameDocument(android.content.ContentInterface, android.net.Uri, String) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri moveDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method public static boolean removeDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri renameDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException; field public static final String ACTION_DOCUMENT_SETTINGS = "android.provider.action.DOCUMENT_SETTINGS"; field public static final String EXTRA_ERROR = "error"; field public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; diff --git a/api/system-current.txt b/api/system-current.txt index 8296eee38167..128ee99c27ad 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -304,7 +304,7 @@ package android.app { } public class AppOpsManager { - method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(int, @Nullable String, @Nullable String[], long, long, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); + method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); method public static String[] getOpStrs(); method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]); method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...); @@ -394,6 +394,17 @@ package android.app { field public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR; } + public static final class AppOpsManager.HistoricalOpsRequest { + } + + public static final class AppOpsManager.HistoricalOpsRequest.Builder { + ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build(); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int); + } + public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String); @@ -1284,11 +1295,11 @@ package android.bluetooth.le { package android.content { - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long); } - public abstract class ContentResolver implements android.content.ContentInterface { + public abstract class ContentResolver { method public android.os.Bundle getCache(android.net.Uri); method public android.graphics.drawable.Drawable getTypeDrawable(String); method public void putCache(android.net.Uri, android.os.Bundle); diff --git a/api/test-current.txt b/api/test-current.txt index 16098c1a80fa..01678b1c1066 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -101,8 +101,8 @@ package android.app { public class AppOpsManager { method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps); method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory(); - method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(int, @Nullable String, @Nullable String[], long, long, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); - method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOpsFromDiskRaw(int, @Nullable String, @Nullable String[], long, long, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); + method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); + method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); method public static int getNumOps(); method public static String[] getOpStrs(); method public boolean isOperationActive(int, int, String); @@ -206,6 +206,17 @@ package android.app { field public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR; } + public static final class AppOpsManager.HistoricalOpsRequest { + } + + public static final class AppOpsManager.HistoricalOpsRequest.Builder { + ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build(); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String); + method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int); + } + public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String); @@ -472,11 +483,11 @@ package android.bluetooth { package android.content { - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long); } - public abstract class ContentResolver implements android.content.ContentInterface { + public abstract class ContentResolver { method public static String[] getSyncAdapterPackagesForAuthorityAsUser(String, int); } diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt index dca3b525c06a..b328f2ac1955 100644 --- a/config/hiddenapi-force-blacklist.txt +++ b/config/hiddenapi-force-blacklist.txt @@ -1,4 +1,6 @@ Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V +Ldalvik/system/VMRuntime;->setTargetSdkVersion(I)V +Ldalvik/system/VMRuntime;->setTargetSdkVersionNative(I)V Ljava/lang/invoke/MethodHandles$Lookup;->IMPL_LOOKUP:Ljava/lang/invoke/MethodHandles$Lookup; Ljava/lang/invoke/VarHandle;->acquireFence()V Ljava/lang/invoke/VarHandle;->compareAndExchange([Ljava/lang/Object;)Ljava/lang/Object; diff --git a/config/hiddenapi-greylist-max-o.txt b/config/hiddenapi-greylist-max-o.txt index 4b6cc0ef7795..d9c1cd0313fc 100644 --- a/config/hiddenapi-greylist-max-o.txt +++ b/config/hiddenapi-greylist-max-o.txt @@ -109777,7 +109777,6 @@ Ldalvik/system/VMRuntime;->setHiddenApiAccessLogSamplingRate(I)V Ldalvik/system/VMRuntime;->setNonSdkApiUsageConsumer(Ljava/util/function/Consumer;)V Ldalvik/system/VMRuntime;->setProcessPackageName(Ljava/lang/String;)V Ldalvik/system/VMRuntime;->setSystemDaemonThreadPriority()V -Ldalvik/system/VMRuntime;->setTargetSdkVersionNative(I)V Ldalvik/system/VMRuntime;->startHeapTaskProcessor()V Ldalvik/system/VMRuntime;->startJitCompilation()V Ldalvik/system/VMRuntime;->stopHeapTaskProcessor()V diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index dc2ed4cc0d69..a836e8ef202f 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -170,7 +170,6 @@ Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo Landroid/app/IAssistDataReceiver$Stub;-><init>()V Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V -Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z Landroid/app/IInstrumentationWatcher$Stub;-><init>()V Landroid/app/IInstrumentationWatcher;->instrumentationStatus(Landroid/content/ComponentName;ILandroid/os/Bundle;)V Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 69c450cee364..7d828d87e278 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -259,10 +259,11 @@ public abstract class ActivityManagerInternal { public abstract void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid, long duration, String tag); - public abstract int broadcastIntentInPackage(String packageName, int uid, Intent intent, - String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, - boolean sticky, int userId, boolean allowBackgroundActivityStarts); + public abstract int broadcastIntentInPackage(String packageName, int uid, int realCallingUid, + int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, + int resultCode, String resultData, Bundle resultExtras, String requiredPermission, + Bundle bOptions, boolean serialized, boolean sticky, int userId, + boolean allowBackgroundActivityStarts); public abstract ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, boolean fgRequired, String callingPackage, int userId, boolean allowBackgroundActivityStarts) throws TransactionTooLargeException; diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index ce7199816726..bcbeb220bfb2 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -291,6 +291,9 @@ public class ActivityView extends ViewGroup { /** Send current location and size to the WM to set tap exclude region for this view. */ private void updateLocation() { + if (!isAttachedToWindow()) { + return; + } try { getLocationInWindow(mLocationInWindow); WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), @@ -429,6 +432,9 @@ public class ActivityView extends ViewGroup { /** Report to server that tap exclude region on hosting display should be cleared. */ private void cleanTapExcludeRegion() { + if (!isAttachedToWindow()) { + return; + } // Update tap exclude region with an empty rect to clean the state on server. try { WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 13eec580ec14..040ad062e512 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -46,6 +46,8 @@ import android.util.ArrayMap; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; + +import com.android.internal.annotations.Immutable; import com.android.internal.app.IAppOpsActiveCallback; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsNotedCallback; @@ -2210,6 +2212,115 @@ public class AppOpsManager { } /** + * Request for getting historical app op usage. The request acts + * as a filtering criteria when querying historical op usage. + * + * @hide + */ + @Immutable + @TestApi + @SystemApi + public static final class HistoricalOpsRequest { + private final int mUid; + private final @Nullable String mPackageName; + private final @Nullable List<String> mOpNames; + private final long mBeginTimeMillis; + private final long mEndTimeMillis; + + private HistoricalOpsRequest(int uid, @Nullable String packageName, + @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis) { + mUid = uid; + mPackageName = packageName; + mOpNames = opNames; + mBeginTimeMillis = beginTimeMillis; + mEndTimeMillis = endTimeMillis; + } + + /** + * Builder for creating a {@link HistoricalOpsRequest}. + * + * @hide + */ + @TestApi + @SystemApi + public static final class Builder { + private int mUid = Process.INVALID_UID; + private @Nullable String mPackageName; + private @Nullable List<String> mOpNames; + private final long mBeginTimeMillis; + private final long mEndTimeMillis; + + /** + * Creates a new builder. + * + * @param beginTimeMillis The beginning of the interval in milliseconds since + * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non + * negative. + * @param endTimeMillis The end of the interval in milliseconds since + * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after + * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent + * history including ops that happen while this call is in flight. + */ + public Builder(long beginTimeMillis, long endTimeMillis) { + Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis, + "beginTimeMillis must be non negative and lesser than endTimeMillis"); + mBeginTimeMillis = beginTimeMillis; + mEndTimeMillis = endTimeMillis; + } + + /** + * Sets the UID to query for. + * + * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid. + * @return This builder. + */ + public @NonNull Builder setUid(int uid) { + Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0, + "uid must be " + Process.INVALID_UID + " or non negative"); + mUid = uid; + return this; + } + + /** + * Sets the package to query for. + * + * @param packageName The package name. <code>Null</code> for any package. + * @return This builder. + */ + public @NonNull Builder setPackageName(@Nullable String packageName) { + mPackageName = packageName; + return this; + } + + /** + * Sets the op names to query for. + * + * @param opNames The op names. <code>Null</code> for any op. + * @return This builder. + */ + public @NonNull Builder setOpNames(@Nullable List<String> opNames) { + if (opNames != null) { + final int opCount = opNames.size(); + for (int i = 0; i < opCount; i++) { + Preconditions.checkArgument(AppOpsManager.strOpToOp( + opNames.get(i)) != AppOpsManager.OP_NONE); + } + } + mOpNames = opNames; + return this; + } + + /** + * @return a new {@link HistoricalOpsRequest}. + */ + public @NonNull HistoricalOpsRequest build() { + return new HistoricalOpsRequest(mUid, mPackageName, mOpNames, + mBeginTimeMillis, mEndTimeMillis); + } + } + } + + /** * This class represents historical app op state of all UIDs for a given time interval. * * @hide @@ -3671,26 +3782,7 @@ public class AppOpsManager { /** * Retrieve historical app op stats for a period. * - * <p>Historical data can be obtained - * for a specific package by specifying the <code>packageName</code> argument, - * for a specific UID if specifying the <code>uid</code> argument, for a - * specific package in a UID by specifying the <code>packageName</code> - * and the <code>uid</code> arguments, for all packages by passing - * {@link android.os.Process#INVALID_UID} and <code>null</code> for the - * <code>uid</code> and <code>packageName</code> arguments, respectively. - * Similarly, you can specify the <code>opNames</code> argument to get - * data only for these ops or <code>null</code> for all ops. - * - * @param uid The UID to query for. - * @param packageName The package to query for. - * @param beginTimeMillis The beginning of the interval in milliseconds since - * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non - * negative. - * @param endTimeMillis The end of the interval in milliseconds since - * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after - * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent - * history including ops that happen while this call is in flight. - * @param opNames The ops to query for. Pass {@code null} for all ops. + * @param request A request object describing the data being queried for. * @param executor Executor on which to run the callback. If <code>null</code> * the callback is executed on the default executor running on the main thread. * @param callback Callback on which to deliver the result. @@ -3702,13 +3794,13 @@ public class AppOpsManager { @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) - public void getHistoricalOps(int uid, @Nullable String packageName, - @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis, + public void getHistoricalOps(@NonNull HistoricalOpsRequest request, @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) { Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(callback, "callback cannot be null"); try { - mService.getHistoricalOps(uid, packageName, opNames, beginTimeMillis, endTimeMillis, + mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames, + request.mBeginTimeMillis, request.mEndTimeMillis, new RemoteCallback((result) -> { final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); final long identity = Binder.clearCallingIdentity(); @@ -3725,29 +3817,12 @@ public class AppOpsManager { /** * Retrieve historical app op stats for a period. - * - * <p>Historical data can be obtained - * for a specific package by specifying the <code>packageName</code> argument, - * for a specific UID if specifying the <code>uid</code> argument, for a - * specific package in a UID by specifying the <code>packageName</code> - * and the <code>uid</code> arguments, for all packages by passing - * {@link android.os.Process#INVALID_UID} and <code>null</code> for the - * <code>uid</code> and <code>packageName</code> arguments, respectively. - * Similarly, you can specify the <code>opNames</code> argument to get - * data only for these ops or <code>null</code> for all ops. * <p> * This method queries only the on disk state and the returned ops are raw, * which is their times are relative to the history start as opposed to the * epoch start. * - * @param uid The UID to query for. - * @param packageName The package to query for. - * @param beginTimeMillis The beginning of the interval in milliseconds since - * history start. History time grows as one goes into the past. - * @param endTimeMillis The end of the interval in milliseconds since - * history start. History time grows as one goes into the past. Must be after - * {@code beginTimeMillis}. - * @param opNames The ops to query for. Pass {@code null} for all ops. + * @param request A request object describing the data being queried for. * @param executor Executor on which to run the callback. If <code>null</code> * the callback is executed on the default executor running on the main thread. * @param callback Callback on which to deliver the result. @@ -3758,15 +3833,15 @@ public class AppOpsManager { */ @TestApi @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) - public void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName, - @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis, + public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request, @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) { Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(callback, "callback cannot be null"); try { - mService.getHistoricalOpsFromDiskRaw(uid, packageName, opNames, beginTimeMillis, - endTimeMillis, new RemoteCallback((result) -> { - final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); + mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName, + request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis, + new RemoteCallback((result) -> { + final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); final long identity = Binder.clearCallingIdentity(); try { executor.execute(() -> callback.accept(ops)); diff --git a/core/java/android/app/IInputForwarder.aidl b/core/java/android/app/IInputForwarder.aidl deleted file mode 100644 index d6be63eb54e5..000000000000 --- a/core/java/android/app/IInputForwarder.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.view.InputEvent; - -/** - * Forwards input events into owned activity container, used in {@link android.app.ActivityView}. - * To forward input to other apps {@link android.Manifest.permission.INJECT_EVENTS} permission is - * required. - * @hide - */ -interface IInputForwarder { - boolean forwardEvent(in InputEvent event); -}
\ No newline at end of file diff --git a/core/java/android/app/admin/TEST_MAPPING b/core/java/android/app/admin/TEST_MAPPING new file mode 100644 index 000000000000..8f88c2243d50 --- /dev/null +++ b/core/java/android/app/admin/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/services/devicepolicy" + } + ] +} diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java index 3d732eb7678d..d41d8d9cc1e2 100644 --- a/core/java/android/content/ContentInterface.java +++ b/core/java/android/content/ContentInterface.java @@ -36,6 +36,8 @@ import java.util.ArrayList; * These methods have been extracted into a general interface so that APIs can * be flexible in accepting either a {@link ContentProvider}, a * {@link ContentResolver}, or a {@link ContentProviderClient}. + * + * @hide */ public interface ContentInterface { public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index f138d39b7fb0..e06322df7a7f 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -134,7 +134,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall private boolean mNoPerms; private boolean mSingleUser; - private final ThreadLocal<String> mCallingPackage = new ThreadLocal<>(); + private ThreadLocal<String> mCallingPackage; private Transport mTransport = new Transport(); @@ -2034,6 +2034,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall private void attachInfo(Context context, ProviderInfo info, boolean testing) { mNoPerms = testing; + mCallingPackage = new ThreadLocal<>(); /* * Only allow it to be set once, so after the content service gives diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 7672ccfcd995..bbfa5cceec1d 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -609,10 +609,60 @@ public abstract class ContentResolver implements ContentInterface { private static final int SLOW_THRESHOLD_MILLIS = 500; private final Random mRandom = new Random(); // guarded by itself - public ContentResolver(Context context) { + public ContentResolver(@Nullable Context context) { + this(context, null); + } + + /** {@hide} */ + public ContentResolver(@Nullable Context context, @Nullable ContentInterface wrapped) { mContext = context != null ? context : ActivityThread.currentApplication(); mPackageName = mContext.getOpPackageName(); mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; + mWrapped = wrapped; + } + + /** {@hide} */ + public static ContentResolver wrap(@NonNull ContentInterface wrapped) { + Preconditions.checkNotNull(wrapped); + + return new ContentResolver(null, wrapped) { + @Override + public void unstableProviderDied(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + public boolean releaseUnstableProvider(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + public boolean releaseProvider(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + protected IContentProvider acquireUnstableProvider(Context c, String name) { + throw new UnsupportedOperationException(); + } + @Override + protected IContentProvider acquireProvider(Context c, String name) { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * Create a {@link ContentResolver} instance that redirects all its methods + * to the given {@link ContentProvider}. + */ + public static ContentResolver wrap(@NonNull ContentProvider wrapped) { + return wrap((ContentInterface) wrapped); + } + + /** + * Create a {@link ContentResolver} instance that redirects all its methods + * to the given {@link ContentProviderClient}. + */ + public static ContentResolver wrap(@NonNull ContentProviderClient wrapped) { + return wrap((ContentInterface) wrapped); } /** @hide */ @@ -660,6 +710,12 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable String getType(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + try { + if (mWrapped != null) return mWrapped.getType(url); + } catch (RemoteException e) { + return null; + } + // XXX would like to have an acquireExistingUnstableProvider for this. IContentProvider provider = acquireExistingProvider(url); if (provider != null) { @@ -715,6 +771,12 @@ public abstract class ContentResolver implements ContentInterface { Preconditions.checkNotNull(url, "url"); Preconditions.checkNotNull(mimeTypeFilter, "mimeTypeFilter"); + try { + if (mWrapped != null) return mWrapped.getStreamTypes(url, mimeTypeFilter); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -843,6 +905,15 @@ public abstract class ContentResolver implements ContentInterface { @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(uri, "uri"); + + try { + if (mWrapped != null) { + return mWrapped.query(uri, projection, queryArgs, cancellationSignal); + } + } catch (RemoteException e) { + return null; + } + IContentProvider unstableProvider = acquireUnstableProvider(uri); if (unstableProvider == null) { return null; @@ -942,6 +1013,13 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable Uri canonicalize(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.canonicalize(url); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -979,6 +1057,13 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable Uri uncanonicalize(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.uncanonicalize(url); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -1015,6 +1100,13 @@ public abstract class ContentResolver implements ContentInterface { public final boolean refresh(@NonNull Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.refresh(url, args, cancellationSignal); + } catch (RemoteException e) { + return false; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return false; @@ -1126,6 +1218,12 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) return mWrapped.openFile(uri, mode, signal); + } catch (RemoteException e) { + return null; + } + return openFileDescriptor(uri, mode, signal); } @@ -1237,6 +1335,12 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) return mWrapped.openAssetFile(uri, mode, signal); + } catch (RemoteException e) { + return null; + } + return openAssetFileDescriptor(uri, mode, signal); } @@ -1448,6 +1552,14 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri, @NonNull String mimeTypeFilter, @Nullable Bundle opts, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) { + return mWrapped.openTypedAssetFile(uri, mimeTypeFilter, opts, signal); + } + } catch (RemoteException e) { + return null; + } + return openTypedAssetFileDescriptor(uri, mimeTypeFilter, opts, signal); } @@ -1664,6 +1776,13 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url, @Nullable ContentValues values) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.insert(url, values); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1705,6 +1824,13 @@ public abstract class ContentResolver implements ContentInterface { throws RemoteException, OperationApplicationException { Preconditions.checkNotNull(authority, "authority"); Preconditions.checkNotNull(operations, "operations"); + + try { + if (mWrapped != null) return mWrapped.applyBatch(authority, operations); + } catch (RemoteException e) { + return null; + } + ContentProviderClient provider = acquireContentProviderClient(authority); if (provider == null) { throw new IllegalArgumentException("Unknown authority " + authority); @@ -1731,6 +1857,13 @@ public abstract class ContentResolver implements ContentInterface { @NonNull ContentValues[] values) { Preconditions.checkNotNull(url, "url"); Preconditions.checkNotNull(values, "values"); + + try { + if (mWrapped != null) return mWrapped.bulkInsert(url, values); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1764,6 +1897,13 @@ public abstract class ContentResolver implements ContentInterface { public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable String where, @Nullable String[] selectionArgs) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.delete(url, where, selectionArgs); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1801,6 +1941,13 @@ public abstract class ContentResolver implements ContentInterface { @Nullable ContentValues values, @Nullable String where, @Nullable String[] selectionArgs) { Preconditions.checkNotNull(uri, "uri"); + + try { + if (mWrapped != null) return mWrapped.update(uri, values, where, selectionArgs); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(uri); if (provider == null) { throw new IllegalArgumentException("Unknown URI " + uri); @@ -1844,6 +1991,13 @@ public abstract class ContentResolver implements ContentInterface { @Nullable String arg, @Nullable Bundle extras) { Preconditions.checkNotNull(authority, "authority"); Preconditions.checkNotNull(method, "method"); + + try { + if (mWrapped != null) return mWrapped.call(authority, method, arg, extras); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(authority); if (provider == null) { throw new IllegalArgumentException("Unknown authority " + authority); @@ -3193,6 +3347,7 @@ public abstract class ContentResolver implements ContentInterface { @UnsupportedAppUsage final String mPackageName; final int mTargetSdkVersion; + final ContentInterface mWrapped; private static final String TAG = "ContentResolver"; diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java index f413d7cc92af..0c07a67e917d 100644 --- a/core/java/android/hardware/display/ColorDisplayManager.java +++ b/core/java/android/hardware/display/ColorDisplayManager.java @@ -65,7 +65,8 @@ public final class ColorDisplayManager { @SystemApi public static final int CAPABILITY_NONE = 0x0; /** - * The device can properly apply transforms over protected content. + * The device can use GPU composition on protected content (layers whose buffers are protected + * in the trusted memory zone). * * @hide */ diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 44b653c314ad..8a0a9c7c9d9d 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -563,7 +563,8 @@ public final class DisplayManager { * 0 produces a grayscale image, 1 is normal. * * @hide - * @deprecated use {@link ColorDisplayManager#setSaturationLevel(int)}. + * @deprecated use {@link ColorDisplayManager#setSaturationLevel(int)} instead. The level passed + * as a parameter here will be rounded to the nearest hundredth. */ @SystemApi @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_SATURATION) diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 97868fa268ad..64448fd98bf3 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -16,7 +16,6 @@ package android.hardware.input; -import android.app.IInputForwarder; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.KeyboardLayout; import android.hardware.input.IInputDevicesChangedListener; @@ -82,7 +81,4 @@ interface IInputManager { void setCustomPointerIcon(in PointerIcon icon); void requestPointerCapture(IBinder windowToken, boolean enabled); - - /** Create input forwarder to deliver touch events to owned display. */ - IInputForwarder createInputForwarder(int displayId); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index bfb7c58c2dc9..fec5c34fab28 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -21,7 +21,6 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; -import android.app.IInputForwarder; import android.content.Context; import android.media.AudioAttributes; import android.os.Binder; @@ -934,26 +933,6 @@ public final class InputManager { } } - - /** - * Create an {@link IInputForwarder} targeted to provided display. - * {@link android.Manifest.permission.INJECT_EVENTS} permission is required to call this method. - * - * @param displayId Id of the target display where input events should be forwarded. - * Display must exist and must be owned by the caller. - * @return The forwarder instance. - * - * @hide - */ - @UnsupportedAppUsage - public IInputForwarder createInputForwarder(int displayId) { - try { - return mIm.createInputForwarder(displayId); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } - } - private void populateInputDevicesLocked() { if (mInputDevicesChangedListener == null) { final InputDevicesChangedListener listener = new InputDevicesChangedListener(); diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 570834265237..d28296786759 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -1281,8 +1281,9 @@ public final class DocumentsContract { * @see DocumentsProvider#openDocumentThumbnail(String, Point, * android.os.CancellationSignal) */ - public static Bitmap getDocumentThumbnail(ContentInterface content, Uri documentUri, Point size, - CancellationSignal signal) throws FileNotFoundException { + public static @Nullable Bitmap getDocumentThumbnail(@NonNull ContentResolver content, + @NonNull Uri documentUri, @NonNull Point size, @Nullable CancellationSignal signal) + throws FileNotFoundException { try { return ContentResolver.loadThumbnail(content, documentUri, Point.convert(size), signal, ImageDecoder.ALLOCATOR_SOFTWARE); @@ -1295,12 +1296,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Bitmap getDocumentThumbnail(ContentResolver content, Uri documentUri, Point size, - CancellationSignal signal) throws FileNotFoundException { - return getDocumentThumbnail((ContentInterface) content, documentUri, size, signal); - } - /** * Create a new document with given MIME type and display name. * @@ -1309,8 +1304,9 @@ public final class DocumentsContract { * @param displayName name of new document * @return newly created document, or {@code null} if failed */ - public static Uri createDocument(ContentInterface content, Uri parentDocumentUri, - String mimeType, String displayName) throws FileNotFoundException { + public static @Nullable Uri createDocument(@NonNull ContentResolver content, + @NonNull Uri parentDocumentUri, @NonNull String mimeType, @NonNull String displayName) + throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri); @@ -1327,12 +1323,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri createDocument(ContentResolver content, Uri parentDocumentUri, - String mimeType, String displayName) throws FileNotFoundException { - return createDocument((ContentInterface) content, parentDocumentUri, mimeType, displayName); - } - /** * Test if a document is descendant (child, grandchild, etc) from the given * parent. @@ -1342,7 +1332,7 @@ public final class DocumentsContract { * @return if given document is a descendant of the given parent. * @see Root#FLAG_SUPPORTS_IS_CHILD */ - public static boolean isChildDocument(@NonNull ContentInterface content, + public static boolean isChildDocument(@NonNull ContentResolver content, @NonNull Uri parentDocumentUri, @NonNull Uri childDocumentUri) throws FileNotFoundException { Preconditions.checkNotNull(content, "content can not be null"); @@ -1369,12 +1359,6 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean isChildDocument(ContentResolver content, Uri parentDocumentUri, - Uri childDocumentUri) throws FileNotFoundException { - return isChildDocument((ContentInterface) content, parentDocumentUri, childDocumentUri); - } - /** * Change the display name of an existing document. * <p> @@ -1388,8 +1372,8 @@ public final class DocumentsContract { * @return the existing or new document after the rename, or {@code null} if * failed. */ - public static Uri renameDocument(ContentInterface content, Uri documentUri, - String displayName) throws FileNotFoundException { + public static @Nullable Uri renameDocument(@NonNull ContentResolver content, + @NonNull Uri documentUri, @NonNull String displayName) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, documentUri); @@ -1406,19 +1390,13 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri renameDocument(ContentResolver content, Uri documentUri, - String displayName) throws FileNotFoundException { - return renameDocument((ContentInterface) content, documentUri, displayName); - } - /** * Delete the given document. * * @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE} * @return if the document was deleted successfully. */ - public static boolean deleteDocument(ContentInterface content, Uri documentUri) + public static boolean deleteDocument(@NonNull ContentResolver content, @NonNull Uri documentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); @@ -1434,12 +1412,6 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean deleteDocument(ContentResolver content, Uri documentUri) - throws FileNotFoundException { - return deleteDocument((ContentInterface) content, documentUri); - } - /** * Copies the given document. * @@ -1448,8 +1420,9 @@ public final class DocumentsContract { * document's copy. * @return the copied document, or {@code null} if failed. */ - public static Uri copyDocument(ContentInterface content, Uri sourceDocumentUri, - Uri targetParentDocumentUri) throws FileNotFoundException { + public static @Nullable Uri copyDocument(@NonNull ContentResolver content, + @NonNull Uri sourceDocumentUri, @NonNull Uri targetParentDocumentUri) + throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri); @@ -1465,12 +1438,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri copyDocument(ContentResolver content, Uri sourceDocumentUri, - Uri targetParentDocumentUri) throws FileNotFoundException { - return copyDocument((ContentInterface) content, sourceDocumentUri, targetParentDocumentUri); - } - /** * Moves the given document under a new parent. * @@ -1480,8 +1447,9 @@ public final class DocumentsContract { * document. * @return the moved document, or {@code null} if failed. */ - public static Uri moveDocument(ContentInterface content, Uri sourceDocumentUri, - Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws FileNotFoundException { + public static @Nullable Uri moveDocument(@NonNull ContentResolver content, + @NonNull Uri sourceDocumentUri, @NonNull Uri sourceParentDocumentUri, + @NonNull Uri targetParentDocumentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri); @@ -1498,13 +1466,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri moveDocument(ContentResolver content, Uri sourceDocumentUri, - Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws FileNotFoundException { - return moveDocument((ContentInterface) content, sourceDocumentUri, sourceParentDocumentUri, - targetParentDocumentUri); - } - /** * Removes the given document from a parent directory. * @@ -1515,8 +1476,8 @@ public final class DocumentsContract { * @param parentDocumentUri parent document of the document to remove. * @return true if the document was removed successfully. */ - public static boolean removeDocument(ContentInterface content, Uri documentUri, - Uri parentDocumentUri) throws FileNotFoundException { + public static boolean removeDocument(@NonNull ContentResolver content, @NonNull Uri documentUri, + @NonNull Uri parentDocumentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, documentUri); @@ -1532,34 +1493,23 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean removeDocument(ContentResolver content, Uri documentUri, - Uri parentDocumentUri) throws FileNotFoundException { - return removeDocument((ContentInterface) content, documentUri, parentDocumentUri); - } - /** * Ejects the given root. It throws {@link IllegalStateException} when ejection failed. * * @param rootUri root with {@link Root#FLAG_SUPPORTS_EJECT} to be ejected */ - public static void ejectRoot(ContentInterface content, Uri rootUri) { + public static void ejectRoot(@NonNull ContentResolver content, @NonNull Uri rootUri) { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, rootUri); content.call(rootUri.getAuthority(), METHOD_EJECT_ROOT, null, in); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); + } catch (Exception e) { + Log.w(TAG, "Failed to eject", e); } } - @Deprecated - public static void ejectRoot(ContentResolver content, Uri rootUri) { - ejectRoot((ContentInterface) content, rootUri); - } - /** * Returns metadata associated with the document. The type of metadata returned * is specific to the document type. For example the data returned for an image @@ -1590,7 +1540,7 @@ public final class DocumentsContract { * @param documentUri a Document URI * @return a Bundle of Bundles. */ - public static @Nullable Bundle getDocumentMetadata(@NonNull ContentInterface content, + public static @Nullable Bundle getDocumentMetadata(@NonNull ContentResolver content, @NonNull Uri documentUri) throws FileNotFoundException { Preconditions.checkNotNull(content, "content can not be null"); Preconditions.checkNotNull(documentUri, "documentUri can not be null"); @@ -1607,12 +1557,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Bundle getDocumentMetadata(ContentResolver content, Uri documentUri) - throws FileNotFoundException { - return getDocumentMetadata((ContentInterface) content, documentUri); - } - /** * Finds the canonical path from the top of the document tree. * @@ -1626,8 +1570,8 @@ public final class DocumentsContract { * @return the path of the document, or {@code null} if failed. * @see DocumentsProvider#findDocumentPath(String, String) */ - public static Path findDocumentPath(ContentInterface content, Uri treeUri) - throws FileNotFoundException { + public static @Nullable Path findDocumentPath(@NonNull ContentResolver content, + @NonNull Uri treeUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, treeUri); @@ -1642,12 +1586,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Path findDocumentPath(ContentResolver content, Uri treeUri) - throws FileNotFoundException { - return findDocumentPath((ContentInterface) content, treeUri); - } - /** * Creates an intent for obtaining a web link for the specified document. * @@ -1699,8 +1637,8 @@ public final class DocumentsContract { * @see DocumentsProvider#createWebLinkIntent(String, Bundle) * @see Intent#EXTRA_EMAIL */ - public static IntentSender createWebLinkIntent(ContentInterface content, Uri uri, - Bundle options) throws FileNotFoundException { + public static @Nullable IntentSender createWebLinkIntent(@NonNull ContentResolver content, + @NonNull Uri uri, @Nullable Bundle options) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, uri); @@ -1721,12 +1659,6 @@ public final class DocumentsContract { } } - @Deprecated - public static IntentSender createWebLinkIntent(ContentResolver content, Uri uri, - Bundle options) throws FileNotFoundException { - return createWebLinkIntent((ContentInterface) content, uri, options); - } - /** * Open the given image for thumbnail purposes, using any embedded EXIF * thumbnail if available, and providing orientation hints from the parent diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index c4ab91f8b429..8a90cade35a2 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -44,9 +44,9 @@ interface IAppOpsService { int checkPackage(int uid, String packageName); List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops); List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops); - void getHistoricalOps(int uid, String packageName, in String[] ops, long beginTimeMillis, + void getHistoricalOps(int uid, String packageName, in List<String> ops, long beginTimeMillis, long endTimeMillis, in RemoteCallback callback); - void getHistoricalOpsFromDiskRaw(int uid, String packageName, in String[] ops, + void getHistoricalOpsFromDiskRaw(int uid, String packageName, in List<String> ops, long beginTimeMillis, long endTimeMillis, in RemoteCallback callback); void offsetHistory(long duration); void setHistoryParameters(int mode, long baseSnapshotInterval, int compressionStep); diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index a8ad8102c610..c46f86792764 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -137,6 +137,7 @@ public class DividerSnapAlgorithm { mDismissStartTarget = mTargets.get(0); mDismissEndTarget = mTargets.get(mTargets.size() - 1); mMiddleTarget = mTargets.get(mTargets.size() / 2); + mMiddleTarget.isMiddleTarget = true; } /** @@ -438,6 +439,8 @@ public class DividerSnapAlgorithm { public final int flag; + public boolean isMiddleTarget; + /** * Multiplier used to calculate distance to snap position. The lower this value, the harder * it's to snap on this target diff --git a/core/res/res/layout/notification_material_media_seekbar.xml b/core/res/res/layout/notification_material_media_seekbar.xml index 1b691d68a201..c23ca835433e 100644 --- a/core/res/res/layout/notification_material_media_seekbar.xml +++ b/core/res/res/layout/notification_material_media_seekbar.xml @@ -30,6 +30,7 @@ android:maxHeight="3dp" android:paddingTop="24dp" android:paddingBottom="24dp" + android:clickable="true" android:layout_marginBottom="-24dp" android:layout_marginTop="-12dp" android:splitTrack="false" diff --git a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java index 02a9adf4fb4d..bff6b5fb3d24 100644 --- a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java +++ b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java @@ -60,7 +60,8 @@ public class DocumentsProviderTest extends ProviderTestCase2<TestDocumentsProvid DocumentsContract.buildDocumentUri(TestDocumentsProvider.AUTHORITY, DOCUMENT_ID); try (ContentProviderClient client = mResolver.acquireUnstableContentProviderClient(docUri)) { - final Path actual = DocumentsContract.findDocumentPath(client, docUri); + final Path actual = DocumentsContract.findDocumentPath( + ContentResolver.wrap(client), docUri); assertEquals(expected, actual); } } diff --git a/media/OWNERS b/media/OWNERS index 03b751c07c6c..eb26367d3d29 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -11,3 +11,6 @@ lajos@google.com marcone@google.com sungsoo@google.com wjia@google.com + +# For maintaining sync with AndroidX code +per-file ExifInterface.java = jinpark@google.com, sungsoo@google.com diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index e0d178fb9a1e..29ae1b29792b 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -137,6 +137,7 @@ android_app { static_libs: [ "SystemUI-core", ], + resource_dirs: [], platform_apis: true, product_specific: true, diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 7a7d1f6b1f04..bb34a878a0d8 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -461,6 +461,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mSnapAlgorithm == null) { mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth, mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide); + if (mSnapTargetBeforeMinimized != null && mSnapTargetBeforeMinimized.isMiddleTarget) { + mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget(); + } } if (mMinimizedSnapAlgorithm == null) { mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index 8160e04d6865..6714b0aea261 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -660,7 +660,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { ++mCount; } catch (Exception e) { Slog.e(TAG, "Error when attempting restore: " + e.toString()); - keyValueAgentErrorCleanup(); + keyValueAgentErrorCleanup(false); executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } } @@ -686,6 +686,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { boolean staging = !packageName.equals("android"); ParcelFileDescriptor stage; File downloadFile = (staging) ? mStageName : mBackupDataName; + boolean startedAgentRestore = false; try { IBackupTransport transport = @@ -766,13 +767,15 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(); backupManagerService.prepareOperationTimeout( mEphemeralOpToken, restoreAgentTimeoutMillis, this, OP_TYPE_RESTORE_WAIT); + startedAgentRestore = true; mAgent.doRestore(mBackupData, appVersionCode, mNewState, mEphemeralOpToken, backupManagerService.getBackupManagerBinder()); } catch (Exception e) { Slog.e(TAG, "Unable to call app for restore: " + packageName, e); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString()); - keyValueAgentErrorCleanup(); // clears any pending timeout messages as well + // Clears any pending timeout messages as well. + keyValueAgentErrorCleanup(startedAgentRestore); // After a restore failure we go back to running the queue. If there // are no more packages to be restored that will be handled by the @@ -832,7 +835,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { Slog.e(TAG, "Unable to finalize restore of " + packageName); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString()); - keyValueAgentErrorCleanup(); + keyValueAgentErrorCleanup(true); executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } } @@ -1110,11 +1113,18 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { mListener.onFinished(callerLogString); } - void keyValueAgentErrorCleanup() { - // If the agent fails restore, it might have put the app's data - // into an incoherent state. For consistency we wipe its data - // again in this case before continuing with normal teardown - backupManagerService.clearApplicationDataAfterRestoreFailure(mCurrentPackage.packageName); + /** + * @param clearAppData - set to {@code true} if the backup agent had already been invoked when + * restore faied. So the app data may be in corrupted state and has to be cleared. + */ + void keyValueAgentErrorCleanup(boolean clearAppData) { + if (clearAppData) { + // If the agent fails restore, it might have put the app's data + // into an incoherent state. For consistency we wipe its data + // again in this case before continuing with normal teardown + backupManagerService.clearApplicationDataAfterRestoreFailure( + mCurrentPackage.packageName); + } keyValueAgentCleanup(); } @@ -1251,7 +1261,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // Some kind of horrible semantic error; we're in an unexpected state. // Back off hard and wind up. Slog.e(TAG, "Unexpected restore callback into state " + mState); - keyValueAgentErrorCleanup(); + keyValueAgentErrorCleanup(true); nextState = UnifiedRestoreState.FINAL; break; } @@ -1271,7 +1281,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, mCurrentPackage.packageName, "restore timeout"); // Handle like an agent that threw on invocation: wipe it and go on to the next - keyValueAgentErrorCleanup(); + keyValueAgentErrorCleanup(true); executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2f20572caa99..3c0430fe0adf 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2704,8 +2704,8 @@ public class ActivityManagerService extends IActivityManager.Stub public void batterySendBroadcast(Intent intent) { synchronized (this) { broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, - -1, SYSTEM_UID, UserHandle.USER_ALL); + OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); } } @@ -3823,12 +3823,13 @@ public class ActivityManagerService extends IActivityManager.Stub intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId); if (isInstantApp) { intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); - broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, - null, null, permission.ACCESS_INSTANT_APPS, null, false, false, - resolvedUserId, false); + broadcastIntentInPackage("android", SYSTEM_UID, uid, pid, intent, null, + null, 0, null, null, permission.ACCESS_INSTANT_APPS, null, false, + false, resolvedUserId, false); } else { - broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, - null, null, null, null, false, false, resolvedUserId, false); + broadcastIntentInPackage("android", SYSTEM_UID, uid, pid, intent, null, + null, 0, null, null, null, null, false, false, resolvedUserId, + false); } if (observer != null) { @@ -4263,7 +4264,8 @@ public class ActivityManagerService extends IActivityManager.Stub intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid)); + null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.getUserId(uid)); } private void cleanupDisabledPackageComponentsLocked( @@ -8709,6 +8711,8 @@ public class ActivityManagerService extends IActivityManager.Stub mAtmInternal.showSystemReadyErrorDialogsIfNeeded(); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); long ident = Binder.clearCallingIdentity(); try { Intent intent = new Intent(Intent.ACTION_USER_STARTED); @@ -8717,7 +8721,7 @@ public class ActivityManagerService extends IActivityManager.Stub intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, + null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, currentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -8731,7 +8735,8 @@ public class ActivityManagerService extends IActivityManager.Stub } }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { @@ -14369,10 +14374,12 @@ public class ActivityManagerService extends IActivityManager.Stub String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { + boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, + int realCallingPid, int userId) { return broadcastIntentLocked(callerApp, callerPackage, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, ordered, - sticky, callingPid, callingUid, userId, false /* allowBackgroundActivityStarts */); + sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId, + false /* allowBackgroundActivityStarts */); } @GuardedBy("this") @@ -14380,8 +14387,8 @@ public class ActivityManagerService extends IActivityManager.Stub String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int userId, - boolean allowBackgroundActivityStarts) { + boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, + int realCallingPid, int userId, boolean allowBackgroundActivityStarts) { intent = new Intent(intent); final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid); @@ -14430,7 +14437,7 @@ public class ActivityManagerService extends IActivityManager.Stub // PendingIntent), because that who is actually supplied the arguments. if (checkComponentPermission( android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, - Binder.getCallingPid(), Binder.getCallingUid(), -1, true) + realCallingPid, realCallingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid @@ -15118,15 +15125,15 @@ public class ActivityManagerService extends IActivityManager.Stub callerApp != null ? callerApp.info.packageName : null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, serialized, sticky, - callingPid, callingUid, userId); + callingPid, callingUid, callingUid, callingPid, userId); Binder.restoreCallingIdentity(origId); return res; } } - int broadcastIntentInPackage(String packageName, int uid, - Intent intent, String resolvedType, IIntentReceiver resultTo, + int broadcastIntentInPackage(String packageName, int uid, int realCallingUid, + int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, int userId, boolean allowBackgroundActivityStarts) { @@ -15139,7 +15146,8 @@ public class ActivityManagerService extends IActivityManager.Stub int res = broadcastIntentLocked(null, packageName, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, OP_NONE, bOptions, serialized, - sticky, -1, uid, userId, allowBackgroundActivityStarts); + sticky, -1, uid, realCallingUid, realCallingPid, userId, + allowBackgroundActivityStarts); Binder.restoreCallingIdentity(origId); return res; } @@ -17721,15 +17729,16 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public int broadcastIntentInPackage(String packageName, int uid, Intent intent, - String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, - boolean sticky, int userId, boolean allowBackgroundActivityStarts) { + public int broadcastIntentInPackage(String packageName, int uid, int realCallingUid, + int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, + int resultCode, String resultData, Bundle resultExtras, String requiredPermission, + Bundle bOptions, boolean serialized, boolean sticky, int userId, + boolean allowBackgroundActivityStarts) { synchronized (ActivityManagerService.this) { return ActivityManagerService.this.broadcastIntentInPackage(packageName, uid, - intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermission, bOptions, serialized, sticky, userId, - allowBackgroundActivityStarts); + realCallingUid, realCallingPid, intent, resolvedType, resultTo, resultCode, + resultData, resultExtras, requiredPermission, bOptions, serialized, sticky, + userId, allowBackgroundActivityStarts); } } @@ -17830,8 +17839,8 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); + OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND @@ -17841,8 +17850,8 @@ public class ActivityManagerService extends IActivityManager.Stub intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); + OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); } // Send a broadcast to PackageInstallers if the configuration change is interesting @@ -17857,7 +17866,7 @@ public class ActivityManagerService extends IActivityManager.Stub new String[] { android.Manifest.permission.INSTALL_PACKAGES }; broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); + Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } } } @@ -17881,7 +17890,8 @@ public class ActivityManagerService extends IActivityManager.Stub } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, -1, SYSTEM_UID, UserHandle.USER_ALL); + OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index af56352b8cc0..a08c829f0576 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -423,9 +423,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub { // If a completion callback has been requested, require // that the broadcast be delivered synchronously int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName, - uid, finalIntent, resolvedType, finishedReceiver, code, null, null, - requiredPermission, options, (finishedReceiver != null), - false, userId, + uid, callingUid, callingPid, finalIntent, resolvedType, + finishedReceiver, code, null, null, requiredPermission, options, + (finishedReceiver != null), false, userId, mAllowBgActivityStartsForBroadcastSender.contains(whitelistToken) || allowTrampoline); if (sent == ActivityManager.BROADCAST_SUCCESS) { diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java index 3ea114758498..376999dfd80d 100644 --- a/services/core/java/com/android/server/am/PreBootBroadcaster.java +++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -108,7 +109,7 @@ public abstract class PreBootBroadcaster extends IIntentReceiver.Stub { mIntent.setComponent(componentName); mService.broadcastIntentLocked(null, null, mIntent, null, this, 0, null, null, null, AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID, - Process.SYSTEM_UID, mUserId); + Process.SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), mUserId); } @Override diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 7f6648a3d174..ac20f6c7eaaf 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -371,7 +371,8 @@ class UserController implements Handler.Callback { | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mInjector.broadcastIntent(intent, null, resultTo, 0, null, null, new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, - AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId); + AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, + Binder.getCallingUid(), Binder.getCallingPid(), userId); } // We need to delay unlocking managed profiles until the parent user @@ -471,7 +472,7 @@ class UserController implements Handler.Callback { Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); mInjector.broadcastIntent(unlockedIntent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - userId); + Binder.getCallingUid(), Binder.getCallingPid(), userId); if (getUserInfo(userId).isManagedProfile()) { UserInfo parent = mInjector.getUserManager().getProfileParent(userId); @@ -484,8 +485,8 @@ class UserController implements Handler.Callback { | Intent.FLAG_RECEIVER_FOREGROUND); mInjector.broadcastIntent(profileUnlockedIntent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, - parent.id); + null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), parent.id); } } @@ -543,7 +544,8 @@ class UserController implements Handler.Callback { mInjector.getUserManager().makeInitialized(userInfo.id); } }, 0, null, null, null, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, userId); + null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), userId); } } @@ -573,7 +575,8 @@ class UserController implements Handler.Callback { } }, 0, null, null, new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, - AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId); + AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, + Binder.getCallingUid(), Binder.getCallingPid(), userId); } int restartUser(final int userId, final boolean foreground) { @@ -696,7 +699,8 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(stoppingIntent, null, stoppingReceiver, 0, null, null, new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); }); } } @@ -735,7 +739,8 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(shutdownIntent, null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, userId); + null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), userId); } void finishUserStopped(UserState uss) { @@ -834,7 +839,8 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); + null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + Binder.getCallingPid(), UserHandle.USER_ALL); } /** @@ -950,6 +956,8 @@ class UserController implements Handler.Callback { Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); final long ident = Binder.clearCallingIdentity(); try { final int oldUserId = getCurrentUserId(); @@ -1088,7 +1096,7 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, userId); + null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); } if (foreground) { @@ -1111,7 +1119,8 @@ class UserController implements Handler.Callback { } }, 0, null, null, new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + UserHandle.USER_ALL); } } finally { Binder.restoreCallingIdentity(ident); @@ -1427,6 +1436,8 @@ class UserController implements Handler.Callback { } void sendUserSwitchBroadcasts(int oldUserId, int newUserId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); long ident = Binder.clearCallingIdentity(); try { Intent intent; @@ -1442,7 +1453,8 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, profileUserId); + null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + profileUserId); } } if (newUserId >= 0) { @@ -1457,7 +1469,8 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, profileUserId); + null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + profileUserId); } intent = new Intent(Intent.ACTION_USER_SWITCHED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY @@ -1466,8 +1479,8 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(intent, null, null, 0, null, null, new String[] {android.Manifest.permission.MANAGE_USERS}, - AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); + AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid, + callingPid, UserHandle.USER_ALL); } } finally { Binder.restoreCallingIdentity(ident); @@ -2107,12 +2120,14 @@ class UserController implements Handler.Callback { protected int broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { + boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, + int realCallingPid, int userId) { // TODO b/64165549 Verify that mLock is not held before calling AMS methods synchronized (mService) { return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, - ordered, sticky, callingPid, callingUid, userId); + ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, + userId); } } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 0e3309088f21..70c28a854512 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -38,6 +38,7 @@ import android.app.ActivityThread; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; +import android.app.AppOpsManager.HistoricalOpsRequest; import android.app.AppOpsManagerInternal; import android.app.AppOpsManagerInternal.CheckOpsDelegate; import android.content.BroadcastReceiver; @@ -1024,25 +1025,29 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void getHistoricalOps(int uid, @NonNull String packageName, - @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis, + @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis, @NonNull RemoteCallback callback) { - Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0, - "uid must be " + Process.INVALID_UID + " or non negative"); - Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis, - "beginTimeMillis must be non negative and lesser than endTimeMillis"); + // Use the builder to validate arguments. + final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( + beginTimeMillis, endTimeMillis) + .setUid(uid) + .setPackageName(packageName) + .setOpNames(opNames) + .build(); Preconditions.checkNotNull(callback, "callback cannot be null"); - checkValidOpsOrNull(opNames); mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), "getHistoricalOps"); + final String[] opNamesArray = (opNames != null) + ? opNames.toArray(new String[opNames.size()]) : null; if (mHistoricalRegistry.getMode() == AppOpsManager.HISTORICAL_MODE_DISABLED) { // TODO (bug:122218838): Remove once the feature fully enabled. - getHistoricalPackagesOpsCompat(uid, packageName, opNames, beginTimeMillis, + getHistoricalPackagesOpsCompat(uid, packageName, opNamesArray, beginTimeMillis, endTimeMillis, callback); } else { // Must not hold the appops lock - mHistoricalRegistry.getHistoricalOps(uid, packageName, opNames, + mHistoricalRegistry.getHistoricalOps(uid, packageName, opNamesArray, beginTimeMillis, endTimeMillis, callback); } } @@ -1101,20 +1106,25 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName, - @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis, + @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis, @NonNull RemoteCallback callback) { - Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0, - "uid must be " + Process.INVALID_UID + " or non negative"); - Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis, - "beginTimeMillis must be non negative and lesser than endTimeMillis"); + // Use the builder to validate arguments. + final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( + beginTimeMillis, endTimeMillis) + .setUid(uid) + .setPackageName(packageName) + .setOpNames(opNames) + .build(); Preconditions.checkNotNull(callback, "callback cannot be null"); - checkValidOpsOrNull(opNames); mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), "getHistoricalOps"); + final String[] opNamesArray = (opNames != null) + ? opNames.toArray(new String[opNames.size()]) : null; + // Must not hold the appops lock - mHistoricalRegistry.getHistoricalOpsFromDiskRaw(uid, packageName, opNames, + mHistoricalRegistry.getHistoricalOpsFromDiskRaw(uid, packageName, opNamesArray, beginTimeMillis, endTimeMillis, callback); } @@ -4266,16 +4276,6 @@ public class AppOpsService extends IAppOpsService.Stub { return packageNames; } - private static void checkValidOpsOrNull(String[] opNames) { - if (opNames != null) { - for (String opName : opNames) { - if (AppOpsManager.strOpToOp(opName) == AppOpsManager.OP_NONE) { - throw new IllegalArgumentException("Unknown op: " + opName); - } - } - } - } - private final class ClientRestrictionState implements DeathRecipient { private final IBinder token; SparseArray<boolean[]> perUserRestrictions; diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java deleted file mode 100644 index 00af8398d0ff..000000000000 --- a/services/core/java/com/android/server/input/InputForwarder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.input; - -import android.app.IInputForwarder; -import android.hardware.input.InputManagerInternal; -import android.view.InputEvent; - -import com.android.server.LocalServices; - -import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC; - -/** - * Basic implementation of {@link IInputForwarder}. - */ -class InputForwarder extends IInputForwarder.Stub { - - private final InputManagerInternal mInputManagerInternal; - private final int mDisplayId; - - InputForwarder(int displayId) { - mDisplayId = displayId; - mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); - } - - @Override - public boolean forwardEvent(InputEvent event) { - event.setDisplayId(mDisplayId); - return mInputManagerInternal.injectInputEvent(event, INJECT_INPUT_EVENT_MODE_ASYNC); - } -}
\ No newline at end of file diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 28393a209111..87c744138797 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -17,7 +17,6 @@ package com.android.server.input; import android.annotation.NonNull; -import android.app.IInputForwarder; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -1685,29 +1684,6 @@ public class InputManagerService extends IInputManager.Stub nativeMonitor(mPtr); } - // Binder call - @Override - public IInputForwarder createInputForwarder(int displayId) throws RemoteException { - if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, - "createInputForwarder()")) { - throw new SecurityException("Requires INJECT_EVENTS permission"); - } - final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); - final Display display = displayManager.getDisplay(displayId); - if (display == null) { - throw new IllegalArgumentException( - "Can't create input forwarder for non-existent displayId: " + displayId); - } - final int callingUid = Binder.getCallingUid(); - final int displayOwnerUid = display.getOwnerUid(); - if (callingUid != displayOwnerUid) { - throw new SecurityException( - "Only owner of the display can forward input events to it."); - } - - return new InputForwarder(displayId); - } - // Native callback. private void notifyConfigurationChanged(long whenNanos) { mWindowManagerCallbacks.notifyConfigurationChanged(); diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index dac4b6ff39c3..e12d1dc92714 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -167,6 +167,27 @@ class ApexManager { } /** + * Marks a staged session as successful. + * + * <p>Only activated session can be marked as successful. + * + * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as + * successful. + */ + void markStagedSessionSuccessful(int sessionId) { + try { + mApexService.markStagedSessionSuccessful(sessionId); + } catch (RemoteException re) { + Slog.e(TAG, "Unable to contact apexservice", re); + throw new RuntimeException(re); + } catch (Exception e) { + // It is fine to just log an exception in this case. APEXd will be able to recover in + // case markStagedSessionSuccessful fails. + Slog.e(TAG, "Failed to mark session " + sessionId + " as successful", e); + } + } + + /** * Dumps various state information to the provided {@link PrintWriter} object. * * @param pw the {@link PrintWriter} object to send information to. @@ -196,7 +217,7 @@ class ApexManager { ipw.increaseIndent(); final ApexSessionInfo[] sessions = mApexService.getSessions(); for (ApexSessionInfo si : sessions) { - ipw.println("Session ID: " + Integer.toString(si.sessionId)); + ipw.println("Session ID: " + si.sessionId); ipw.increaseIndent(); if (si.isUnknown) { ipw.println("State: UNKNOWN"); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 6c212d63d77c..d1ebc9400e4d 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -247,7 +247,8 @@ public class StagingManager { } private void resumeSession(@NonNull PackageInstallerSession session) { - if (sessionContainsApex(session)) { + boolean hasApex = sessionContainsApex(session); + if (hasApex) { // Check with apexservice whether the apex packages have been activated. ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId); if (apexSessionInfo == null) { @@ -271,7 +272,7 @@ public class StagingManager { mBgHandler.post(() -> preRebootVerification(session)); return; } - if (!apexSessionInfo.isActivated) { + if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) { // In all the remaining cases apexd will try to apply the session again at next // boot. Nothing to do here for now. Slog.w(TAG, "Staged session " + session.sessionId + " scheduled to be applied " @@ -287,7 +288,11 @@ public class StagingManager { + "more information."); return; } + session.setStagedSessionApplied(); + if (hasApex) { + mApexManager.markStagedSessionSuccessful(session.sessionId); + } } private String findFirstAPKInDir(File stageDir) { diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index ceaf829290d7..05d3c17e5c25 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -16,6 +16,7 @@ package com.android.server.rollback; +import android.annotation.NonNull; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -842,6 +843,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { String packageName = newPackage.packageName; for (PackageRollbackInfo info : rd.packages) { if (info.getPackageName().equals(packageName)) { + info.getInstalledUsers().addAll(IntArray.wrap(installedUsers)); AppDataRollbackHelper.SnapshotAppDataResult rs = mAppDataRollbackHelper.snapshotAppData(packageName, installedUsers); info.getPendingBackups().addAll(rs.pendingBackups); @@ -874,7 +876,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * the child sessions, not the parent session. */ private boolean enableRollbackForSession(PackageInstaller.SessionInfo session, - int[] installedUsers, boolean snapshotUserData) { + @NonNull int[] installedUsers, boolean snapshotUserData) { // TODO: Don't attempt to enable rollback for split installs. final int installFlags = session.installFlags; if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) { @@ -1016,7 +1018,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } if (!session.isMultiPackage()) { - if (!enableRollbackForSession(session, null, false)) { + if (!enableRollbackForSession(session, new int[0], false)) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); return; @@ -1030,7 +1032,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { result.offer(false); return; } - if (!enableRollbackForSession(childSession, null, false)) { + if (!enableRollbackForSession(childSession, new int[0], false)) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); return; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f33c518941e5..087de69b6c12 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -87,8 +87,6 @@ import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; import static android.os.Process.SYSTEM_UID; import static android.view.Display.INVALID_DISPLAY; -import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; -import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT; import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK; @@ -2828,28 +2826,6 @@ final class ActivityRecord extends ConfigurationContainer { outAppBounds.setEmpty(); } - // TODO(b/112288258): Remove below calculation because the position information in bounds - // will be replaced by the offset of surface. - final Rect appBounds = parentConfig.windowConfiguration.getAppBounds(); - if (appBounds != null) { - final Rect outBounds = inOutConfig.windowConfiguration.getBounds(); - final int activityWidth = outBounds.width(); - final int navBarPosition = mAtmService.mWindowManager.getNavBarPosition(getDisplayId()); - if (navBarPosition == NAV_BAR_LEFT) { - // Position the activity frame on the opposite side of the nav bar. - outBounds.left = appBounds.right - activityWidth; - outBounds.right = appBounds.right; - } else if (navBarPosition == NAV_BAR_RIGHT) { - // Position the activity frame on the opposite side of the nav bar. - outBounds.left = 0; - outBounds.right = activityWidth + appBounds.left; - } else if (appBounds.width() > activityWidth) { - // Horizontally center the frame. - outBounds.left = appBounds.left + (appBounds.width() - activityWidth) / 2; - outBounds.right = outBounds.left + activityWidth; - } - } - task.computeConfigResourceOverrides(inOutConfig, parentConfig, insideParentBounds); } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 0a3c2fba3930..c685b05e99e0 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -2332,6 +2332,20 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { if (!task.canBeLaunchedOnDisplay(actualDisplayId)) { throw new IllegalStateException("Task resolved to incompatible display"); } + + final ActivityDisplay preferredDisplay = + mRootActivityContainer.getActivityDisplay(preferredDisplayId); + + final boolean singleTaskInstance = preferredDisplay != null + && preferredDisplay.isSingleTaskInstance(); + + if (singleTaskInstance) { + // Suppress the warning toast if the preferredDisplay was set to singleTask. + // The singleTaskInstance displays will only contain one task and any attempt to + // launch new task will re-route to the default display. + return; + } + if (preferredDisplayId != actualDisplayId) { Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId); // Display a warning toast that we failed to put a task on a secondary display. diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java index 97062a6065e2..5c528c7f6047 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -568,7 +568,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { final long token = proto.start(fieldId); mRequestedOverrideConfiguration.writeToProto(proto, OVERRIDE_CONFIGURATION, - logLevel != WindowTraceLogLevel.CRITICAL); + logLevel == WindowTraceLogLevel.CRITICAL); if (logLevel == WindowTraceLogLevel.ALL) { mFullConfiguration.writeToProto(proto, FULL_CONFIGURATION, false /* critical */); mMergedOverrideConfiguration.writeToProto(proto, MERGED_OVERRIDE_CONFIGURATION, diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index ea65dd99077a..1d76a71aaea1 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -396,6 +396,10 @@ public class DockedStackDividerController { if (mAdjustedForIme != adjustedForIme || (adjustedForIme && mImeHeight != imeHeight) || mAdjustedForDivider != adjustedForDivider) { if (animate && !mAnimatingForMinimizedDockedStack) { + // Notify SystemUI to set the target docked stack size according current docked + // state without animation when calling startImeAdjustAnimation. + notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */, + isHomeStackResizable()); startImeAdjustAnimation(adjustedForIme, adjustedForDivider, imeWin); } else { // Animation might be delayed, so only notify if we don't run an animation. @@ -889,7 +893,10 @@ public class DockedStackDividerController { } if (mAnimatingForMinimizedDockedStack) { return animateForMinimizedDockedStack(now); - } else if (mAnimatingForIme) { + } else if (mAnimatingForIme && !mDisplayContent.mAppTransition.isRunning()) { + // To prevent task stack resize animation may flicking when playing app transition + // animation & IME window enter animation in parallel, make sure app transition is done + // and then start to animate for IME. return animateForIme(now); } return false; diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java index 59d7560fc5b0..9d3112fec0f2 100644 --- a/services/core/java/com/android/server/wm/TaskRecord.java +++ b/services/core/java/com/android/server/wm/TaskRecord.java @@ -2134,7 +2134,7 @@ class TaskRecord extends ConfigurationContainer { if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density); inOutConfig.screenHeightDp = insideParentBounds - ? Math.min(overrideScreenHeightDp, parentConfig.screenWidthDp) + ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp) : overrideScreenHeightDp; } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 7b742fd2e0f3..b91519903eb8 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1163,6 +1163,14 @@ public class TaskStack extends WindowContainer<Task> implements } private boolean adjustForIME(final WindowState imeWin) { + // To prevent task stack resize animation may flicking when playing app transition + // animation & IME window enter animation in parallel, we need to make sure app + // transition is done and then adjust task size for IME, skip the new adjusted frame when + // app transition is still running. + if (getDisplayContent().mAppTransition.isRunning()) { + return false; + } + final int dockedSide = getDockSide(); final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM; if (imeWin == null || !dockedTopOrBottom) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 3430987f4736..21a557e6809e 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2164,9 +2164,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // A modal window uses the whole compatibility bounds. flags |= FLAG_NOT_TOUCH_MODAL; mTmpRect.set(mAppToken.getResolvedOverrideBounds()); - // TODO(b/112288258): Remove the forced offset when the override bounds always - // starts from zero (See {@link ActivityRecord#resolveOverrideConfiguration}). - mTmpRect.offsetTo(0, 0); } else { // Non-modal uses the application based frame. mTmpRect.set(mWindowFrames.mCompatFrame); diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING new file mode 100644 index 000000000000..ab85a6873cf6 --- /dev/null +++ b/services/devicepolicy/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "postsubmit": [ + { + "name": "CtsDevicePolicyManagerTestCases" + } + ] +} diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index bd03a8d22643..04abeca1192e 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -403,7 +403,8 @@ public class UserControllerTest { protected int broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, - boolean sticky, int callingPid, int callingUid, int userId) { + boolean sticky, int callingPid, int callingUid, int realCallingUid, + int realCallingPid, int userId) { Log.i(TAG, "broadcastIntentLocked " + intent); mSentIntents.add(intent); return 0; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 8c36905d8422..a1db3e8d8ded 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -27,9 +27,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; -import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; -import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT; -import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT; import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING; import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; @@ -158,35 +155,6 @@ public class ActivityRecordTests extends ActivityTestsBase { assertTrue(mActivity.isState(STOPPED)); } - @Test - public void testPositionLimitedAspectRatioNavBarBottom() { - verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f, - new Rect(0, 0, 1000, 1500)); - } - - @Test - public void testPositionLimitedAspectRatioNavBarLeft() { - verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f, - new Rect(500, 0, 2000, 1000)); - } - - @Test - public void testPositionLimitedAspectRatioNavBarRight() { - verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f, - new Rect(0, 0, 1500, 1000)); - } - - private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds, - float aspectRatio, Rect expectedActivityBounds) { - // Verify with nav bar on the right. - when(mService.mWindowManager.getNavBarPosition(mActivity.getDisplayId())) - .thenReturn(navBarPosition); - mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds); - mActivity.info.maxAspectRatio = aspectRatio; - ensureActivityConfiguration(); - assertEquals(expectedActivityBounds, mActivity.getBounds()); - } - private void ensureActivityConfiguration() { mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index bcf9dd218835..388f98ffe4a3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -24,6 +24,7 @@ import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.util.DisplayMetrics.DENSITY_DEFAULT; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -307,6 +308,41 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(fullScreenBounds, task.getBounds()); } + @Test + public void testComputeConfigResourceOverrides() { + final TaskRecord task = new TaskBuilder(mSupervisor).build(); + final Configuration inOutConfig = new Configuration(); + final Configuration parentConfig = new Configuration(); + final int longSide = 1200; + final int shortSide = 600; + parentConfig.densityDpi = 400; + parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px + parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px + + // Portrait bounds. + inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide); + // By default, the parent bounds should limit the existing input bounds. + task.computeConfigResourceOverrides(inOutConfig, parentConfig); + + assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp); + assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp); + assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation); + + inOutConfig.setToDefaults(); + // Landscape bounds. + inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide); + // Without limiting to be inside the parent bounds, the out screen size should keep relative + // to the input bounds. + task.computeConfigResourceOverrides(inOutConfig, parentConfig, + false /* insideParentBounds */); + + assertEquals(shortSide * DENSITY_DEFAULT / parentConfig.densityDpi, + inOutConfig.screenHeightDp); + assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi, + inOutConfig.screenWidthDp); + assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation); + } + /** Ensures that the alias intent won't have target component resolved. */ @Test public void testTaskIntentActivityAlias() { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 3eb9085b68f6..b0e20b89b811 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -35,6 +35,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; @@ -54,7 +55,6 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; import android.graphics.Insets; import android.graphics.Matrix; @@ -87,6 +87,7 @@ import java.util.LinkedList; */ @SmallTest @Presubmit +@FlakyTest(bugId = 124127512) public class WindowStateTests extends WindowTestsBase { private static int sPreviousNewInsetsMode; @@ -389,6 +390,7 @@ public class WindowStateTests extends WindowTestsBase { } @Test + @FlakyTest(bugId = 74078662) public void testLayoutSeqResetOnReparent() { final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); app.mLayoutSeq = 1; @@ -445,6 +447,7 @@ public class WindowStateTests extends WindowTestsBase { } @Test + @FlakyTest(bugId = 74078662) public void testDisplayCutoutIsCalculatedRelativeToFrame() { final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); WindowFrames wf = app.getWindowFrames(); diff --git a/tests/RollbackTest/Android.mk b/tests/RollbackTest/Android.mk index 40d4eff53577..0967ad3767c6 100644 --- a/tests/RollbackTest/Android.mk +++ b/tests/RollbackTest/Android.mk @@ -71,7 +71,7 @@ ROLLBACK_TEST_APP_BV2 := $(LOCAL_INSTALLED_MODULE) # RollbackTest include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := $(call all-java-files-under, RollbackTest/src) LOCAL_PACKAGE_NAME := RollbackTest LOCAL_MODULE_TAGS := tests LOCAL_STATIC_JAVA_LIBRARIES := android-support-test @@ -84,10 +84,21 @@ LOCAL_JAVA_RESOURCE_FILES := \ $(ROLLBACK_TEST_APP_BV1) \ $(ROLLBACK_TEST_APP_BV2) \ $(ROLLBACK_TEST_APEX_V2) +LOCAL_MANIFEST_FILE := RollbackTest/AndroidManifest.xml LOCAL_SDK_VERSION := system_current LOCAL_TEST_CONFIG := RollbackTest.xml include $(BUILD_PACKAGE) +# StagedRollbackTest +include $(CLEAR_VARS) +LOCAL_SRC_FILES := $(call all-java-files-under, StagedRollbackTest/src) +LOCAL_MODULE := StagedRollbackTest +LOCAL_MODULE_TAGS := tests +LOCAL_JAVA_LIBRARIES := tradefed +LOCAL_COMPATIBILITY_SUITE := general-tests +LOCAL_TEST_CONFIG := StagedRollbackTest.xml +include $(BUILD_HOST_JAVA_LIBRARY) + # Clean up local variables ROLLBACK_TEST_APP_AV1 := ROLLBACK_TEST_APP_AV2 := diff --git a/tests/RollbackTest/README.txt b/tests/RollbackTest/README.txt new file mode 100644 index 000000000000..c0b718a3e2c1 --- /dev/null +++ b/tests/RollbackTest/README.txt @@ -0,0 +1,23 @@ +This directory contains a test for the rollback manager service. + +Directory structure +=================== +RollbackTest + - device driven test for rollbacks not involving staged rollbacks. + +StagedRollbackTest + - device driven test for staged rollbacks. + +TestApp + - source for dummy apks used in testing. + +TestApex + - source for dummy apex modules used in testing. + +Running the tests +================= + +You can manually run the tests as follows: + + atest RollbackTest + atest StagedRollbackTest diff --git a/tests/RollbackTest/RollbackTest.xml b/tests/RollbackTest/RollbackTest.xml index adbad56cd934..ac39f853656a 100644 --- a/tests/RollbackTest/RollbackTest.xml +++ b/tests/RollbackTest/RollbackTest.xml @@ -21,5 +21,9 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.tests.rollback" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + + <!-- Exclude the StagedRollbackTest tests, which needs to be specially + driven from the StagedRollbackTest host test --> + <option name="exclude-filter" value="com.android.tests.rollback.StagedRollbackTest" /> </test> </configuration> diff --git a/tests/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml index e57a768ad1b5..e57a768ad1b5 100644 --- a/tests/RollbackTest/AndroidManifest.xml +++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml diff --git a/tests/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java index ddcf1dabcafc..ddcf1dabcafc 100644 --- a/tests/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java index e10f866c899f..e10f866c899f 100644 --- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java index f07ae9f65b1b..f3edf09c5e95 100644 --- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java @@ -16,6 +16,10 @@ package com.android.tests.rollback; +import static com.android.tests.rollback.RollbackTestUtils.assertPackageRollbackInfoEquals; +import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals; +import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage; + import android.Manifest; import android.app.ActivityManager; import android.content.BroadcastReceiver; @@ -24,7 +28,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.VersionedPackage; -import android.content.rollback.PackageRollbackInfo; import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.os.Handler; @@ -42,7 +45,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.Collections; -import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.SynchronousQueue; @@ -617,17 +619,6 @@ public class RollbackTest { } } - // Helper function to test the value of a PackageRollbackInfo - private void assertPackageRollbackInfoEquals(String packageName, - long versionRolledBackFrom, long versionRolledBackTo, - PackageRollbackInfo info) { - assertEquals(packageName, info.getPackageName()); - assertEquals(packageName, info.getVersionRolledBackFrom().getPackageName()); - assertEquals(versionRolledBackFrom, info.getVersionRolledBackFrom().getLongVersionCode()); - assertEquals(packageName, info.getVersionRolledBackTo().getPackageName()); - assertEquals(versionRolledBackTo, info.getVersionRolledBackTo().getLongVersionCode()); - } - /** * Test bad update automatic rollback. */ @@ -713,23 +704,6 @@ public class RollbackTest { } } - // Helper function to test the value of a RollbackInfo with single package - private void assertRollbackInfoEquals(String packageName, - long versionRolledBackFrom, long versionRolledBackTo, - RollbackInfo info, VersionedPackage... causePackages) { - assertNotNull(info); - assertEquals(1, info.getPackages().size()); - assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom, versionRolledBackTo, - info.getPackages().get(0)); - assertEquals(causePackages.length, info.getCausePackages().size()); - for (int i = 0; i < causePackages.length; ++i) { - assertEquals(causePackages[i].getPackageName(), - info.getCausePackages().get(i).getPackageName()); - assertEquals(causePackages[i].getLongVersionCode(), - info.getCausePackages().get(i).getLongVersionCode()); - } - } - // Helper function to test that the given rollback info is a rollback for // the atomic set {A2, B2} -> {A1, B1}. private void assertRollbackInfoForAandB(RollbackInfo rollback) { @@ -743,23 +717,4 @@ public class RollbackTest { assertPackageRollbackInfoEquals(TEST_APP_A, 2, 1, rollback.getPackages().get(1)); } } - - // Helper function to return the RollbackInfo with a given package in the - // list of rollbacks. Throws an assertion failure if there is more than - // one such rollback info. Returns null if there are no such rollback - // infos. - private RollbackInfo getUniqueRollbackInfoForPackage(List<RollbackInfo> rollbacks, - String packageName) { - RollbackInfo found = null; - for (RollbackInfo rollback : rollbacks) { - for (PackageRollbackInfo info : rollback.getPackages()) { - if (packageName.equals(info.getPackageName())) { - assertNull(found); - found = rollback; - break; - } - } - } - return found; - } } diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java index 60c7a59d9456..280ee1d1c576 100644 --- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java @@ -16,19 +16,31 @@ package com.android.tests.rollback; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; +import android.content.rollback.PackageRollbackInfo; +import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.support.test.InstrumentationRegistry; +import android.util.Log; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; /** * Utilities to facilitate testing rollbacks. @@ -157,20 +169,28 @@ class RollbackTestUtils { /** * Installs the apks with the given resource names as an atomic set. + * <p> + * In case of staged installs, this function will return succesfully after + * the staged install has been committed and is ready for the device to + * reboot. * + * @param staged if the rollback should be staged. * @param enableRollback if rollback should be enabled. * @param resourceNames names of the class loader resource for the apks to * install. * @throws AssertionError if the installation fails. */ - static void installMultiPackage(boolean enableRollback, String... resourceNames) - throws InterruptedException, IOException { + private static void install(boolean staged, boolean enableRollback, + String... resourceNames) throws InterruptedException, IOException { Context context = InstrumentationRegistry.getContext(); PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); PackageInstaller.SessionParams multiPackageParams = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); multiPackageParams.setMultiPackage(); + if (staged) { + multiPackageParams.setStaged(); + } if (enableRollback) { // TODO: Do we set this on the parent params, the child params, or // both? @@ -183,6 +203,9 @@ class RollbackTestUtils { PackageInstaller.Session session = null; PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); + if (staged) { + params.setStaged(); + } if (enableRollback) { params.setEnableRollback(); } @@ -204,6 +227,36 @@ class RollbackTestUtils { // Commit the session (this will start the installation workflow). multiPackage.commit(LocalIntentSender.getIntentSender()); assertStatusSuccess(LocalIntentSender.getIntentSenderResult()); + + if (staged) { + waitForSessionReady(multiPackageId); + } + } + + /** + * Installs the apks with the given resource names as an atomic set. + * + * @param enableRollback if rollback should be enabled. + * @param resourceNames names of the class loader resource for the apks to + * install. + * @throws AssertionError if the installation fails. + */ + static void installMultiPackage(boolean enableRollback, String... resourceNames) + throws InterruptedException, IOException { + install(false, enableRollback, resourceNames); + } + + /** + * Installs the apks with the given resource names as a staged atomic set. + * + * @param enableRollback if rollback should be enabled. + * @param resourceNames names of the class loader resource for the apks to + * install. + * @throws AssertionError if the installation fails. + */ + static void installStaged(boolean enableRollback, String... resourceNames) + throws InterruptedException, IOException { + install(true, enableRollback, resourceNames); } static void adoptShellPermissionIdentity(String... permissions) { @@ -219,4 +272,104 @@ class RollbackTestUtils { .getUiAutomation() .dropShellPermissionIdentity(); } + + /** + * Returns the RollbackInfo with a given package in the list of rollbacks. + * Throws an assertion failure if there is more than one such rollback + * info. Returns null if there are no such rollback infos. + */ + static RollbackInfo getUniqueRollbackInfoForPackage(List<RollbackInfo> rollbacks, + String packageName) { + RollbackInfo found = null; + for (RollbackInfo rollback : rollbacks) { + for (PackageRollbackInfo info : rollback.getPackages()) { + if (packageName.equals(info.getPackageName())) { + assertNull(found); + found = rollback; + break; + } + } + } + return found; + } + + /** + * Asserts that the given PackageRollbackInfo has the expected package + * name and versions. + */ + static void assertPackageRollbackInfoEquals(String packageName, + long versionRolledBackFrom, long versionRolledBackTo, + PackageRollbackInfo info) { + assertEquals(packageName, info.getPackageName()); + assertEquals(packageName, info.getVersionRolledBackFrom().getPackageName()); + assertEquals(versionRolledBackFrom, info.getVersionRolledBackFrom().getLongVersionCode()); + assertEquals(packageName, info.getVersionRolledBackTo().getPackageName()); + assertEquals(versionRolledBackTo, info.getVersionRolledBackTo().getLongVersionCode()); + } + + /** + * Asserts that the given RollbackInfo has a single package with expected + * package name and versions. + */ + static void assertRollbackInfoEquals(String packageName, + long versionRolledBackFrom, long versionRolledBackTo, + RollbackInfo info, VersionedPackage... causePackages) { + assertNotNull(info); + assertEquals(1, info.getPackages().size()); + assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom, versionRolledBackTo, + info.getPackages().get(0)); + assertEquals(causePackages.length, info.getCausePackages().size()); + for (int i = 0; i < causePackages.length; ++i) { + assertEquals(causePackages[i].getPackageName(), + info.getCausePackages().get(i).getPackageName()); + assertEquals(causePackages[i].getLongVersionCode(), + info.getCausePackages().get(i).getLongVersionCode()); + } + } + + /** + * Waits for the given session to be marked as ready. + * Throws an assertion if the session fails. + */ + static void waitForSessionReady(int sessionId) { + BlockingQueue<PackageInstaller.SessionInfo> sessionStatus = new LinkedBlockingQueue<>(); + BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + PackageInstaller.SessionInfo info = + intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION); + if (info != null && info.getSessionId() == sessionId) { + if (info.isSessionReady() || info.isSessionFailed()) { + try { + sessionStatus.put(info); + } catch (InterruptedException e) { + Log.e(TAG, "Failed to put session info.", e); + } + } + } + } + }; + IntentFilter sessionUpdatedFilter = + new IntentFilter(PackageInstaller.ACTION_SESSION_UPDATED); + + Context context = InstrumentationRegistry.getContext(); + context.registerReceiver(sessionUpdatedReceiver, sessionUpdatedFilter); + + PackageInstaller installer = context.getPackageManager().getPackageInstaller(); + PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId); + + try { + if (info.isSessionReady() || info.isSessionFailed()) { + sessionStatus.put(info); + } + + info = sessionStatus.take(); + context.unregisterReceiver(sessionUpdatedReceiver); + if (info.isSessionFailed()) { + throw new AssertionError(info.getStagedSessionErrorMessage()); + } + } catch (InterruptedException e) { + throw new AssertionError(e); + } + } } diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java new file mode 100644 index 000000000000..297bf869278f --- /dev/null +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tests.rollback; + +import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals; +import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage; + +import android.Manifest; +import android.content.rollback.RollbackInfo; +import android.content.rollback.RollbackManager; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for rollback of staged installs. + * <p> + * Note: These tests require reboot in between test phases. They are run + * specially so that the testFooEnableRollback, testFooCommitRollback, and + * testFooConfirmRollback phases of each test are run in order with reboots in + * between them. + */ +@RunWith(JUnit4.class) +public class StagedRollbackTest { + + private static final String TAG = "RollbackTest"; + private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A"; + + /** + * Adopts common shell permissions needed for rollback tests. + */ + @Before + public void adoptShellPermissions() { + RollbackTestUtils.adoptShellPermissionIdentity( + Manifest.permission.INSTALL_PACKAGES, + Manifest.permission.DELETE_PACKAGES, + Manifest.permission.MANAGE_ROLLBACKS); + } + + /** + * Drops shell permissions needed for rollback tests. + */ + @After + public void dropShellPermissions() { + RollbackTestUtils.dropShellPermissionIdentity(); + } + + + /** + * Test basic rollbacks. Enable rollback phase. + */ + @Test + public void testBasicEnableRollback() throws Exception { + RollbackTestUtils.uninstall(TEST_APP_A); + assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); + + RollbackTestUtils.install("RollbackTestAppAv1.apk", false); + assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); + + RollbackTestUtils.installStaged(true, "RollbackTestAppAv2.apk"); + + // At this point, the host test driver will reboot the device and run + // testBasicCommitRollback(). + } + + /** + * Test basic rollbacks. Commit rollback phase. + */ + @Test + public void testBasicCommitRollback() throws Exception { + assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); + + RollbackManager rm = RollbackTestUtils.getRollbackManager(); + RollbackInfo rollback = getUniqueRollbackInfoForPackage( + rm.getAvailableRollbacks(), TEST_APP_A); + assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback); + assertTrue(rollback.isStaged()); + + RollbackTestUtils.rollback(rollback.getRollbackId()); + + rollback = getUniqueRollbackInfoForPackage( + rm.getRecentlyCommittedRollbacks(), TEST_APP_A); + assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback); + assertTrue(rollback.isStaged()); + assertNotEquals(-1, rollback.getCommittedSessionId()); + + RollbackTestUtils.waitForSessionReady(rollback.getCommittedSessionId()); + + // The app should not be rolled back until after reboot. + assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); + + // At this point, the host test driver will reboot the device and run + // testBasicConfirmRollback(). + } + + /** + * Test basic rollbacks. Confirm rollback phase. + */ + @Test + public void testBasicConfirmRollback() throws Exception { + assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); + + RollbackManager rm = RollbackTestUtils.getRollbackManager(); + RollbackInfo rollback = getUniqueRollbackInfoForPackage( + rm.getRecentlyCommittedRollbacks(), TEST_APP_A); + assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback); + assertTrue(rollback.isStaged()); + assertNotEquals(-1, rollback.getCommittedSessionId()); + } +} diff --git a/tests/RollbackTest/StagedRollbackTest.xml b/tests/RollbackTest/StagedRollbackTest.xml new file mode 100644 index 000000000000..2750d3765c20 --- /dev/null +++ b/tests/RollbackTest/StagedRollbackTest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Runs the staged rollback tests"> + <option name="test-suite-tag" value="StagedRollbackTest" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="RollbackTest.apk" /> + </target_preparer> + <test class="com.android.tradefed.testtype.HostTest" > + <option name="class" value="com.android.tests.rollback.host.StagedRollbackTest" /> + </test> +</configuration> diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java new file mode 100644 index 000000000000..6cb0dd091392 --- /dev/null +++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tests.rollback.host; + +import static org.junit.Assert.assertTrue; + +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Runs the staged rollback tests. + */ +@RunWith(DeviceJUnit4ClassRunner.class) +public class StagedRollbackTest extends BaseHostJUnit4Test { + + /** + * Runs the given phase of a test by calling into the device. + * Throws an exception if the test phase fails. + * <p> + * For example, <code>runPhase("testBasicEnableRollback");</code> + */ + private void runPhase(String phase) throws Exception { + assertTrue(runDeviceTests("com.android.tests.rollback", + "com.android.tests.rollback.StagedRollbackTest", + phase)); + } + + /** + * Tests staged rollbacks. + */ + @Test + public void testBasic() throws Exception { + runPhase("testBasicEnableRollback"); + getDevice().reboot(); + runPhase("testBasicCommitRollback"); + getDevice().reboot(); + runPhase("testBasicConfirmRollback"); + } +} |