Support platform AppSearchManager(backend) to accept database name.
This change also add namespace for getByUri and deleteByUri in AppSearchManagerService Bug: 170285774 Test: AppSearchManagerTest Change-Id: I8044fc5f22dbd03b2d73f85806659e12d75d8afa
This commit is contained in:
@@ -40,6 +40,7 @@ import java.util.concurrent.ExecutionException;
|
||||
// TODO(b/148046169): This class header needs a detailed example/tutorial.
|
||||
@SystemService(Context.APP_SEARCH_SERVICE)
|
||||
public class AppSearchManager {
|
||||
private static final String DEFAULT_DATABASE = "";
|
||||
private final IAppSearchManager mService;
|
||||
|
||||
/** @hide */
|
||||
@@ -112,7 +113,7 @@ public class AppSearchManager {
|
||||
}
|
||||
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.setSchema(schemaBundles, request.isForceOverride(), future);
|
||||
mService.setSchema(DEFAULT_DATABASE, schemaBundles, request.isForceOverride(), future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ public class AppSearchManager {
|
||||
}
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.putDocuments(documentBundles, future);
|
||||
mService.putDocuments(DEFAULT_DATABASE, documentBundles, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
@@ -172,7 +173,7 @@ public class AppSearchManager {
|
||||
List<String> uris = new ArrayList<>(request.getUris());
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getDocuments(uris, future);
|
||||
mService.getDocuments(DEFAULT_DATABASE, request.getNamespace(), uris, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
@@ -260,7 +261,8 @@ public class AppSearchManager {
|
||||
// them in one big list.
|
||||
AndroidFuture<AppSearchResult> searchResultsFuture = new AndroidFuture<>();
|
||||
try {
|
||||
mService.query(queryExpression, searchSpec.getBundle(), searchResultsFuture);
|
||||
mService.query(DEFAULT_DATABASE, queryExpression,
|
||||
searchSpec.getBundle(), searchResultsFuture);
|
||||
} catch (RemoteException e) {
|
||||
searchResultsFuture.completeExceptionally(e);
|
||||
}
|
||||
@@ -292,7 +294,7 @@ public class AppSearchManager {
|
||||
List<String> uris = new ArrayList<>(request.getUris());
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.delete(uris, future);
|
||||
mService.delete(DEFAULT_DATABASE, request.getNamespace(), uris, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
@@ -300,7 +302,7 @@ public class AppSearchManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes {@link android.app.appsearch.AppSearch.Document}s by schema type.
|
||||
* Deletes {@link android.app.appsearch.GenericDocument}s by schema type.
|
||||
*
|
||||
* <p>You should not call this method directly; instead, use the
|
||||
* {@code AppSearch#deleteByType()} API provided by JetPack.
|
||||
@@ -313,7 +315,7 @@ public class AppSearchManager {
|
||||
public AppSearchBatchResult<String, Void> deleteByTypes(@NonNull List<String> schemaTypes) {
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.deleteByTypes(schemaTypes, future);
|
||||
mService.deleteByTypes(DEFAULT_DATABASE, schemaTypes, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
@@ -324,7 +326,7 @@ public class AppSearchManager {
|
||||
public AppSearchResult<Void> deleteAll() {
|
||||
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.deleteAll(future);
|
||||
mService.deleteAll(DEFAULT_DATABASE, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Sets the schema.
|
||||
*
|
||||
* @param databaseName The databaseName this document resides in.
|
||||
* @param schemaBundles List of AppSearchSchema bundles.
|
||||
* @param forceOverride Whether to apply the new schema even if it is incompatible. All
|
||||
* incompatible documents will be deleted.
|
||||
@@ -35,6 +36,7 @@ interface IAppSearchManager {
|
||||
* The results of the call.
|
||||
*/
|
||||
void setSchema(
|
||||
in String databaseName,
|
||||
in List<Bundle> schemaBundles,
|
||||
boolean forceOverride,
|
||||
in AndroidFuture<AppSearchResult> callback);
|
||||
@@ -42,6 +44,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Inserts documents into the index.
|
||||
*
|
||||
* @param databaseName The name of the database where this document lives.
|
||||
* @param documentBundes List of GenericDocument bundles.
|
||||
* @param callback
|
||||
* {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>.
|
||||
@@ -51,11 +54,15 @@ interface IAppSearchManager {
|
||||
* where the keys are document URIs, and the values are {@code null}.
|
||||
*/
|
||||
void putDocuments(
|
||||
in List<Bundle> documentBundles, in AndroidFuture<AppSearchBatchResult> callback);
|
||||
in String databaseName,
|
||||
in List<Bundle> documentBundles,
|
||||
in AndroidFuture<AppSearchBatchResult> callback);
|
||||
|
||||
/**
|
||||
* Retrieves documents from the index.
|
||||
*
|
||||
* @param databaseName The databaseName this document resides in.
|
||||
* @param namespace The namespace this document resides in.
|
||||
* @param uris The URIs of the documents to retrieve
|
||||
* @param callback
|
||||
* {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Bundle}>>.
|
||||
@@ -64,16 +71,22 @@ interface IAppSearchManager {
|
||||
* {@link AppSearchBatchResult}<{@link String}, {@link Bundle}>
|
||||
* where the keys are document URIs, and the values are Document bundles.
|
||||
*/
|
||||
void getDocuments(in List<String> uris, in AndroidFuture<AppSearchBatchResult> callback);
|
||||
void getDocuments(
|
||||
in String databaseName,
|
||||
in String namespace,
|
||||
in List<String> uris,
|
||||
in AndroidFuture<AppSearchBatchResult> callback);
|
||||
|
||||
/**
|
||||
* Searches a document based on a given specifications.
|
||||
*
|
||||
* @param databaseName The databaseName this query for.
|
||||
* @param queryExpression String to search for
|
||||
* @param searchSpecBundle SearchSpec bundle
|
||||
* @param callback {@link AndroidFuture}<{@link AppSearchResult}<{@link SearchResults}>>
|
||||
*/
|
||||
void query(
|
||||
in String databaseName,
|
||||
in String queryExpression,
|
||||
in Bundle searchSpecBundle,
|
||||
in AndroidFuture<AppSearchResult> callback);
|
||||
@@ -81,6 +94,8 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Deletes documents by URI.
|
||||
*
|
||||
* @param databaseName The databaseName the document is in.
|
||||
* @param namespace Namespace of the document to remove.
|
||||
* @param uris The URIs of the documents to delete
|
||||
* @param callback
|
||||
* {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>.
|
||||
@@ -90,11 +105,16 @@ interface IAppSearchManager {
|
||||
* where the keys are document URIs. If a document doesn't exist, it will be reported as a
|
||||
* failure where the {@code throwable} is {@code null}.
|
||||
*/
|
||||
void delete(in List<String> uris, in AndroidFuture<AppSearchBatchResult> callback);
|
||||
void delete(
|
||||
in String databaseName,
|
||||
in String namespace,
|
||||
in List<String> uris,
|
||||
in AndroidFuture<AppSearchBatchResult> callback);
|
||||
|
||||
/**
|
||||
* Deletes documents by schema type.
|
||||
*
|
||||
* @param databaseName The databaseName the document is in.
|
||||
* @param schemaTypes The schema types of the documents to delete
|
||||
* @param callback
|
||||
* {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>.
|
||||
@@ -105,13 +125,16 @@ interface IAppSearchManager {
|
||||
* failure where the {@code throwable} is {@code null}.
|
||||
*/
|
||||
void deleteByTypes(
|
||||
in List<String> schemaTypes, in AndroidFuture<AppSearchBatchResult> callback);
|
||||
in String databaseName,
|
||||
in List<String> schemaTypes,
|
||||
in AndroidFuture<AppSearchBatchResult> callback);
|
||||
|
||||
/**
|
||||
* Deletes all documents belonging to the calling app.
|
||||
*
|
||||
* @param databaseName The databaseName to remove all documents from.
|
||||
* @param callback {@link AndroidFuture}<{@link AppSearchResult}<{@link Void}>>.
|
||||
* Will be completed with the result of the call.
|
||||
*/
|
||||
void deleteAll(in AndroidFuture<AppSearchResult> callback);
|
||||
void deleteAll(in String databaseName, in AndroidFuture<AppSearchResult> callback);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import java.util.List;
|
||||
*/
|
||||
public class AppSearchManagerService extends SystemService {
|
||||
private static final String TAG = "AppSearchManagerService";
|
||||
private static final char CALLING_NAME_DATABASE_DELIMITER = '$';
|
||||
|
||||
public AppSearchManagerService(Context context) {
|
||||
super(context);
|
||||
@@ -66,6 +67,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
private class Stub extends IAppSearchManager.Stub {
|
||||
@Override
|
||||
public void setSchema(
|
||||
@NonNull String databaseName,
|
||||
@NonNull List<Bundle> schemaBundles,
|
||||
boolean forceOverride,
|
||||
@NonNull AndroidFuture<AppSearchResult> callback) {
|
||||
@@ -82,7 +84,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
schemaProtoBuilder.addTypes(schemaTypeProto);
|
||||
}
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
impl.setSchema(databaseName, schemaProtoBuilder.build(), forceOverride);
|
||||
callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null));
|
||||
} catch (Throwable t) {
|
||||
@@ -94,6 +96,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void putDocuments(
|
||||
@NonNull String databaseName,
|
||||
@NonNull List<Bundle> documentBundles,
|
||||
@NonNull AndroidFuture<AppSearchBatchResult> callback) {
|
||||
Preconditions.checkNotNull(documentBundles);
|
||||
@@ -103,7 +106,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
for (int i = 0; i < documentBundles.size(); i++) {
|
||||
@@ -125,7 +128,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDocuments(
|
||||
public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
|
||||
@NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) {
|
||||
Preconditions.checkNotNull(uris);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -134,14 +137,14 @@ public class AppSearchManagerService extends SystemService {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
for (int i = 0; i < uris.size(); i++) {
|
||||
String uri = uris.get(i);
|
||||
try {
|
||||
DocumentProto documentProto = impl.getDocument(
|
||||
databaseName, GenericDocument.DEFAULT_NAMESPACE, uri);
|
||||
databaseName, namespace, uri);
|
||||
if (documentProto == null) {
|
||||
resultBuilder.setFailure(
|
||||
uri, AppSearchResult.RESULT_NOT_FOUND, /*errorMessage=*/ null);
|
||||
@@ -165,6 +168,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
// TODO(sidchhabra): Do this in a threadpool.
|
||||
@Override
|
||||
public void query(
|
||||
@NonNull String databaseName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull Bundle searchSpecBundle,
|
||||
@NonNull AndroidFuture<AppSearchResult> callback) {
|
||||
@@ -181,7 +185,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
searchSpecProto = searchSpecProto.toBuilder()
|
||||
.setQuery(queryExpression).build();
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
// TODO(adorokhine): handle pagination
|
||||
SearchResultProto searchResultProto = impl.query(
|
||||
databaseName,
|
||||
@@ -201,7 +205,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
|
||||
public void delete(@NonNull String databaseName, @NonNull String namespace,
|
||||
List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
|
||||
Preconditions.checkNotNull(uris);
|
||||
Preconditions.checkNotNull(callback);
|
||||
int callingUid = Binder.getCallingUidOrThrow();
|
||||
@@ -209,13 +214,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
for (int i = 0; i < uris.size(); i++) {
|
||||
String uri = uris.get(i);
|
||||
try {
|
||||
impl.remove(databaseName, GenericDocument.DEFAULT_NAMESPACE, uri);
|
||||
impl.remove(databaseName, namespace, uri);
|
||||
resultBuilder.setSuccess(uri, /*result= */null);
|
||||
} catch (Throwable t) {
|
||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||
@@ -230,7 +235,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTypes(
|
||||
public void deleteByTypes(@NonNull String databaseName,
|
||||
List<String> schemaTypes, AndroidFuture<AppSearchBatchResult> callback) {
|
||||
Preconditions.checkNotNull(schemaTypes);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -239,7 +244,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
for (int i = 0; i < schemaTypes.size(); i++) {
|
||||
@@ -260,14 +265,15 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(@NonNull AndroidFuture<AppSearchResult> callback) {
|
||||
public void deleteAll(@NonNull String databaseName,
|
||||
@NonNull AndroidFuture<AppSearchResult> callback) {
|
||||
Preconditions.checkNotNull(callback);
|
||||
int callingUid = Binder.getCallingUidOrThrow();
|
||||
int callingUserId = UserHandle.getUserId(callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String databaseName = makeDatabaseName(callingUid);
|
||||
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
|
||||
impl.removeAll(databaseName);
|
||||
callback.complete(AppSearchResult.newSuccessfulResult(null));
|
||||
} catch (Throwable t) {
|
||||
@@ -278,13 +284,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique database name for the given uid.
|
||||
* Rewrites the database name by adding a prefix of unique name for the given uid.
|
||||
*
|
||||
* <p>The current implementation returns the package name of the app with this uid in a
|
||||
* format like {@code com.example.package} or {@code com.example.sharedname:5678}.
|
||||
*/
|
||||
@NonNull
|
||||
private String makeDatabaseName(int callingUid) {
|
||||
private String rewriteDatabaseNameWithUid(String databaseName, int callingUid) {
|
||||
// For regular apps, this call will return the package name. If callingUid is an
|
||||
// android:sharedUserId, this value may be another type of name and have a :uid suffix.
|
||||
String callingUidName = getContext().getPackageManager().getNameForUid(callingUid);
|
||||
@@ -293,7 +299,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
throw new IllegalStateException(
|
||||
"Failed to look up package name for uid " + callingUid);
|
||||
}
|
||||
return callingUidName;
|
||||
return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName;
|
||||
}
|
||||
|
||||
private <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
|
||||
|
||||
Reference in New Issue
Block a user