summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java300
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java58
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java195
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java170
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java132
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java126
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java5
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java5
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java245
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java148
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java275
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java31
13 files changed, 808 insertions, 954 deletions
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 31203c73c76a..400c24138060 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -37,6 +37,7 @@ import android.app.appsearch.aidl.AppSearchResultParcel;
import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
import android.app.appsearch.aidl.IAppSearchManager;
import android.app.appsearch.aidl.IAppSearchResultCallback;
+import android.app.appsearch.exceptions.AppSearchException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -58,10 +59,7 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalManagerRegistry;
import com.android.server.SystemService;
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.appsearch.stats.LoggerInstanceManager;
-import com.android.server.appsearch.stats.PlatformLogger;
import com.android.server.appsearch.util.PackageUtil;
import com.android.server.appsearch.visibilitystore.VisibilityStore;
import com.android.server.usage.StorageStatsManagerLocal;
@@ -89,9 +87,8 @@ public class AppSearchManagerService extends SystemService {
private static final String TAG = "AppSearchManagerService";
private final Context mContext;
private PackageManager mPackageManager;
- private ImplInstanceManager mImplInstanceManager;
private UserManager mUserManager;
- private LoggerInstanceManager mLoggerInstanceManager;
+ private AppSearchUserInstanceManager mAppSearchUserInstanceManager;
// Never call shutdownNow(). It will cancel the futures it's returned. And since
// Executor#execute won't return anything, we will hang forever waiting for the execution.
@@ -116,9 +113,8 @@ public class AppSearchManagerService extends SystemService {
public void onStart() {
publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
mPackageManager = getContext().getPackageManager();
- mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
+ mAppSearchUserInstanceManager = AppSearchUserInstanceManager.getInstance();
mUserManager = mContext.getSystemService(UserManager.class);
- mLoggerInstanceManager = LoggerInstanceManager.getInstance();
registerReceivers();
LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
.registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
@@ -180,8 +176,7 @@ public class AppSearchManagerService extends SystemService {
*/
private void handleUserRemoved(@NonNull UserHandle userHandle) {
try {
- mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
- mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
+ mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
} catch (Throwable t) {
Log.e(TAG, "Unable to remove data for: " + userHandle, t);
@@ -224,14 +219,13 @@ public class AppSearchManagerService extends SystemService {
return;
}
// Only clear the package's data if AppSearch exists for this user.
- if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
- PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
- userHandle, AppSearchConfig.getInstance(EXECUTOR));
- AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
- userHandle, logger);
+ if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
//TODO(b/145759910) clear visibility setting for package.
- impl.clearPackageData(packageName);
- logger.removeCachedUidForPackage(packageName);
+ instance.getAppSearchImpl().clearPackageData(packageName);
+ instance.getLogger().removeCachedUidForPackage(packageName);
}
} catch (Throwable t) {
Log.e(TAG, "Unable to remove data for package: " + packageName, t);
@@ -248,11 +242,10 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
// Only clear the package's data if AppSearch exists for this user.
- if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
- PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
- mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
- AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
- userHandle, logger);
+ if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
List<PackageInfo> installedPackageInfos = mContext
.createContextAsUser(userHandle, /*flags=*/0)
.getPackageManager()
@@ -263,7 +256,7 @@ public class AppSearchManagerService extends SystemService {
}
packagesToKeep.add(VisibilityStore.PACKAGE_NAME);
//TODO(b/145759910) clear visibility setting for package.
- impl.prunePackageData(packagesToKeep);
+ instance.getAppSearchImpl().prunePackageData(packagesToKeep);
}
} catch (Throwable t) {
Log.e(TAG, "Unable to prune packages for " + user, t);
@@ -279,7 +272,7 @@ public class AppSearchManagerService extends SystemService {
UserHandle userHandle = user.getUserHandle();
mUnlockedUsersLocked.remove(userHandle);
try {
- mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
+ mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
} catch (Throwable t) {
Log.e(TAG, "Error handling user stopping.", t);
}
@@ -311,7 +304,7 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName,
@NonNull List<Bundle> schemaBundles,
@NonNull List<String> schemasNotDisplayedBySystem,
- @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+ @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
boolean forceOverride,
int schemaVersion,
@NonNull UserHandle userHandle,
@@ -321,7 +314,7 @@ public class AppSearchManagerService extends SystemService {
Objects.requireNonNull(databaseName);
Objects.requireNonNull(schemaBundles);
Objects.requireNonNull(schemasNotDisplayedBySystem);
- Objects.requireNonNull(schemasPackageAccessibleBundles);
+ Objects.requireNonNull(schemasVisibleToPackagesBundles);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback);
@@ -330,7 +323,7 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
@@ -341,9 +334,9 @@ public class AppSearchManagerService extends SystemService {
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
}
Map<String, List<PackageIdentifier>> schemasPackageAccessible =
- new ArrayMap<>(schemasPackageAccessibleBundles.size());
+ new ArrayMap<>(schemasVisibleToPackagesBundles.size());
for (Map.Entry<String, List<Bundle>> entry :
- schemasPackageAccessibleBundles.entrySet()) {
+ schemasVisibleToPackagesBundles.entrySet()) {
List<PackageIdentifier> packageIdentifiers =
new ArrayList<>(entry.getValue().size());
for (int i = 0; i < entry.getValue().size(); i++) {
@@ -352,12 +345,12 @@ public class AppSearchManagerService extends SystemService {
}
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
}
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
- SetSchemaResponse setSchemaResponse = impl.setSchema(
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
packageName,
databaseName,
schemas,
+ instance.getVisibilityStore(),
schemasNotDisplayedBySystem,
schemasPackageAccessible,
forceOverride,
@@ -370,12 +363,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -410,8 +403,10 @@ public class AppSearchManagerService extends SystemService {
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- GetSchemaResponse response = impl.getSchema(packageName, databaseName);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ GetSchemaResponse response =
+ instance.getAppSearchImpl().getSchema(packageName, databaseName);
invokeCallbackOnResult(
callback,
AppSearchResult.newSuccessfulResult(response.getBundle()));
@@ -438,10 +433,12 @@ public class AppSearchManagerService extends SystemService {
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- List<String> namespaces = impl.getNamespaces(packageName, databaseName);
- invokeCallbackOnResult(callback,
- AppSearchResult.newSuccessfulResult(namespaces));
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ List<String> namespaces =
+ instance.getAppSearchImpl().getNamespaces(packageName, databaseName);
+ invokeCallbackOnResult(
+ callback, AppSearchResult.newSuccessfulResult(namespaces));
} catch (Throwable t) {
invokeCallbackOnError(callback, t);
}
@@ -467,7 +464,7 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
@@ -475,17 +472,16 @@ public class AppSearchManagerService extends SystemService {
verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
for (int i = 0; i < documentBundles.size(); i++) {
GenericDocument document = new GenericDocument(documentBundles.get(i));
try {
- impl.putDocument(packageName, databaseName, document, logger);
- resultBuilder.setSuccess(document.getId(), /*result=*/ null);
+ instance.getAppSearchImpl().putDocument(
+ packageName, databaseName, document, instance.getLogger());
+ resultBuilder.setSuccess(document.getId(), /*value=*/ null);
++operationSuccessCount;
} catch (Throwable t) {
- resultBuilder.setResult(document.getId(),
- throwableToFailedResult(t));
+ resultBuilder.setResult(document.getId(), throwableToFailedResult(t));
AppSearchResult<Void> result = throwableToFailedResult(t);
resultBuilder.setResult(document.getId(), result);
// Since we can only include one status code in the atom,
@@ -495,19 +491,19 @@ public class AppSearchManagerService extends SystemService {
}
}
// Now that the batch has been written. Persist the newly written data.
- impl.persistToDisk(PersistType.Code.LITE);
+ instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -548,7 +544,7 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
@@ -556,18 +552,16 @@ public class AppSearchManagerService extends SystemService {
verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
for (int i = 0; i < ids.size(); i++) {
String id = ids.get(i);
try {
- GenericDocument document =
- impl.getDocument(
- packageName,
- databaseName,
- namespace,
- id,
- typePropertyPaths);
+ GenericDocument document = instance.getAppSearchImpl().getDocument(
+ packageName,
+ databaseName,
+ namespace,
+ id,
+ typePropertyPaths);
++operationSuccessCount;
resultBuilder.setSuccess(id, document.getBundle());
} catch (Throwable t) {
@@ -585,12 +579,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -629,21 +623,19 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
- SearchResultPage searchResultPage =
- impl.query(
- packageName,
- databaseName,
- queryExpression,
- new SearchSpec(searchSpecBundle),
- logger);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
+ packageName,
+ databaseName,
+ queryExpression,
+ new SearchSpec(searchSpecBundle),
+ instance.getLogger());
++operationSuccessCount;
invokeCallbackOnResult(
callback,
@@ -653,12 +645,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -695,21 +687,24 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- SearchResultPage searchResultPage =
- impl.globalQuery(
- queryExpression,
- new SearchSpec(searchSpecBundle),
- packageName,
- callingUid,
- logger);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
+
+ boolean callerHasSystemAccess =
+ instance.getVisibilityStore().doesCallerHaveSystemAccess(packageName);
+ SearchResultPage searchResultPage = instance.getAppSearchImpl().globalQuery(
+ queryExpression,
+ new SearchSpec(searchSpecBundle),
+ packageName,
+ instance.getVisibilityStore(),
+ callingUid,
+ callerHasSystemAccess,
+ instance.getLogger());
++operationSuccessCount;
invokeCallbackOnResult(
callback,
@@ -719,12 +714,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setStatusCode(statusCode)
.setTotalLatencyMillis(totalLatencyMillis)
@@ -756,8 +751,10 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
verifyUserUnlocked(callingUser);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ SearchResultPage searchResultPage =
+ instance.getAppSearchImpl().getNextPage(nextPageToken);
invokeCallbackOnResult(
callback,
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
@@ -776,8 +773,9 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
verifyUserUnlocked(callingUser);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- impl.invalidateNextPageToken(nextPageToken);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
} catch (Throwable t) {
Log.e(TAG, "Unable to invalidate the query page token", t);
}
@@ -806,11 +804,12 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
// we don't need to append the file. The file is always brand new.
try (DataOutputStream outputStream = new DataOutputStream(
new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
- SearchResultPage searchResultPage = impl.query(
+ SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
packageName,
databaseName,
queryExpression,
@@ -822,7 +821,7 @@ public class AppSearchManagerService extends SystemService {
outputStream, searchResultPage.getResults().get(i)
.getGenericDocument().getBundle());
}
- searchResultPage = impl.getNextPage(
+ searchResultPage = instance.getAppSearchImpl().getNextPage(
searchResultPage.getNextPageToken());
}
}
@@ -851,7 +850,8 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
GenericDocument document;
ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
@@ -866,8 +866,8 @@ public class AppSearchManagerService extends SystemService {
break;
}
try {
- impl.putDocument(packageName, databaseName, document,
- /*logger=*/ null);
+ instance.getAppSearchImpl().putDocument(
+ packageName, databaseName, document, /*logger=*/ null);
} catch (Throwable t) {
migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
document.getNamespace(),
@@ -878,7 +878,7 @@ public class AppSearchManagerService extends SystemService {
}
}
}
- impl.persistToDisk(PersistType.Code.FULL);
+ instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
invokeCallbackOnResult(callback,
AppSearchResult.newSuccessfulResult(migrationFailureBundles));
} catch (Throwable t) {
@@ -909,17 +909,23 @@ public class AppSearchManagerService extends SystemService {
EXECUTOR.execute(() -> {
try {
verifyUserUnlocked(callingUser);
-
- if (systemUsage) {
- // TODO(b/183031844): Validate that the call comes from the system
+ verifyCallingPackage(callingUser, callingUid, packageName);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+
+ if (systemUsage
+ && !instance.getVisibilityStore()
+ .doesCallerHaveSystemAccess(packageName)) {
+ throw new AppSearchException(
+ AppSearchResult.RESULT_SECURITY_ERROR,
+ packageName + " does not have access to report system usage");
}
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- impl.reportUsage(
+ instance.getAppSearchImpl().reportUsage(
packageName, databaseName, namespace, documentId,
usageTimeMillis, systemUsage);
invokeCallbackOnResult(
- callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
+ callback, AppSearchResult.newSuccessfulResult(/*value=*/ null));
} catch (Throwable t) {
invokeCallbackOnError(callback, t);
}
@@ -947,7 +953,7 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
@@ -955,12 +961,11 @@ public class AppSearchManagerService extends SystemService {
verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
for (int i = 0; i < ids.size(); i++) {
String id = ids.get(i);
try {
- impl.remove(
+ instance.getAppSearchImpl().remove(
packageName,
databaseName,
namespace,
@@ -978,19 +983,19 @@ public class AppSearchManagerService extends SystemService {
}
}
// Now that the batch has been written. Persist the newly written data.
- impl.persistToDisk(PersistType.Code.LITE);
+ instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -1030,22 +1035,21 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
- impl.removeByQuery(
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ instance.getAppSearchImpl().removeByQuery(
packageName,
databaseName,
queryExpression,
new SearchSpec(searchSpecBundle),
/*removeStatsBuilder=*/ null);
// Now that the batch has been written. Persist the newly written data.
- impl.persistToDisk(PersistType.Code.LITE);
+ instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
++operationSuccessCount;
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) {
@@ -1053,12 +1057,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setPackageName(packageName)
.setDatabase(databaseName)
.setStatusCode(statusCode)
@@ -1093,9 +1097,10 @@ public class AppSearchManagerService extends SystemService {
try {
verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUser, callingUid, packageName);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
- databaseName);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ StorageInfo storageInfo = instance.getAppSearchImpl()
+ .getStorageInfoForDatabase(packageName, databaseName);
Bundle storageInfoBundle = storageInfo.getBundle();
invokeCallbackOnResult(
callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
@@ -1116,26 +1121,25 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUser);
- AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
- logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
- impl.persistToDisk(PersistType.Code.FULL);
+ instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
+ instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
++operationSuccessCount;
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
Log.e(TAG, "Unable to persist the data to disk", t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setStatusCode(statusCode)
.setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_FLUSH)
@@ -1164,15 +1168,13 @@ public class AppSearchManagerService extends SystemService {
UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
- PlatformLogger logger = null;
+ AppSearchUserInstance instance = null;
int operationSuccessCount = 0;
int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUser);
- logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
- mContext, callingUser,
- AppSearchConfig.getInstance(EXECUTOR));
- mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
+ instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
++operationSuccessCount;
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) {
@@ -1180,12 +1182,12 @@ public class AppSearchManagerService extends SystemService {
statusCode = throwableToFailedResult(t).getResultCode();
invokeCallbackOnError(callback, t);
} finally {
- if (logger != null) {
+ if (instance != null) {
int estimatedBinderLatencyMillis =
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- logger.logStats(new CallStats.Builder()
+ instance.getLogger().logStats(new CallStats.Builder()
.setStatusCode(statusCode)
.setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_INITIALIZE)
@@ -1329,12 +1331,11 @@ public class AppSearchManagerService extends SystemService {
try {
verifyUserUnlocked(userHandle);
- PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
- mContext, userHandle,
- AppSearchConfig.getInstance(EXECUTOR));
- AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
- mContext, userHandle, logger);
- stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+ stats.dataSize += instance.getAppSearchImpl()
+ .getStorageInfoForPackage(packageName).getSizeBytes();
} catch (Throwable t) {
Log.e(
TAG,
@@ -1358,14 +1359,12 @@ public class AppSearchManagerService extends SystemService {
if (packagesForUid == null) {
return;
}
- PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
- mContext, userHandle,
- AppSearchConfig.getInstance(EXECUTOR));
- AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
- mContext, userHandle, logger);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
for (int i = 0; i < packagesForUid.length; i++) {
- stats.dataSize +=
- impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
+ stats.dataSize += instance.getAppSearchImpl()
+ .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
}
} catch (Throwable t) {
Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
@@ -1388,14 +1387,13 @@ public class AppSearchManagerService extends SystemService {
if (packagesForUser == null) {
return;
}
- PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
- mContext, userHandle,
- AppSearchConfig.getInstance(EXECUTOR));
- AppSearchImpl impl =
- mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
+ AppSearchUserInstance instance =
+ mAppSearchUserInstanceManager.getOrCreateUserInstance(
+ mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
for (int i = 0; i < packagesForUser.size(); i++) {
String packageName = packagesForUser.get(i).packageName;
- stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
+ stats.dataSize += instance.getAppSearchImpl()
+ .getStorageInfoForPackage(packageName).getSizeBytes();
}
} catch (Throwable t) {
Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
new file mode 100644
index 000000000000..7e743edaf3ee
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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.appsearch;
+
+import android.annotation.NonNull;
+
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.stats.PlatformLogger;
+import com.android.server.appsearch.visibilitystore.VisibilityStore;
+
+import java.util.Objects;
+
+/**
+ * Container for AppSearch classes that should only be initialized once per device-user and make up
+ * the core of the AppSearch system.
+ */
+public final class AppSearchUserInstance {
+ private final PlatformLogger mLogger;
+ private final AppSearchImpl mAppSearchImpl;
+ private final VisibilityStore mVisibilityStore;
+
+ AppSearchUserInstance(
+ @NonNull PlatformLogger logger,
+ @NonNull AppSearchImpl appSearchImpl,
+ @NonNull VisibilityStore visibilityStore) {
+ mLogger = Objects.requireNonNull(logger);
+ mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
+ mVisibilityStore = Objects.requireNonNull(visibilityStore);
+ }
+
+ @NonNull
+ public PlatformLogger getLogger() {
+ return mLogger;
+ }
+
+ @NonNull
+ public AppSearchImpl getAppSearchImpl() {
+ return mAppSearchImpl;
+ }
+
+ @NonNull
+ public VisibilityStore getVisibilityStore() {
+ return mVisibilityStore;
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
new file mode 100644
index 000000000000..cedc364f6072
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
@@ -0,0 +1,195 @@
+/*
+ * 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.server.appsearch;
+
+import android.annotation.NonNull;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.content.Context;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
+import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
+import com.android.server.appsearch.stats.PlatformLogger;
+import com.android.server.appsearch.visibilitystore.VisibilityStore;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Manages the lifecycle of AppSearch classes that should only be initialized once per device-user
+ * and make up the core of the AppSearch system.
+ *
+ * @hide
+ */
+public final class AppSearchUserInstanceManager {
+ private static final String TAG = "AppSearchUserInstanceMa";
+
+ private static volatile AppSearchUserInstanceManager sAppSearchUserInstanceManager;
+
+ @GuardedBy("mInstancesLocked")
+ private final Map<UserHandle, AppSearchUserInstance> mInstancesLocked = new ArrayMap<>();
+
+ private AppSearchUserInstanceManager() {}
+
+ /**
+ * Gets an instance of AppSearchUserInstanceManager to be used.
+ *
+ * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
+ * existing instance will be returned.
+ */
+ @NonNull
+ public static AppSearchUserInstanceManager getInstance() {
+ if (sAppSearchUserInstanceManager == null) {
+ synchronized (AppSearchUserInstanceManager.class) {
+ if (sAppSearchUserInstanceManager == null) {
+ sAppSearchUserInstanceManager = new AppSearchUserInstanceManager();
+ }
+ }
+ }
+ return sAppSearchUserInstanceManager;
+ }
+
+ /**
+ * Returns AppSearch directory in the credential encrypted system directory for the given user.
+ *
+ * <p>This folder should only be accessed after unlock.
+ */
+ public static File getAppSearchDir(@NonNull UserHandle userHandle) {
+ // Duplicates the implementation of Environment#getDataSystemCeDirectory
+ // TODO(b/191059409): Unhide Environment#getDataSystemCeDirectory and switch to it.
+ File systemCeDir = new File(Environment.getDataDirectory(), "system_ce");
+ File systemCeUserDir = new File(systemCeDir, String.valueOf(userHandle.getIdentifier()));
+ return new File(systemCeUserDir, "appsearch");
+ }
+
+ /**
+ * Gets an instance of AppSearchUserInstance for the given user, or creates one if none exists.
+ *
+ * <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and
+ * one will be created.
+ *
+ * @param context The context
+ * @param userHandle The multi-user handle of the device user calling AppSearch
+ * @param config Flag manager for AppSearch
+ * @return An initialized {@link AppSearchUserInstance} for this user
+ */
+ @NonNull
+ public AppSearchUserInstance getOrCreateUserInstance(
+ @NonNull Context context,
+ @NonNull UserHandle userHandle,
+ @NonNull AppSearchConfig config)
+ throws AppSearchException {
+ Objects.requireNonNull(context);
+ Objects.requireNonNull(userHandle);
+ Objects.requireNonNull(config);
+
+ synchronized (mInstancesLocked) {
+ AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
+ if (instance == null) {
+ Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0);
+ instance = createUserInstance(userContext, userHandle, config);
+ mInstancesLocked.put(userHandle, instance);
+ }
+ return instance;
+ }
+ }
+
+ /**
+ * Closes and removes an {@link AppSearchUserInstance} for the given user.
+ *
+ * <p>All mutations applied to the underlying {@link AppSearchImpl} will be persisted to disk.
+ *
+ * @param userHandle The multi-user user handle of the user that need to be removed.
+ */
+ public void closeAndRemoveUserInstance(@NonNull UserHandle userHandle) {
+ Objects.requireNonNull(userHandle);
+ synchronized (mInstancesLocked) {
+ AppSearchUserInstance instance = mInstancesLocked.remove(userHandle);
+ if (instance != null) {
+ instance.getAppSearchImpl().close();
+ }
+ }
+ }
+
+ /**
+ * Gets an {@link AppSearchUserInstance} for the given user.
+ *
+ * <p>This method should only be called by an initialized SearchSession, which has already
+ * called {@link #getOrCreateUserInstance} before.
+ *
+ * @param userHandle The multi-user handle of the device user calling AppSearch
+ * @return An initialized {@link AppSearchUserInstance} for this user
+ * @throws IllegalStateException if {@link AppSearchUserInstance} haven't created for the given
+ * user.
+ */
+ @NonNull
+ public AppSearchUserInstance getUserInstance(@NonNull UserHandle userHandle) {
+ Objects.requireNonNull(userHandle);
+ synchronized (mInstancesLocked) {
+ AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
+ if (instance == null) {
+ // Impossible scenario, user cannot call an uninitialized SearchSession,
+ // getInstance should always find the instance for the given user and never try to
+ // create an instance for this user again.
+ throw new IllegalStateException(
+ "AppSearchUserInstance has never been created for: " + userHandle);
+ }
+ return instance;
+ }
+ }
+
+ @NonNull
+ private AppSearchUserInstance createUserInstance(
+ @NonNull Context userContext,
+ @NonNull UserHandle userHandle,
+ @NonNull AppSearchConfig config)
+ throws AppSearchException {
+ long totalLatencyStartMillis = SystemClock.elapsedRealtime();
+ InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
+
+ // Initialize the classes that make up AppSearchUserInstance
+ PlatformLogger logger = new PlatformLogger(userContext, userHandle, config);
+
+ File appSearchDir = getAppSearchDir(userHandle);
+ File icingDir = new File(appSearchDir, "icing");
+ Log.i(TAG, "Creating new AppSearch instance at: " + icingDir);
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(icingDir, initStatsBuilder, new FrameworkOptimizeStrategy());
+
+ long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
+ VisibilityStore visibilityStore = VisibilityStore.create(appSearchImpl, userContext);
+ long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
+
+ initStatsBuilder
+ .setTotalLatencyMillis(
+ (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
+ .setPrepareVisibilityStoreLatencyMillis(
+ (int)
+ (prepareVisibilityStoreLatencyEndMillis
+ - prepareVisibilityStoreLatencyStartMillis));
+ logger.logStats(initStatsBuilder.build());
+
+ return new AppSearchUserInstance(logger, appSearchImpl, visibilityStore);
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
deleted file mode 100644
index 2181dab90681..000000000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.server.appsearch;
-
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.os.Environment;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.AppSearchLogger;
-import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Manages the lifecycle of instances of {@link AppSearchImpl}.
- *
- * <p>These instances are managed per unique device-user.
- * @hide
- */
-public final class ImplInstanceManager {
- private static final String TAG = "AppSearchImplInstanceMa";
-
- private static ImplInstanceManager sImplInstanceManager;
-
- @GuardedBy("mInstancesLocked")
- private final Map<UserHandle, AppSearchImpl> mInstancesLocked = new ArrayMap<>();
-
- /**
- * Gets an instance of ImplInstanceManager to be used.
- *
- * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
- * existing instance will be returned.
- */
- @NonNull
- public static ImplInstanceManager getInstance(@NonNull Context context) {
- if (sImplInstanceManager == null) {
- synchronized (ImplInstanceManager.class) {
- if (sImplInstanceManager == null) {
- sImplInstanceManager = new ImplInstanceManager();
- }
- }
- }
- return sImplInstanceManager;
- }
-
- /**
- * Returns AppSearch directory in the credential encrypted system directory for the given user.
- *
- * <p>This folder should only be accessed after unlock.
- */
- public static File getAppSearchDir(@NonNull UserHandle userHandle) {
- // Duplicates the implementation of Environment#getDataSystemCeDirectory
- // TODO(b/191059409): Unhide Environment#getDataSystemCeDirectory and switch to it.
- File systemCeDir = new File(Environment.getDataDirectory(), "system_ce");
- File systemCeUserDir = new File(systemCeDir, String.valueOf(userHandle.getIdentifier()));
- return new File(systemCeUserDir, "appSearch");
- }
-
- /**
- * Gets an instance of AppSearchImpl for the given user, or creates one if none exists.
- *
- * <p>If no AppSearchImpl instance exists for the unlocked user, Icing will be initialized and
- * one will be created.
- *
- * @param context The system context
- * @param userHandle The multi-user handle of the device user calling AppSearch
- * @return An initialized {@link AppSearchImpl} for this user
- */
- @NonNull
- public AppSearchImpl getOrCreateAppSearchImpl(
- @NonNull Context context,
- @NonNull UserHandle userHandle,
- @Nullable AppSearchLogger logger) throws AppSearchException {
- Objects.requireNonNull(context);
- Objects.requireNonNull(userHandle);
-
- synchronized (mInstancesLocked) {
- AppSearchImpl instance = mInstancesLocked.get(userHandle);
- if (instance == null) {
- Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0);
- instance = createImpl(userContext, userHandle, logger);
- mInstancesLocked.put(userHandle, instance);
- }
- return instance;
- }
- }
-
- /**
- * Close and remove an instance of {@link AppSearchImpl} for the given user.
- *
- * <p>All mutation apply to this {@link AppSearchImpl} will be persisted to disk.
- *
- * @param userHandle The multi-user user handle of the user that need to be removed.
- */
- public void closeAndRemoveAppSearchImplForUser(@NonNull UserHandle userHandle) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- AppSearchImpl appSearchImpl = mInstancesLocked.get(userHandle);
- if (appSearchImpl != null) {
- appSearchImpl.close();
- mInstancesLocked.remove(userHandle);
- }
- }
- }
-
- /**
- * Gets an instance of AppSearchImpl for the given user.
- *
- * <p>This method should only be called by an initialized SearchSession, which has been already
- * created the AppSearchImpl instance for the given user.
- *
- * @param userHandle The multi-user handle of the device user calling AppSearch
- * @return An initialized {@link AppSearchImpl} for this user
- * @throws IllegalStateException if {@link AppSearchImpl} haven't created for the given user.
- */
- @NonNull
- public AppSearchImpl getAppSearchImpl(@NonNull UserHandle userHandle) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- AppSearchImpl instance = mInstancesLocked.get(userHandle);
- if (instance == null) {
- // Impossible scenario, user cannot call an uninitialized SearchSession,
- // getInstance should always find the instance for the given user and never try to
- // create an instance for this user again.
- throw new IllegalStateException(
- "AppSearchImpl has never been created for: " + userHandle);
- }
- return instance;
- }
- }
-
- private AppSearchImpl createImpl(
- @NonNull Context userContext,
- @NonNull UserHandle userHandle,
- @Nullable AppSearchLogger logger)
- throws AppSearchException {
- File appSearchDir = getAppSearchDir(userHandle);
- File icingDir = new File(appSearchDir, "icing");
- Log.i(TAG, "Creating new AppSearch instance at: " + icingDir);
- return AppSearchImpl.create(
- icingDir,
- userContext,
- /*logger=*/ null,
- new FrameworkOptimizeStrategy());
- }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 4a1a9ae3546b..77a1bb402bd3 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -39,7 +39,6 @@ import android.app.appsearch.SetSchemaResponse;
import android.app.appsearch.StorageInfo;
import android.app.appsearch.exceptions.AppSearchException;
import android.app.appsearch.util.LogUtil;
-import android.content.Context;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -157,9 +156,6 @@ public final class AppSearchImpl implements Closeable {
@VisibleForTesting
final IcingSearchEngine mIcingSearchEngineLocked;
- @GuardedBy("mReadWriteLock")
- private final VisibilityStore mVisibilityStoreLocked;
-
// This map contains schema types and SchemaTypeConfigProtos for all package-database
// prefixes. It maps each package-database prefix to an inner-map. The inner-map maps each
// prefixed schema type to its respective SchemaTypeConfigProto.
@@ -195,56 +191,27 @@ public final class AppSearchImpl implements Closeable {
* <p>Instead, logger instance needs to be passed to each individual method, like create, query
* and putDocument.
*
- * @param logger collects stats for initialization if provided.
+ * @param initStatsBuilder collects stats for initialization if provided.
*/
@NonNull
public static AppSearchImpl create(
@NonNull File icingDir,
- @NonNull Context userContext,
- @Nullable AppSearchLogger logger,
+ @Nullable InitializeStats.Builder initStatsBuilder,
@NonNull OptimizeStrategy optimizeStrategy)
throws AppSearchException {
- Objects.requireNonNull(icingDir);
- Objects.requireNonNull(userContext);
- Objects.requireNonNull(optimizeStrategy);
-
- long totalLatencyStartMillis = SystemClock.elapsedRealtime();
- InitializeStats.Builder initStatsBuilder = null;
- if (logger != null) {
- initStatsBuilder = new InitializeStats.Builder();
- }
-
- AppSearchImpl appSearchImpl =
- new AppSearchImpl(
- icingDir, userContext, initStatsBuilder, optimizeStrategy);
-
- long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
- appSearchImpl.initializeVisibilityStore();
- long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
-
- if (logger != null) {
- initStatsBuilder
- .setTotalLatencyMillis(
- (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
- .setPrepareVisibilityStoreLatencyMillis(
- (int)
- (prepareVisibilityStoreLatencyEndMillis
- - prepareVisibilityStoreLatencyStartMillis));
- logger.logStats(initStatsBuilder.build());
- }
-
- return appSearchImpl;
+ return new AppSearchImpl(icingDir, initStatsBuilder, optimizeStrategy);
}
/** @param initStatsBuilder collects stats for initialization if provided. */
private AppSearchImpl(
@NonNull File icingDir,
- @NonNull Context userContext,
@Nullable InitializeStats.Builder initStatsBuilder,
@NonNull OptimizeStrategy optimizeStrategy)
throws AppSearchException {
- mReadWriteLock.writeLock().lock();
+ Objects.requireNonNull(icingDir);
+ mOptimizeStrategy = Objects.requireNonNull(optimizeStrategy);
+ mReadWriteLock.writeLock().lock();
try {
// We synchronize here because we don't want to call IcingSearchEngine.initialize() more
// than once. It's unnecessary and can be a costly operation.
@@ -258,9 +225,6 @@ public final class AppSearchImpl implements Closeable {
"Constructing IcingSearchEngine, response",
Objects.hashCode(mIcingSearchEngineLocked));
- mVisibilityStoreLocked = new VisibilityStore(this, userContext);
- mOptimizeStrategy = optimizeStrategy;
-
// The core initialization procedure. If any part of this fails, we bail into
// resetLocked(), deleting all data (but hopefully allowing AppSearchImpl to come up).
try {
@@ -342,23 +306,6 @@ public final class AppSearchImpl implements Closeable {
}
}
- /**
- * Initialize the visibility store in AppSearchImpl.
- *
- * @throws AppSearchException on IcingSearchEngine error.
- */
- void initializeVisibilityStore() throws AppSearchException {
- mReadWriteLock.writeLock().lock();
- try {
- throwIfClosedLocked();
- mLogUtil.piiTrace("Initializing VisibilityStore, request");
- mVisibilityStoreLocked.initialize();
- mLogUtil.piiTrace("Initializing VisibilityStore, response");
- } finally {
- mReadWriteLock.writeLock().unlock();
- }
- }
-
@GuardedBy("mReadWriteLock")
private void throwIfClosedLocked() {
if (mClosedLocked) {
@@ -399,6 +346,8 @@ public final class AppSearchImpl implements Closeable {
* @param packageName The package name that owns the schemas.
* @param databaseName The name of the database where this schema lives.
* @param schemas Schemas to set for this app.
+ * @param visibilityStore If set, {@code schemasNotPlatformSurfaceable} and {@code
+ * schemasPackageAccessible} will be saved here if the schema is successfully applied.
* @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
* surfaces.
* @param schemasPackageAccessible Schema types that are visible to the specified packages.
@@ -416,6 +365,7 @@ public final class AppSearchImpl implements Closeable {
@NonNull String packageName,
@NonNull String databaseName,
@NonNull List<AppSearchSchema> schemas,
+ @Nullable VisibilityStore visibilityStore,
@NonNull List<String> schemasNotPlatformSurfaceable,
@NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible,
boolean forceOverride,
@@ -479,25 +429,27 @@ public final class AppSearchImpl implements Closeable {
removeFromMap(mSchemaMapLocked, prefix, schemaType);
}
- Set<String> prefixedSchemasNotPlatformSurfaceable =
- new ArraySet<>(schemasNotPlatformSurfaceable.size());
- for (int i = 0; i < schemasNotPlatformSurfaceable.size(); i++) {
- prefixedSchemasNotPlatformSurfaceable.add(
- prefix + schemasNotPlatformSurfaceable.get(i));
- }
+ if (visibilityStore != null) {
+ Set<String> prefixedSchemasNotPlatformSurfaceable =
+ new ArraySet<>(schemasNotPlatformSurfaceable.size());
+ for (int i = 0; i < schemasNotPlatformSurfaceable.size(); i++) {
+ prefixedSchemasNotPlatformSurfaceable.add(
+ prefix + schemasNotPlatformSurfaceable.get(i));
+ }
- Map<String, List<PackageIdentifier>> prefixedSchemasPackageAccessible =
- new ArrayMap<>(schemasPackageAccessible.size());
- for (Map.Entry<String, List<PackageIdentifier>> entry :
- schemasPackageAccessible.entrySet()) {
- prefixedSchemasPackageAccessible.put(prefix + entry.getKey(), entry.getValue());
- }
+ Map<String, List<PackageIdentifier>> prefixedSchemasPackageAccessible =
+ new ArrayMap<>(schemasPackageAccessible.size());
+ for (Map.Entry<String, List<PackageIdentifier>> entry :
+ schemasPackageAccessible.entrySet()) {
+ prefixedSchemasPackageAccessible.put(prefix + entry.getKey(), entry.getValue());
+ }
- mVisibilityStoreLocked.setVisibility(
- packageName,
- databaseName,
- prefixedSchemasNotPlatformSurfaceable,
- prefixedSchemasPackageAccessible);
+ visibilityStore.setVisibility(
+ packageName,
+ databaseName,
+ prefixedSchemasNotPlatformSurfaceable,
+ prefixedSchemasPackageAccessible);
+ }
return SetSchemaResponseToProtoConverter.toSetSchemaResponse(
setSchemaResultProto, prefix);
@@ -817,7 +769,11 @@ public final class AppSearchImpl implements Closeable {
* @param searchSpec Spec for setting filters, raw query etc.
* @param callerPackageName Package name of the caller, should belong to the {@code
* userContext}.
+ * @param visibilityStore Optional visibility store to obtain system and package visibility
+ * settings from
* @param callerUid UID of the client making the globalQuery call.
+ * @param callerHasSystemAccess Whether the caller has been positively identified as having
+ * access to schemas marked system surfaceable.
* @param logger logger to collect globalQuery stats
* @return The results of performing this search. It may contain an empty list of results if no
* documents matched the query.
@@ -828,7 +784,9 @@ public final class AppSearchImpl implements Closeable {
@NonNull String queryExpression,
@NonNull SearchSpec searchSpec,
@NonNull String callerPackageName,
+ @Nullable VisibilityStore visibilityStore,
int callerUid,
+ boolean callerHasSystemAccess,
@Nullable AppSearchLogger logger)
throws AppSearchException {
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
@@ -885,15 +843,18 @@ public final class AppSearchImpl implements Closeable {
if (packageName.equals(callerPackageName)) {
// Callers can always retrieve their own data
allow = true;
+ } else if (visibilityStore == null) {
+ // If there's no visibility store, there's no extra access
+ allow = false;
} else {
String databaseName = getDatabaseName(prefixedSchema);
allow =
- mVisibilityStoreLocked.isSchemaSearchableByCaller(
+ visibilityStore.isSchemaSearchableByCaller(
packageName,
databaseName,
prefixedSchema,
- callerPackageName,
- callerUid);
+ callerUid,
+ callerHasSystemAccess);
}
if (!allow) {
@@ -1488,9 +1449,6 @@ public final class AppSearchImpl implements Closeable {
/**
* Clears documents and schema across all packages and databaseNames.
*
- * <p>This method also clear all data in {@link VisibilityStore}, an {@link
- * #initializeVisibilityStore()} must be called after this.
- *
* <p>This method belongs to mutate group.
*
* @throws AppSearchException on IcingSearchEngine error.
@@ -1514,9 +1472,6 @@ public final class AppSearchImpl implements Closeable {
.setResetStatusCode(statusProtoToResultCode(resetResultProto.getStatus()));
}
- // Must be called after everything else since VisibilityStore may repopulate
- // IcingSearchEngine with an initial schema.
- mVisibilityStoreLocked.handleReset();
checkSuccess(resetResultProto.getStatus());
}
@@ -2075,13 +2030,6 @@ public final class AppSearchImpl implements Closeable {
return result;
}
- @GuardedBy("mReadWriteLock")
- @NonNull
- @VisibleForTesting
- VisibilityStore getVisibilityStoreLocked() {
- return mVisibilityStoreLocked;
- }
-
/**
* Converts an erroneous status code from the Icing status enums to the AppSearchResult enums.
*
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java
deleted file mode 100644
index ea00f506b47f..000000000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2021 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.appsearch.stats;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.appsearch.AppSearchConfig;
-import com.android.server.appsearch.AppSearchManagerService;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Manages the lifecycle of instances of {@link PlatformLogger}.
- *
- * <p>These instances are managed per unique device-user.
- */
-public final class LoggerInstanceManager {
- private static volatile LoggerInstanceManager sLoggerInstanceManager;
-
- @GuardedBy("mInstancesLocked")
- private final Map<UserHandle, PlatformLogger> mInstancesLocked = new ArrayMap<>();
-
- private LoggerInstanceManager() {
- }
-
- /**
- * Gets an instance of {@link LoggerInstanceManager} to be used.
- *
- * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
- * existing instance will be returned.
- */
- @NonNull
- public static LoggerInstanceManager getInstance() {
- if (sLoggerInstanceManager == null) {
- synchronized (LoggerInstanceManager.class) {
- if (sLoggerInstanceManager == null) {
- sLoggerInstanceManager =
- new LoggerInstanceManager();
- }
- }
- }
- return sLoggerInstanceManager;
- }
-
- /**
- * Gets an instance of PlatformLogger for the given user, or creates one if none exists.
- *
- * @param context The context
- * @param userHandle The multi-user handle of the device user calling AppSearch
- * @return An initialized {@link PlatformLogger} for this user
- */
- @NonNull
- public PlatformLogger getOrCreatePlatformLogger(
- @NonNull Context context, @NonNull UserHandle userHandle,
- @NonNull AppSearchConfig config) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- PlatformLogger instance = mInstancesLocked.get(userHandle);
- if (instance == null) {
- instance = new PlatformLogger(context, userHandle, config);
- mInstancesLocked.put(userHandle, instance);
- }
- return instance;
- }
- }
-
- /**
- * Gets an instance of PlatformLogger for the given user.
- *
- * <p>This method should only be called by an initialized SearchSession, which has been already
- * created the PlatformLogger instance for the given user.
- *
- * @param userHandle The multi-user handle of the device user calling AppSearch
- * @return An initialized {@link PlatformLogger} for this user
- * @throws IllegalStateException if {@link PlatformLogger} haven't created for the given user.
- */
- @NonNull
- public PlatformLogger getPlatformLogger(@NonNull UserHandle userHandle) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- PlatformLogger instance = mInstancesLocked.get(userHandle);
- if (instance == null) {
- // Impossible scenario, user cannot call an uninitialized SearchSession,
- // getInstance should always find the instance for the given user and never try to
- // create an instance for this user again.
- throw new IllegalStateException(
- "PlatformLogger has never been created for: " + userHandle);
- }
- return instance;
- }
- }
-
- /**
- * Remove an instance of {@link PlatformLogger} for the given user.
- *
- * <p>This method should only be called if {@link AppSearchManagerService} receives an
- * ACTION_USER_REMOVED, which the logger instance of given user should be removed.
- *
- * @param userHandle The multi-user handle of the user that need to be removed.
- */
- public void removePlatformLoggerForUser(@NonNull UserHandle userHandle) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- mInstancesLocked.remove(userHandle);
- }
- }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java
index 5ad4276d9318..9e36fd02569f 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java
@@ -73,9 +73,4 @@ class NotPlatformSurfaceableMap {
// isn't one of those opt-outs, it's surfaceable.
return !schemaTypes.contains(prefixedSchema);
}
-
- /** Discards all data in the map. */
- public void clear() {
- mMap.clear();
- }
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java
index 2b3934718aed..cff729aa4e8a 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java
@@ -82,9 +82,4 @@ class PackageAccessibleMap {
}
return accessiblePackages;
}
-
- /** Discards all data in the map. */
- public void clear() {
- mMap.clear();
- }
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
index a9f6adb20225..ae1ec56b4ee6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
@@ -99,28 +99,23 @@ public class VisibilityStore {
private final PackageAccessibleMap mPackageAccessibleMap = new PackageAccessibleMap();
/**
- * Creates an uninitialized VisibilityStore object. Callers must also call {@link #initialize()}
- * before using the object.
+ * Creates and initializes VisibilityStore.
*
* @param appSearchImpl AppSearchImpl instance
* @param userContext Context of the user that the call is being made as
*/
- public VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext) {
+ @NonNull
+ public static VisibilityStore create(
+ @NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
+ throws AppSearchException {
+ return new VisibilityStore(appSearchImpl, userContext);
+ }
+
+ private VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
+ throws AppSearchException {
mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
mUserContext = Objects.requireNonNull(userContext);
- }
- /**
- * Initializes schemas and member variables to track visibility settings.
- *
- * <p>This is kept separate from the constructor because this will call methods on
- * AppSearchImpl. Some may even then recursively call back into VisibilityStore (for example,
- * {@link AppSearchImpl#setSchema} will call {@link #setVisibility}. We need to have both
- * AppSearchImpl and VisibilityStore fully initialized for this call flow to work.
- *
- * @throws AppSearchException AppSearchException on AppSearchImpl error.
- */
- public void initialize() throws AppSearchException {
GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
boolean hasVisibilityType = false;
boolean hasPackageAccessibleType = false;
@@ -142,6 +137,7 @@ public class VisibilityStore {
PACKAGE_NAME,
DATABASE_NAME,
Arrays.asList(VisibilityDocument.SCHEMA, PackageAccessibleDocument.SCHEMA),
+ /*visibilityStore=*/ null, // Avoid recursive calls
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -149,7 +145,6 @@ public class VisibilityStore {
}
// Populate visibility settings set
- mNotPlatformSurfaceableMap.clear();
for (Map.Entry<String, Set<String>> entry :
mAppSearchImpl.getPackageToDatabases().entrySet()) {
String packageName = entry.getKey();
@@ -281,38 +276,45 @@ public class VisibilityStore {
}
/**
+ * Checks whether the given package has access to system-surfaceable schemas.
+ *
+ * @param callerPackageName Package name of the caller.
+ */
+ public boolean doesCallerHaveSystemAccess(@NonNull String callerPackageName) {
+ Objects.requireNonNull(callerPackageName);
+ return mUserContext.getPackageManager()
+ .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, callerPackageName)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ /**
* Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}.
*
* @param packageName Package that owns the schema.
* @param databaseName Database within the package that owns the schema.
* @param prefixedSchema Prefixed schema type the caller is trying to access.
- * @param callerPackageName Package name of the caller.
- * @param callerUid Uid of the caller.
+ * @param callerUid UID of the client making the globalQuery call.
+ * @param callerHasSystemAccess Whether the caller has been identified as having
+ * access to schemas marked system surfaceable by {@link
+ * #doesCallerHaveSystemAccess}.
*/
public boolean isSchemaSearchableByCaller(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String prefixedSchema,
- @NonNull String callerPackageName,
- int callerUid) {
+ int callerUid,
+ boolean callerHasSystemAccess) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
Objects.requireNonNull(prefixedSchema);
- Objects.requireNonNull(callerPackageName);
if (packageName.equals(PACKAGE_NAME)) {
return false; // VisibilityStore schemas are for internal bookkeeping.
}
- // TODO(b/180058203): If we can cache or pass in that a caller has the
- // READ_GLOBAL_SEARCH_DATA permission, then we can save this package manager lookup for
- // each schema we may check in the loop.
- if (mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable(
- packageName, databaseName, prefixedSchema)
- && mUserContext
- .getPackageManager()
- .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, callerPackageName)
- == PackageManager.PERMISSION_GRANTED) {
+ if (callerHasSystemAccess
+ && mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable(
+ packageName, databaseName, prefixedSchema)) {
return true;
}
@@ -373,16 +375,6 @@ public class VisibilityStore {
}
/**
- * Handles an {@code AppSearchImpl#reset()} by clearing any cached state.
- *
- * <p>{@link #initialize()} must be called after this.
- */
- public void handleReset() {
- mNotPlatformSurfaceableMap.clear();
- mPackageAccessibleMap.clear();
- }
-
- /**
* Adds a prefix to create a visibility store document's id.
*
* @param packageName Package to which the visibility doc refers
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
index 8666fa6ac35a..aadaba4d2fce 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
@@ -42,6 +42,7 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.compatibility.common.util.SystemUtil;
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
+import com.android.server.appsearch.visibilitystore.VisibilityStore;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -66,6 +67,7 @@ public class AppSearchImplPlatformTest {
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
private Context mContext;
private AppSearchImpl mAppSearchImpl;
+ private VisibilityStore mVisibilityStore;
private int mGlobalQuerierUid;
@Before
@@ -89,13 +91,9 @@ public class AppSearchImplPlatformTest {
};
// Give ourselves global query permissions
- mAppSearchImpl =
- AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- mContext,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
-
+ mAppSearchImpl = AppSearchImpl.create(
+ mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+ mVisibilityStore = VisibilityStore.create(mAppSearchImpl, mContext);
mGlobalQuerierUid =
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
}
@@ -128,6 +126,7 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
"schema1",
@@ -136,26 +135,20 @@ public class AppSearchImplPlatformTest {
/*schemaVersion=*/ 0);
// "schema1" is platform hidden now and package visible to package1
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
// Add a new schema, and include the already-existing "schema1"
@@ -165,6 +158,7 @@ public class AppSearchImplPlatformTest {
ImmutableList.of(
new AppSearchSchema.Builder("schema1").build(),
new AppSearchSchema.Builder("schema2").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
"schema1",
@@ -174,50 +168,40 @@ public class AppSearchImplPlatformTest {
// Check that "schema1" still has the same visibility settings
SystemUtil.runWithShellPermissionIdentity(() -> assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse(),
READ_GLOBAL_APP_SEARCH_DATA);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
// "schema2" has default visibility settings
SystemUtil.runWithShellPermissionIdentity(() -> assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema2",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema2",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue(),
READ_GLOBAL_APP_SEARCH_DATA);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema2",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema2",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
}
@@ -248,6 +232,7 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
"schema1",
@@ -256,26 +241,20 @@ public class AppSearchImplPlatformTest {
/*schemaVersion=*/ 0);
// "schema1" is platform hidden now and package accessible
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
// Remove "schema1" by force overriding
@@ -283,32 +262,27 @@ public class AppSearchImplPlatformTest {
"package",
"database",
/*schemas=*/ Collections.emptyList(),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*schemaVersion=*/ 0);
// Check that "schema1" is no longer considered platform hidden or package accessible
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
// Add "schema1" back, it gets default visibility settings which means it's not platform
@@ -317,30 +291,25 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "schema1",
- packageNameFoo,
- uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "schema1",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
}
@@ -357,20 +326,18 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "Schema",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "Schema",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
}
@@ -387,20 +354,18 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("Schema"),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
- .isSchemaSearchableByCaller(
- "package",
- "database",
- prefix + "Schema",
- mContext.getPackageName(),
- mGlobalQuerierUid))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ prefix + "Schema",
+ mGlobalQuerierUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
}
@@ -418,19 +383,18 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
+ assertThat(mVisibilityStore
.isSchemaSearchableByCaller(
"package",
"database",
prefix + "Schema",
- packageName,
- /*callerUid=*/ 42))
+ /*callerUid=*/ 42,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
}
@@ -458,21 +422,20 @@ public class AppSearchImplPlatformTest {
"package",
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+ mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
"Schema",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
- assertThat(
- mAppSearchImpl
- .getVisibilityStoreLocked()
+ assertThat(mVisibilityStore
.isSchemaSearchableByCaller(
"package",
"database",
prefix + "Schema",
- packageNameFoo,
- uidFoo))
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
index 4faffc025e2f..b67ebe423eab 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
@@ -88,15 +88,10 @@ public class VisibilityStoreTest {
};
// Give ourselves global query permissions
- AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- mContext,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
-
+ AppSearchImpl appSearchImpl = AppSearchImpl.create(
+ mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+ mVisibilityStore = VisibilityStore.create(appSearchImpl, mContext);
mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
- mVisibilityStore = appSearchImpl.getVisibilityStoreLocked();
}
/**
@@ -122,12 +117,28 @@ public class VisibilityStoreTest {
}
@Test
+ public void testDoesCallerHaveSystemAccess() {
+ PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
+ when(mockPackageManager
+ .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
+ .thenReturn(PERMISSION_GRANTED);
+ assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName())).isTrue();
+
+ when(mockPackageManager
+ .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
+ .thenReturn(PERMISSION_DENIED);
+ assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName()))
+ .isFalse();
+ }
+
+ @Test
public void testSetVisibility_platformSurfaceable() throws Exception {
// Make sure we have global query privileges
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
when(mockPackageManager
.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
.thenReturn(PERMISSION_GRANTED);
+ assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName())).isTrue();
mVisibilityStore.setVisibility(
"package",
@@ -140,16 +151,16 @@ public class VisibilityStoreTest {
"package",
"database",
"prefix/schema1",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
"database",
"prefix/schema2",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
// New .setVisibility() call completely overrides previous visibility settings.
@@ -165,24 +176,24 @@ public class VisibilityStoreTest {
"package",
"database",
"prefix/schema1",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
"database",
"prefix/schema2",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
"database",
"prefix/schema3",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isFalse();
// Everything defaults to visible again.
@@ -196,24 +207,24 @@ public class VisibilityStoreTest {
"package",
"database",
"prefix/schema1",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
"database",
"prefix/schema2",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
"database",
"prefix/schema3",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
}
@@ -242,13 +253,19 @@ public class VisibilityStoreTest {
.thenReturn(PERMISSION_DENIED);
// By default, a schema isn't package accessible.
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaBar", packageNameBar, uidBar))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaBar",
+ uidBar,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
// Grant package access
@@ -268,9 +285,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
.thenReturn(false);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
// Should fail if PackageManager doesn't think the package belongs to the uid
@@ -279,9 +299,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
.thenReturn(true);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
// But if uid and certificate match, then we should have access
@@ -290,9 +313,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
.thenReturn(true);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
when(mockPackageManager.getPackageUid(eq(packageNameBar), /*flags=*/ anyInt()))
@@ -300,9 +326,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameBar, sha256CertBar, PackageManager.CERT_INPUT_SHA256))
.thenReturn(true);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaBar", packageNameBar, uidBar))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaBar",
+ uidBar,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
// New .setVisibility() call completely overrides previous visibility settings. So
@@ -320,9 +349,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
.thenReturn(true);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
when(mockPackageManager.getPackageUid(eq(packageNameBar), /*flags=*/ anyInt()))
@@ -330,9 +362,12 @@ public class VisibilityStoreTest {
when(mockPackageManager.hasSigningCertificate(
packageNameBar, sha256CertBar, PackageManager.CERT_INPUT_SHA256))
.thenReturn(true);
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaBar", packageNameBar, uidBar))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaBar",
+ uidBar,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
}
@@ -363,9 +398,12 @@ public class VisibilityStoreTest {
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
// If we can't verify the Foo package that has access, assume it doesn't have access.
- assertThat(
- mVisibilityStore.isSchemaSearchableByCaller(
- "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo))
+ assertThat(mVisibilityStore.isSchemaSearchableByCaller(
+ "package",
+ "database",
+ "prefix/schemaFoo",
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isFalse();
}
@@ -397,8 +435,8 @@ public class VisibilityStoreTest {
/*packageName=*/ "",
/*databaseName=*/ "",
"schema",
- mContext.getPackageName(),
- mUid))
+ mUid,
+ /*callerHasSystemAccess=*/ true))
.isTrue();
when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
@@ -411,8 +449,8 @@ public class VisibilityStoreTest {
/*packageName=*/ "",
/*databaseName=*/ "",
"schema",
- packageNameFoo,
- uidFoo))
+ uidFoo,
+ /*callerHasSystemAccess=*/ false))
.isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index e26cfeab1529..f032402f47a0 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -83,15 +83,9 @@ public class AppSearchImplTest {
@Before
public void setUp() throws Exception {
- Context context = ApplicationProvider.getApplicationContext();
-
- // Give ourselves global query permissions.
mAppSearchImpl =
AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
}
/**
@@ -149,7 +143,7 @@ public class AppSearchImplTest {
.build();
AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
- mAppSearchImpl.rewriteSchema(
+ AppSearchImpl.rewriteSchema(
createPrefix("package", "newDatabase"), existingSchemaBuilder, newSchema);
// We rewrote all the new types that were added. And nothing was removed.
@@ -249,7 +243,7 @@ public class AppSearchImplTest {
.build();
AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
- mAppSearchImpl.rewriteSchema(
+ AppSearchImpl.rewriteSchema(
createPrefix("package", "existingDatabase"),
existingSchemaBuilder,
newSchema);
@@ -284,7 +278,7 @@ public class AppSearchImplTest {
.build();
AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
- mAppSearchImpl.rewriteSchema(
+ AppSearchImpl.rewriteSchema(
createPrefix("package", "existingDatabase"),
existingSchemaBuilder,
newSchema);
@@ -386,7 +380,7 @@ public class AppSearchImplTest {
}
@Test
- public void testRemoveDatabasesFromDocumentThrowsException() throws Exception {
+ public void testRemoveDatabasesFromDocumentThrowsException() {
// Set two different database names in the document, which should never happen
DocumentProto documentProto =
DocumentProto.newBuilder()
@@ -403,7 +397,7 @@ public class AppSearchImplTest {
}
@Test
- public void testNestedRemoveDatabasesFromDocumentThrowsException() throws Exception {
+ public void testNestedRemoveDatabasesFromDocumentThrowsException() {
// Set two different database names in the outer and inner document, which should never
// happen.
DocumentProto insideDocument =
@@ -436,6 +430,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -473,11 +468,7 @@ public class AppSearchImplTest {
Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
// Insert schema
List<AppSearchSchema> schemas =
@@ -488,6 +479,7 @@ public class AppSearchImplTest {
context.getPackageName(),
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -506,7 +498,9 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
+ /*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
+ /*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -532,18 +526,13 @@ public class AppSearchImplTest {
PutResultProto putResultProto = appSearchImpl.mIcingSearchEngineLocked.put(invalidDoc);
assertThat(putResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.OK);
- // Create a logger for capturing initialization to make sure we are logging the recovery
- // process correctly.
- AppSearchLoggerTest.TestLogger testLogger = new AppSearchLoggerTest.TestLogger();
-
// Initialize AppSearchImpl. This should cause a reset.
+ InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
appSearchImpl.close();
- appSearchImpl =
- AppSearchImpl.create(
- appsearchDir, context, testLogger, ALWAYS_OPTIMIZE);
+ appSearchImpl = AppSearchImpl.create(appsearchDir, initStatsBuilder, ALWAYS_OPTIMIZE);
// Check recovery state
- InitializeStats initStats = testLogger.mInitializeStats;
+ InitializeStats initStats = initStatsBuilder.build();
assertThat(initStats).isNotNull();
assertThat(initStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
assertThat(initStats.hasDeSync()).isFalse();
@@ -568,7 +557,9 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
+ /*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
+ /*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).isEmpty();
@@ -577,6 +568,7 @@ public class AppSearchImplTest {
context.getPackageName(),
"database1",
Collections.singletonList(new AppSearchSchema.Builder("Type1").build()),
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -592,7 +584,9 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
+ /*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
+ /*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -609,6 +603,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -642,6 +637,7 @@ public class AppSearchImplTest {
"package",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -650,6 +646,7 @@ public class AppSearchImplTest {
"package",
"database2",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -694,6 +691,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -735,6 +733,7 @@ public class AppSearchImplTest {
"package1",
"database1",
schema1,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -747,6 +746,7 @@ public class AppSearchImplTest {
"package2",
"database2",
schema2,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -789,6 +789,7 @@ public class AppSearchImplTest {
"package1",
"database1",
schema1,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -801,6 +802,7 @@ public class AppSearchImplTest {
"package2",
"database2",
schema2,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -848,7 +850,9 @@ public class AppSearchImplTest {
"",
searchSpec,
/*callerPackageName=*/ "",
+ /*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
+ /*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(searchResultPage.getResults()).isEmpty();
}
@@ -888,6 +892,7 @@ public class AppSearchImplTest {
"package",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -911,9 +916,6 @@ public class AppSearchImplTest {
@Test
public void testSetSchema_incompatible() throws Exception {
- List<SchemaTypeConfigProto> existingSchemas =
- mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-
List<AppSearchSchema> oldSchemas = new ArrayList<>();
oldSchemas.add(
new AppSearchSchema.Builder("Email")
@@ -935,6 +937,7 @@ public class AppSearchImplTest {
"package",
"database1",
oldSchemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -950,6 +953,7 @@ public class AppSearchImplTest {
"package",
"database1",
newSchemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
@@ -972,6 +976,7 @@ public class AppSearchImplTest {
"package",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1004,6 +1009,7 @@ public class AppSearchImplTest {
"package",
"database1",
finalSchemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1017,6 +1023,7 @@ public class AppSearchImplTest {
"package",
"database1",
finalSchemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
@@ -1054,6 +1061,7 @@ public class AppSearchImplTest {
"package",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1062,6 +1070,7 @@ public class AppSearchImplTest {
"package",
"database2",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1101,6 +1110,7 @@ public class AppSearchImplTest {
"package",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
@@ -1145,6 +1155,7 @@ public class AppSearchImplTest {
"package",
"database",
schema,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1206,6 +1217,7 @@ public class AppSearchImplTest {
"packageA",
"database",
schema,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1214,6 +1226,7 @@ public class AppSearchImplTest {
"packageB",
"database",
schema,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1259,6 +1272,7 @@ public class AppSearchImplTest {
"package1",
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1272,6 +1286,7 @@ public class AppSearchImplTest {
"package1",
"database2",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1285,6 +1300,7 @@ public class AppSearchImplTest {
"package2",
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1343,6 +1359,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1493,6 +1510,7 @@ public class AppSearchImplTest {
"package1",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1515,6 +1533,7 @@ public class AppSearchImplTest {
"package1",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1530,6 +1549,7 @@ public class AppSearchImplTest {
"package2",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1578,6 +1598,7 @@ public class AppSearchImplTest {
"package1",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1600,6 +1621,7 @@ public class AppSearchImplTest {
"package1",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1621,6 +1643,7 @@ public class AppSearchImplTest {
"package1",
"database1",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1629,6 +1652,7 @@ public class AppSearchImplTest {
"package1",
"database2",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1664,13 +1688,9 @@ public class AppSearchImplTest {
@Test
public void testThrowsExceptionIfClosed() throws Exception {
- Context context = ApplicationProvider.getApplicationContext();
AppSearchImpl appSearchImpl =
AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
// Initial check that we could do something at first.
List<AppSearchSchema> schemas =
@@ -1679,6 +1699,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1689,140 +1710,115 @@ public class AppSearchImplTest {
// Check all our public APIs
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.setSchema(
- "package",
- "database",
- schemas,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
- /*forceOverride=*/ false,
- /*version=*/ 0);
- });
+ () ->
+ appSearchImpl.setSchema(
+ "package",
+ "database",
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+ /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0));
expectThrows(
- IllegalStateException.class,
- () -> {
- appSearchImpl.getSchema("package", "database");
- });
+ IllegalStateException.class, () -> appSearchImpl.getSchema("package", "database"));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.putDocument(
- "package",
- "database",
- new GenericDocument.Builder<>("namespace", "id", "type").build(),
- /*logger=*/ null);
- });
+ () ->
+ appSearchImpl.putDocument(
+ "package",
+ "database",
+ new GenericDocument.Builder<>("namespace", "id", "type").build(),
+ /*logger=*/ null));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.getDocument(
- "package", "database", "namespace", "id", Collections.emptyMap());
- });
+ () ->
+ appSearchImpl.getDocument(
+ "package", "database", "namespace", "id", Collections.emptyMap()));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.query(
- "package",
- "database",
- "query",
- new SearchSpec.Builder()
- .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
- .build(),
- /*logger=*/ null);
- });
+ () ->
+ appSearchImpl.query(
+ "package",
+ "database",
+ "query",
+ new SearchSpec.Builder().build(),
+ /*logger=*/ null));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.globalQuery(
- "query",
- new SearchSpec.Builder()
- .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
- .build(),
- "package",
- VisibilityStore.NO_OP_UID,
- /*logger=*/ null);
- });
+ () ->
+ appSearchImpl.globalQuery(
+ "query",
+ new SearchSpec.Builder().build(),
+ "package",
+ /*visibilityStore=*/ null,
+ VisibilityStore.NO_OP_UID,
+ /*callerHasSystemAccess=*/ false,
+ /*logger=*/ null));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.getNextPage(/*nextPageToken=*/ 1L);
- });
+ () -> appSearchImpl.getNextPage(/*nextPageToken=*/ 1L));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.invalidateNextPageToken(/*nextPageToken=*/ 1L);
- });
+ () -> appSearchImpl.invalidateNextPageToken(/*nextPageToken=*/ 1L));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.reportUsage(
- "package",
- "database",
- "namespace",
- "id",
- /*usageTimestampMillis=*/ 1000L,
- /*systemUsage=*/ false);
- });
+ () ->
+ appSearchImpl.reportUsage(
+ "package",
+ "database",
+ "namespace",
+ "id",
+ /*usageTimestampMillis=*/ 1000L,
+ /*systemUsage=*/ false));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.remove(
- "package", "database", "namespace", "id", /*statsBuilder=*/ null);
- });
+ () ->
+ appSearchImpl.remove(
+ "package",
+ "database",
+ "namespace",
+ "id",
+ /*removeStatsBuilder=*/ null));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.removeByQuery(
- "package",
- "database",
- "query",
- new SearchSpec.Builder()
- .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
- .build(),
- /*statsBuilder=*/ null);
- });
+ () ->
+ appSearchImpl.removeByQuery(
+ "package",
+ "database",
+ "query",
+ new SearchSpec.Builder().build(),
+ /*removeStatsBuilder=*/ null));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.getStorageInfoForPackage("package");
- });
+ () -> appSearchImpl.getStorageInfoForPackage("package"));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.getStorageInfoForDatabase("package", "database");
- });
+ () -> appSearchImpl.getStorageInfoForDatabase("package", "database"));
expectThrows(
IllegalStateException.class,
- () -> {
- appSearchImpl.persistToDisk(PersistType.Code.FULL);
- });
+ () -> appSearchImpl.persistToDisk(PersistType.Code.FULL));
}
@Test
public void testPutPersistsWithLiteFlush() throws Exception {
// Setup the index
- Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1830,6 +1826,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1848,11 +1845,7 @@ public class AppSearchImplTest {
// That document should be visible even from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
getResult =
appSearchImpl2.getDocument(
"package", "database", "namespace1", "id1", Collections.emptyMap());
@@ -1862,14 +1855,9 @@ public class AppSearchImplTest {
@Test
public void testDeletePersistsWithLiteFlush() throws Exception {
// Setup the index
- Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1877,6 +1865,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -1919,11 +1908,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
expectThrows(
AppSearchException.class,
() ->
@@ -1942,14 +1927,9 @@ public class AppSearchImplTest {
@Test
public void testDeleteByQueryPersistsWithLiteFlush() throws Exception {
// Setup the index
- Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1957,6 +1937,7 @@ public class AppSearchImplTest {
"package",
"database",
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -2007,11 +1988,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(
- appsearchDir,
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
expectThrows(
AppSearchException.class,
() ->
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
index c6726c69c7fd..f20e8c6d13a9 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
@@ -25,9 +25,6 @@ import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
-import android.content.Context;
-
-import androidx.test.core.app.ApplicationProvider;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
@@ -60,15 +57,9 @@ public class AppSearchLoggerTest {
@Before
public void setUp() throws Exception {
- Context context = ApplicationProvider.getApplicationContext();
-
- // Give ourselves global query permissions
mAppSearchImpl =
AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- context,
- /*logger=*/ null,
- ALWAYS_OPTIMIZE);
+ mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
mLogger = new TestLogger();
}
@@ -289,20 +280,15 @@ public class AppSearchLoggerTest {
//
@Test
public void testLoggingStats_initialize() throws Exception {
- Context context = ApplicationProvider.getApplicationContext();
-
// Create an unused AppSearchImpl to generated an InitializeStats.
- AppSearchImpl appSearchImpl =
- AppSearchImpl.create(
- mTemporaryFolder.newFolder(),
- context,
- mLogger,
- ALWAYS_OPTIMIZE);
+ InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
+ AppSearchImpl.create(mTemporaryFolder.newFolder(), initStatsBuilder, ALWAYS_OPTIMIZE);
+ InitializeStats iStats = initStatsBuilder.build();
- InitializeStats iStats = mLogger.mInitializeStats;
assertThat(iStats).isNotNull();
assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
- assertThat(iStats.getTotalLatencyMillis()).isGreaterThan(0);
+ // Total latency captured in LocalStorage
+ assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
assertThat(iStats.hasDeSync()).isFalse();
assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
assertThat(iStats.getDocumentStoreDataStatus())
@@ -322,6 +308,7 @@ public class AppSearchLoggerTest {
testPackageName,
testDatabase,
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -350,10 +337,12 @@ public class AppSearchLoggerTest {
testPackageName,
testDatabase,
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
+
GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
@@ -401,6 +390,7 @@ public class AppSearchLoggerTest {
testPackageName,
testDatabase,
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
@@ -432,6 +422,7 @@ public class AppSearchLoggerTest {
testPackageName,
testDatabase,
schemas,
+ /*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,