Merge "Prevent instant apps from using AppSearch." into sc-dev

This commit is contained in:
Cassie Wang
2021-06-24 02:36:40 +00:00
committed by Android (Google) Code Review
12 changed files with 143 additions and 80 deletions

View File

@@ -90,6 +90,7 @@ public final class AppSearchSession implements Closeable {
@NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
try { try {
mService.initialize( mService.initialize(
mPackageName,
mUserHandle, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@@ -685,7 +686,9 @@ public final class AppSearchSession implements Closeable {
if (mIsMutated && !mIsClosed) { if (mIsMutated && !mIsClosed) {
try { try {
mService.persistToDisk( mService.persistToDisk(
mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mPackageName,
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the AppSearchSession", e); Log.e(TAG, "Unable to close the AppSearchSession", e);

View File

@@ -73,6 +73,7 @@ public class GlobalSearchSession implements Closeable {
@NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) { @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
try { try {
mService.initialize( mService.initialize(
mPackageName,
mUserHandle, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@@ -187,7 +188,9 @@ public class GlobalSearchSession implements Closeable {
if (mIsMutated && !mIsClosed) { if (mIsMutated && !mIsClosed) {
try { try {
mService.persistToDisk( mService.persistToDisk(
mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mPackageName,
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the GlobalSearchSession", e); Log.e(TAG, "Unable to close the GlobalSearchSession", e);

View File

@@ -124,7 +124,8 @@ public class SearchResults implements Closeable {
wrapCallback(executor, callback)); wrapCallback(executor, callback));
} }
} else { } else {
mService.getNextPage(mNextPageToken, mUserHandle, wrapCallback(executor, callback)); mService.getNextPage(mPackageName, mNextPageToken, mUserHandle,
wrapCallback(executor, callback));
} }
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
@@ -135,7 +136,7 @@ public class SearchResults implements Closeable {
public void close() { public void close() {
if (!mIsClosed) { if (!mIsClosed) {
try { try {
mService.invalidateNextPageToken(mNextPageToken, mUserHandle); mService.invalidateNextPageToken(mPackageName, mNextPageToken, mUserHandle);
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the SearchResults", e); Log.e(TAG, "Unable to close the SearchResults", e);

View File

@@ -181,21 +181,30 @@ interface IAppSearchManager {
* Fetches the next page of results of a previously executed query. Results can be empty if * Fetches the next page of results of a previously executed query. Results can be empty if
* next-page token is invalid or all pages have been returned. * next-page token is invalid or all pages have been returned.
* *
* @param packageName The name of the package to persist to disk for.
* @param nextPageToken The token of pre-loaded results of previously executed query. * @param nextPageToken The token of pre-loaded results of previously executed query.
* @param userHandle Handle of the calling user * @param userHandle Handle of the calling user
* @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
* operation. * operation.
*/ */
void getNextPage(in long nextPageToken, in UserHandle userHandle, in IAppSearchResultCallback callback); void getNextPage(
in String packageName,
in long nextPageToken,
in UserHandle userHandle,
in IAppSearchResultCallback callback);
/** /**
* Invalidates the next-page token so that no more results of the related query can be returned. * Invalidates the next-page token so that no more results of the related query can be returned.
* *
* @param packageName The name of the package to persist to disk for.
* @param nextPageToken The token of pre-loaded results of previously executed query to be * @param nextPageToken The token of pre-loaded results of previously executed query to be
* Invalidated. * Invalidated.
* @param userHandle Handle of the calling user * @param userHandle Handle of the calling user
*/ */
void invalidateNextPageToken(in long nextPageToken, in UserHandle userHandle); void invalidateNextPageToken(
in String packageName,
in long nextPageToken,
in UserHandle userHandle);
/** /**
* Searches a document based on a given specifications. * Searches a document based on a given specifications.
@@ -336,20 +345,26 @@ interface IAppSearchManager {
/** /**
* Persists all update/delete requests to the disk. * Persists all update/delete requests to the disk.
* *
* @param packageName The name of the package to persist to disk for.
* @param userHandle Handle of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
*/ */
void persistToDisk(in UserHandle userHandle, in long binderCallStartTimeMillis); void persistToDisk(
in String packageName,
in UserHandle userHandle,
in long binderCallStartTimeMillis);
/** /**
* Creates and initializes AppSearchImpl for the calling app. * Creates and initializes AppSearchImpl for the calling app.
* *
* @param packageName The name of the package to initialize for.
* @param userHandle Handle of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Void}&gt;. * {@link AppSearchResult}&lt;{@link Void}&gt;.
*/ */
void initialize( void initialize(
in String packageName,
in UserHandle userHandle, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);

View File

@@ -239,6 +239,8 @@ public final class AppSearchResult<ValueType> {
resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT; resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
} else if (t instanceof IOException) { } else if (t instanceof IOException) {
resultCode = AppSearchResult.RESULT_IO_ERROR; resultCode = AppSearchResult.RESULT_IO_ERROR;
} else if (t instanceof SecurityException) {
resultCode = AppSearchResult.RESULT_SECURITY_ERROR;
} else { } else {
resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR; resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
} }

View File

@@ -220,9 +220,10 @@ public class AppSearchManagerService extends SystemService {
} }
// Only clear the package's data if AppSearch exists for this user. // Only clear the package's data if AppSearch exists for this user.
if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) { if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getOrCreateUserInstance( mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
//TODO(b/145759910) clear visibility setting for package. //TODO(b/145759910) clear visibility setting for package.
instance.getAppSearchImpl().clearPackageData(packageName); instance.getAppSearchImpl().clearPackageData(packageName);
instance.getLogger().removeCachedUidForPackage(packageName); instance.getLogger().removeCachedUidForPackage(packageName);
@@ -243,11 +244,11 @@ public class AppSearchManagerService extends SystemService {
try { try {
// Only clear the package's data if AppSearch exists for this user. // Only clear the package's data if AppSearch exists for this user.
if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) { if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getOrCreateUserInstance( mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
List<PackageInfo> installedPackageInfos = mContext List<PackageInfo> installedPackageInfos = userContext
.createContextAsUser(userHandle, /*flags=*/0)
.getPackageManager() .getPackageManager()
.getInstalledPackages(/*flags=*/0); .getInstalledPackages(/*flags=*/0);
Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size()); Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
@@ -327,8 +328,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size()); List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
for (int i = 0; i < schemaBundles.size(); i++) { for (int i = 0; i < schemaBundles.size(); i++) {
schemas.add(new AppSearchSchema(schemaBundles.get(i))); schemas.add(new AppSearchSchema(schemaBundles.get(i)));
@@ -401,8 +404,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
GetSchemaResponse response = GetSchemaResponse response =
@@ -431,8 +436,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
List<String> namespaces = List<String> namespaces =
@@ -468,8 +475,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder = AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -548,8 +557,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchBatchResult.Builder<String, Bundle> resultBuilder = AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -627,8 +638,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
SearchResultPage searchResultPage = instance.getAppSearchImpl().query( SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
packageName, packageName,
@@ -691,8 +704,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
boolean callerHasSystemAccess = boolean callerHasSystemAccess =
@@ -738,9 +753,11 @@ public class AppSearchManagerService extends SystemService {
@Override @Override
public void getNextPage( public void getNextPage(
@NonNull String packageName,
long nextPageToken, long nextPageToken,
@NonNull UserHandle userHandle, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
@@ -750,7 +767,10 @@ public class AppSearchManagerService extends SystemService {
// opened it // opened it
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
SearchResultPage searchResultPage = SearchResultPage searchResultPage =
@@ -765,14 +785,19 @@ public class AppSearchManagerService extends SystemService {
} }
@Override @Override
public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) { public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken,
@NonNull UserHandle userHandle) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken); instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
@@ -803,7 +828,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyCallingPackage(callingUser, callingUid, packageName); Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
// we don't need to append the file. The file is always brand new. // we don't need to append the file. The file is always brand new.
@@ -849,7 +877,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyCallingPackage(callingUser, callingUid, packageName); Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -908,8 +939,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -957,8 +990,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder = AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -1039,8 +1074,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
instance.getAppSearchImpl().removeByQuery( instance.getAppSearchImpl().removeByQuery(
packageName, packageName,
@@ -1095,8 +1132,10 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName); verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser); mAppSearchUserInstanceManager.getUserInstance(callingUser);
StorageInfo storageInfo = instance.getAppSearchImpl() StorageInfo storageInfo = instance.getAppSearchImpl()
@@ -1112,8 +1151,10 @@ public class AppSearchManagerService extends SystemService {
@Override @Override
public void persistToDisk( public void persistToDisk(
@NonNull String packageName,
@NonNull UserHandle userHandle, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis) { @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
@@ -1125,7 +1166,10 @@ public class AppSearchManagerService extends SystemService {
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL); instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
++operationSuccessCount; ++operationSuccessCount;
@@ -1157,24 +1201,30 @@ public class AppSearchManagerService extends SystemService {
@Override @Override
public void initialize( public void initialize(
@NonNull String packageName,
@NonNull UserHandle userHandle, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
UserHandle callingUser = handleIncomingUser(userHandle, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
AppSearchUserInstance instance = null; AppSearchUserInstance instance = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
verifyUserUnlocked(callingUser); verifyUserUnlocked(callingUser);
verifyCallingPackage(userContext, callingUser, callingUid, packageName);
verifyNotInstantApp(userContext, packageName);
instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR)); userContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
++operationSuccessCount; ++operationSuccessCount;
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) { } catch (Throwable t) {
@@ -1204,14 +1254,15 @@ public class AppSearchManagerService extends SystemService {
} }
private void verifyCallingPackage( private void verifyCallingPackage(
@NonNull Context userContext,
@NonNull UserHandle actualCallingUser, @NonNull UserHandle actualCallingUser,
int actualCallingUid, int actualCallingUid,
@NonNull String claimedCallingPackage) { @NonNull String claimedCallingPackage) {
Objects.requireNonNull(actualCallingUser); Objects.requireNonNull(actualCallingUser);
Objects.requireNonNull(claimedCallingPackage); Objects.requireNonNull(claimedCallingPackage);
int claimedCallingUid = PackageUtil.getPackageUidAsUser( int claimedCallingUid = PackageUtil.getPackageUid(
mContext, claimedCallingPackage, actualCallingUser); userContext, claimedCallingPackage);
if (claimedCallingUid == INVALID_UID) { if (claimedCallingUid == INVALID_UID) {
throw new SecurityException( throw new SecurityException(
"Specified calling package [" + claimedCallingPackage + "] not found"); "Specified calling package [" + claimedCallingPackage + "] not found");
@@ -1317,6 +1368,21 @@ public class AppSearchManagerService extends SystemService {
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL); + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
} }
/**
* Helper for ensuring instant apps can't make calls to AppSearch.
*
* @param userContext Context of the user making the call.
* @param packageName Package name of the caller.
* @throws SecurityException if the caller is an instant app.
*/
private void verifyNotInstantApp(@NonNull Context userContext, @NonNull String packageName) {
PackageManager callingPackageManager = userContext.getPackageManager();
if (callingPackageManager.isInstantApp(packageName)) {
throw new SecurityException("Caller not allowed to create AppSearch session"
+ "; userHandle=" + userContext.getUser() + ", callingPackage=" + packageName);
}
}
// TODO(b/179160886): Cache the previous storage stats. // TODO(b/179160886): Cache the previous storage stats.
private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter { private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
@Override @Override
@@ -1331,9 +1397,10 @@ public class AppSearchManagerService extends SystemService {
try { try {
verifyUserUnlocked(userHandle); verifyUserUnlocked(userHandle);
Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getOrCreateUserInstance( mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
stats.dataSize += instance.getAppSearchImpl() stats.dataSize += instance.getAppSearchImpl()
.getStorageInfoForPackage(packageName).getSizeBytes(); .getStorageInfoForPackage(packageName).getSizeBytes();
} catch (Throwable t) { } catch (Throwable t) {
@@ -1359,9 +1426,10 @@ public class AppSearchManagerService extends SystemService {
if (packagesForUid == null) { if (packagesForUid == null) {
return; return;
} }
Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getOrCreateUserInstance( mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
for (int i = 0; i < packagesForUid.length; i++) { for (int i = 0; i < packagesForUid.length; i++) {
stats.dataSize += instance.getAppSearchImpl() stats.dataSize += instance.getAppSearchImpl()
.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes(); .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
@@ -1387,9 +1455,10 @@ public class AppSearchManagerService extends SystemService {
if (packagesForUser == null) { if (packagesForUser == null) {
return; return;
} }
Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
AppSearchUserInstance instance = AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getOrCreateUserInstance( mAppSearchUserInstanceManager.getOrCreateUserInstance(
mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
for (int i = 0; i < packagesForUser.size(); i++) { for (int i = 0; i < packagesForUser.size(); i++) {
String packageName = packagesForUser.get(i).packageName; String packageName = packagesForUser.get(i).packageName;
stats.dataSize += instance.getAppSearchImpl() stats.dataSize += instance.getAppSearchImpl()

View File

@@ -89,25 +89,24 @@ public final class AppSearchUserInstanceManager {
* <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and * <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and
* one will be created. * one will be created.
* *
* @param context The context * @param userContext Context of the user calling AppSearch
* @param userHandle The multi-user handle of the device user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch
* @param config Flag manager for AppSearch * @param config Flag manager for AppSearch
* @return An initialized {@link AppSearchUserInstance} for this user * @return An initialized {@link AppSearchUserInstance} for this user
*/ */
@NonNull @NonNull
public AppSearchUserInstance getOrCreateUserInstance( public AppSearchUserInstance getOrCreateUserInstance(
@NonNull Context context, @NonNull Context userContext,
@NonNull UserHandle userHandle, @NonNull UserHandle userHandle,
@NonNull AppSearchConfig config) @NonNull AppSearchConfig config)
throws AppSearchException { throws AppSearchException {
Objects.requireNonNull(context); Objects.requireNonNull(userContext);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
Objects.requireNonNull(config); Objects.requireNonNull(config);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
AppSearchUserInstance instance = mInstancesLocked.get(userHandle); AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
if (instance == null) { if (instance == null) {
Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0);
instance = createUserInstance(userContext, userHandle, config); instance = createUserInstance(userContext, userHandle, config);
mInstancesLocked.put(userHandle, instance); mInstancesLocked.put(userHandle, instance);
} }
@@ -169,7 +168,7 @@ public final class AppSearchUserInstanceManager {
InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder(); InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
// Initialize the classes that make up AppSearchUserInstance // Initialize the classes that make up AppSearchUserInstance
PlatformLogger logger = new PlatformLogger(userContext, userHandle, config); PlatformLogger logger = new PlatformLogger(userContext, config);
File appSearchDir = getAppSearchDir(userHandle); File appSearchDir = getAppSearchDir(userHandle);
File icingDir = new File(appSearchDir, "icing"); File icingDir = new File(appSearchDir, "icing");

View File

@@ -22,7 +22,6 @@ import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context; import android.content.Context;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@@ -55,11 +54,8 @@ import java.util.Random;
public final class PlatformLogger implements AppSearchLogger { public final class PlatformLogger implements AppSearchLogger {
private static final String TAG = "AppSearchPlatformLogger"; private static final String TAG = "AppSearchPlatformLogger";
// Context of the system service. // Context of the user we're logging for.
private final Context mContext; private final Context mUserContext;
// User we're logging for.
private final UserHandle mUserHandle;
// Manager holding the configuration flags // Manager holding the configuration flags
private final AppSearchConfig mConfig; private final AppSearchConfig mConfig;
@@ -120,10 +116,9 @@ public final class PlatformLogger implements AppSearchLogger {
* Westworld constructor * Westworld constructor
*/ */
public PlatformLogger( public PlatformLogger(
@NonNull Context context, @NonNull UserHandle userHandle, @NonNull Context userContext,
@NonNull AppSearchConfig config) { @NonNull AppSearchConfig config) {
mContext = Objects.requireNonNull(context); mUserContext = Objects.requireNonNull(userContext);
mUserHandle = Objects.requireNonNull(userHandle);
mConfig = Objects.requireNonNull(config); mConfig = Objects.requireNonNull(config);
} }
@@ -451,7 +446,7 @@ public final class PlatformLogger implements AppSearchLogger {
private int getPackageUidAsUserLocked(@NonNull String packageName) { private int getPackageUidAsUserLocked(@NonNull String packageName) {
Integer packageUid = mPackageUidCacheLocked.get(packageName); Integer packageUid = mPackageUidCacheLocked.get(packageName);
if (packageUid == null) { if (packageUid == null) {
packageUid = PackageUtil.getPackageUidAsUser(mContext, packageName, mUserHandle); packageUid = PackageUtil.getPackageUid(mUserContext, packageName);
if (packageUid != Process.INVALID_UID) { if (packageUid != Process.INVALID_UID) {
mPackageUidCacheLocked.put(packageName, packageUid); mPackageUidCacheLocked.put(packageName, packageUid);
} }

View File

@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Process; import android.os.Process;
import android.os.UserHandle;
/** /**
* Utilities for interacting with {@link android.content.pm.PackageManager}, * Utilities for interacting with {@link android.content.pm.PackageManager},
@@ -31,16 +30,6 @@ import android.os.UserHandle;
public class PackageUtil { public class PackageUtil {
private PackageUtil() {} private PackageUtil() {}
/**
* Finds the UID of the {@code packageName}. Returns {@link Process#INVALID_UID} if unable to
* find the UID.
*/
public static int getPackageUidAsUser(
@NonNull Context context, @NonNull String packageName, @NonNull UserHandle user) {
Context userContext = context.createContextAsUser(user, /*flags=*/ 0);
return getPackageUid(userContext, packageName);
}
/** /**
* Finds the UID of the {@code packageName} in the given {@code context}. Returns * Finds the UID of the {@code packageName} in the given {@code context}. Returns
* {@link Process#INVALID_UID} if unable to find the UID. * {@link Process#INVALID_UID} if unable to find the UID.

View File

@@ -21,7 +21,6 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -63,7 +62,6 @@ public class PlatformLoggerTest {
public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() { public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() {
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.of(UserHandle.USER_NULL),
mAppSearchConfig); mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -96,8 +94,7 @@ public class PlatformLoggerTest {
int putDocumentSamplingInterval = 1; int putDocumentSamplingInterval = 1;
int batchCallSamplingInterval = 2; int batchCallSamplingInterval = 2;
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(), mAppSearchConfig);
UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
@@ -143,7 +140,6 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.of(UserHandle.USER_NULL),
mAppSearchConfig); mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -162,7 +158,6 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.of(UserHandle.USER_NULL),
mAppSearchConfig); mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -186,7 +181,6 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.of(UserHandle.USER_NULL),
mAppSearchConfig); mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -214,7 +208,6 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.of(UserHandle.USER_NULL),
mAppSearchConfig); mAppSearchConfig);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,

View File

@@ -64,14 +64,9 @@ public class PlatformLoggerTest {
public void setUp() throws Exception { public void setUp() throws Exception {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
mContext = new ContextWrapper(context) { mContext = new ContextWrapper(context) {
@Override
public Context createContextAsUser(UserHandle user, int flags) {
return new ContextWrapper(super.createContextAsUser(user, flags)) {
@Override @Override
public PackageManager getPackageManager() { public PackageManager getPackageManager() {
return getMockPackageManager(user); return getMockPackageManager(mContext.getUser());
}
};
} }
}; };
} }
@@ -153,7 +148,6 @@ public class PlatformLoggerTest {
final int testUid = 1234; final int testUid = 1234;
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
mContext, mContext,
mContext.getUser(),
AppSearchConfig.create(DIRECT_EXECUTOR)); AppSearchConfig.create(DIRECT_EXECUTOR));
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser()); PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid); when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid);

View File

@@ -785,7 +785,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void getNextPage(long nextPageToken, UserHandle userHandle, public void getNextPage(String packageName, long nextPageToken, UserHandle userHandle,
IAppSearchResultCallback callback) throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
final Bundle page = new Bundle(); final Bundle page = new Bundle();
page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
@@ -795,8 +795,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void invalidateNextPageToken(long nextPageToken, UserHandle userHandle) public void invalidateNextPageToken(String packageName, long nextPageToken,
throws RemoteException { UserHandle userHandle) throws RemoteException {
} }
@Override @Override
@@ -875,13 +875,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void persistToDisk(UserHandle userHandle, long binderCallStartTimeMillis) public void persistToDisk(String packageName, UserHandle userHandle,
throws RemoteException { long binderCallStartTimeMillis) throws RemoteException {
} }
@Override @Override
public void initialize(UserHandle userHandle, long binderCallStartTimeMillis, public void initialize(String packageName, UserHandle userHandle,
IAppSearchResultCallback callback) long binderCallStartTimeMillis, IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
ignore(callback); ignore(callback);
} }