Merge "Pass package name across binder."
This commit is contained in:
@@ -46,6 +46,7 @@ import java.util.function.Consumer;
|
||||
public class AppSearchManager {
|
||||
/**
|
||||
* The default empty database name.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEFAULT_DATABASE_NAME = "";
|
||||
@@ -70,8 +71,8 @@ public class AppSearchManager {
|
||||
/**
|
||||
* Returns the name of the database to create or open.
|
||||
*
|
||||
* <p>Databases with different names are fully separate with distinct types, namespaces,
|
||||
* and data.
|
||||
* <p>Databases with different names are fully separate with distinct types, namespaces, and
|
||||
* data.
|
||||
*/
|
||||
@NonNull
|
||||
public String getDatabaseName() {
|
||||
@@ -126,11 +127,11 @@ public class AppSearchManager {
|
||||
* initialization process will create one under the user's credential encrypted directory.
|
||||
*
|
||||
* @param searchContext The {@link SearchContext} contains all information to create a new
|
||||
* {@link AppSearchSession}
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback The {@link AppSearchResult}<{@link AppSearchSession}> of
|
||||
* performing this operation. Or a {@link AppSearchResult} with failure
|
||||
* reason code and error information.
|
||||
* {@link AppSearchSession}
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback The {@link AppSearchResult}<{@link AppSearchSession}> of performing
|
||||
* this operation. Or a {@link AppSearchResult} with failure reason code and error
|
||||
* information.
|
||||
*/
|
||||
public void createSearchSession(
|
||||
@NonNull SearchContext searchContext,
|
||||
@@ -140,7 +141,12 @@ public class AppSearchManager {
|
||||
Objects.requireNonNull(executor);
|
||||
Objects.requireNonNull(callback);
|
||||
AppSearchSession.createSearchSession(
|
||||
searchContext, mService, mContext.getUserId(), executor, callback);
|
||||
searchContext,
|
||||
mService,
|
||||
mContext.getUserId(),
|
||||
getPackageName(),
|
||||
executor,
|
||||
callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,10 +155,10 @@ public class AppSearchManager {
|
||||
* <p>This process requires an AppSearch native indexing file system. If it's not created, the
|
||||
* initialization process will create one under the user's credential encrypted directory.
|
||||
*
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback The {@link AppSearchResult}<{@link GlobalSearchSession}> of
|
||||
* performing this operation. Or a {@link AppSearchResult} with failure
|
||||
* reason code and error information.
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback The {@link AppSearchResult}<{@link GlobalSearchSession}> of performing
|
||||
* this operation. Or a {@link AppSearchResult} with failure reason code and error
|
||||
* information.
|
||||
*/
|
||||
public void createGlobalSearchSession(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@@ -160,7 +166,7 @@ public class AppSearchManager {
|
||||
Objects.requireNonNull(executor);
|
||||
Objects.requireNonNull(callback);
|
||||
GlobalSearchSession.createGlobalSearchSession(
|
||||
mService, mContext.getUserId(), executor, callback);
|
||||
mService, mContext.getUserId(), getPackageName(), executor, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,40 +176,42 @@ public class AppSearchManager {
|
||||
* to {@link #setSchema}, if any, to determine how to treat existing documents. The following
|
||||
* types of schema modifications are always safe and are made without deleting any existing
|
||||
* documents:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Addition of new types
|
||||
* <li>Addition of new
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
|
||||
* OPTIONAL} or
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
|
||||
* REPEATED} properties to a type
|
||||
* <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
|
||||
* OPTIONAL} property into a
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
|
||||
* REPEATED} property.
|
||||
* <li>Addition of new types
|
||||
* <li>Addition of new {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
|
||||
* REPEATED} properties to a type
|
||||
* <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
|
||||
* property into a {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED}
|
||||
* property.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The following types of schema changes are not backwards-compatible:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Removal of an existing type
|
||||
* <li>Removal of a property from a type
|
||||
* <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
|
||||
* <li>For properties of {@code GenericDocument} type, changing the schema type of
|
||||
* {@code GenericDocument}s of that property
|
||||
* <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
|
||||
* OPTIONAL} property into a
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
|
||||
* REQUIRED} property).
|
||||
* <li>Adding a
|
||||
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
|
||||
* REQUIRED} property.
|
||||
* <li>Removal of an existing type
|
||||
* <li>Removal of a property from a type
|
||||
* <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
|
||||
* <li>For properties of {@code GenericDocument} type, changing the schema type of {@code
|
||||
* GenericDocument}s of that property
|
||||
* <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
|
||||
* property into a {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
|
||||
* property).
|
||||
* <li>Adding a {@link
|
||||
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
|
||||
* property.
|
||||
* </ul>
|
||||
* <p>Supplying a schema with such changes will result in this call returning an
|
||||
* {@link AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an
|
||||
* error message describing the incompatibility. In this case the previously set schema will
|
||||
* remain active.
|
||||
*
|
||||
* <p>Supplying a schema with such changes will result in this call returning an {@link
|
||||
* AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an error
|
||||
* message describing the incompatibility. In this case the previously set schema will remain
|
||||
* active.
|
||||
*
|
||||
* <p>If you need to make non-backwards-compatible changes as described above, instead use the
|
||||
* {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to
|
||||
@@ -214,8 +222,8 @@ public class AppSearchManager {
|
||||
*
|
||||
* @param request The schema update request.
|
||||
* @return the result of performing this operation.
|
||||
* @deprecated use {@link AppSearchSession#setSchema} instead.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#setSchema} instead.
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchResult<Void> setSchema(@NonNull SetSchemaRequest request) {
|
||||
@@ -229,6 +237,7 @@ public class AppSearchManager {
|
||||
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.setSchema(
|
||||
getPackageName(),
|
||||
DEFAULT_DATABASE_NAME,
|
||||
schemaBundles,
|
||||
new ArrayList<>(request.getSchemasNotVisibleToSystemUi()),
|
||||
@@ -249,21 +258,19 @@ public class AppSearchManager {
|
||||
/**
|
||||
* Index {@link GenericDocument}s into AppSearch.
|
||||
*
|
||||
* <p>You should not call this method directly; instead, use the
|
||||
* {@code AppSearch#putDocuments()} API provided by JetPack.
|
||||
* <p>You should not call this method directly; instead, use the {@code
|
||||
* AppSearch#putDocuments()} API provided by JetPack.
|
||||
*
|
||||
* <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
|
||||
* schema type previously registered via the {@link #setSchema} method.
|
||||
*
|
||||
* @param request {@link PutDocumentsRequest} containing documents to be indexed
|
||||
* @return The pending result of performing this operation. The keys of the returned
|
||||
* {@link AppSearchBatchResult} are the URIs of the input documents. The values are
|
||||
* {@code null} if they were successfully indexed, or a failed {@link AppSearchResult}
|
||||
* otherwise.
|
||||
* @return The pending result of performing this operation. The keys of the returned {@link
|
||||
* AppSearchBatchResult} are the URIs of the input documents. The values are {@code null} if
|
||||
* they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
*
|
||||
* @deprecated use {@link AppSearchSession#putDocuments} instead.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#putDocuments} instead.
|
||||
*/
|
||||
public AppSearchBatchResult<String, Void> putDocuments(@NonNull PutDocumentsRequest request) {
|
||||
// TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in
|
||||
@@ -275,7 +282,11 @@ public class AppSearchManager {
|
||||
}
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.putDocuments(DEFAULT_DATABASE_NAME, documentBundles, mContext.getUserId(),
|
||||
mService.putDocuments(
|
||||
getPackageName(),
|
||||
DEFAULT_DATABASE_NAME,
|
||||
documentBundles,
|
||||
mContext.getUserId(),
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
future.complete(result);
|
||||
@@ -294,19 +305,18 @@ public class AppSearchManager {
|
||||
/**
|
||||
* Retrieves {@link GenericDocument}s by URI.
|
||||
*
|
||||
* <p>You should not call this method directly; instead, use the
|
||||
* {@code AppSearch#getDocuments()} API provided by JetPack.
|
||||
* <p>You should not call this method directly; instead, use the {@code
|
||||
* AppSearch#getDocuments()} API provided by JetPack.
|
||||
*
|
||||
* @param request {@link GetByUriRequest} containing URIs to be retrieved.
|
||||
* @return The pending result of performing this operation. The keys of the returned
|
||||
* {@link AppSearchBatchResult} are the input URIs. The values are the returned
|
||||
* {@link GenericDocument}s on success, or a failed {@link AppSearchResult} otherwise.
|
||||
* URIs that are not found will return a failed {@link AppSearchResult} with a result code
|
||||
* of {@link AppSearchResult#RESULT_NOT_FOUND}.
|
||||
* @return The pending result of performing this operation. The keys of the returned {@link
|
||||
* AppSearchBatchResult} are the input URIs. The values are the returned {@link
|
||||
* GenericDocument}s on success, or a failed {@link AppSearchResult} otherwise. URIs that
|
||||
* are not found will return a failed {@link AppSearchResult} with a result code of {@link
|
||||
* AppSearchResult#RESULT_NOT_FOUND}.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
*
|
||||
* @deprecated use {@link AppSearchSession#getByUri} instead.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#getByUri} instead.
|
||||
*/
|
||||
public AppSearchBatchResult<String, GenericDocument> getByUri(
|
||||
@NonNull GetByUriRequest request) {
|
||||
@@ -315,7 +325,11 @@ public class AppSearchManager {
|
||||
List<String> uris = new ArrayList<>(request.getUris());
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.getDocuments(DEFAULT_DATABASE_NAME, request.getNamespace(), uris,
|
||||
mService.getDocuments(
|
||||
getPackageName(),
|
||||
DEFAULT_DATABASE_NAME,
|
||||
request.getNamespace(),
|
||||
uris,
|
||||
mContext.getUserId(),
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -371,43 +385,39 @@ public class AppSearchManager {
|
||||
* provided by JetPack.
|
||||
*
|
||||
* <p>Currently we support following features in the raw query format:
|
||||
*
|
||||
* <ul>
|
||||
* <li>AND
|
||||
* <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and
|
||||
* ‘cat’”).
|
||||
* Example: hello world matches documents that have both ‘hello’ and ‘world’
|
||||
* <li>OR
|
||||
* <p>OR joins (e.g. “match documents that have either the term ‘dog’ or
|
||||
* ‘cat’”).
|
||||
* Example: dog OR puppy
|
||||
* <li>Exclusion
|
||||
* <p>Exclude a term (e.g. “match documents that do
|
||||
* not have the term ‘dog’”).
|
||||
* Example: -dog excludes the term ‘dog’
|
||||
* <li>Grouping terms
|
||||
* <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
|
||||
* “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
|
||||
* Example: (dog puppy) (cat kitten) two one group containing two terms.
|
||||
* <li>Property restricts
|
||||
* <p> Specifies which properties of a document to specifically match terms in (e.g.
|
||||
* “match documents where the ‘subject’ property contains ‘important’”).
|
||||
* Example: subject:important matches documents with the term ‘important’ in the
|
||||
* ‘subject’ property
|
||||
* <li>Schema type restricts
|
||||
* <p>This is similar to property restricts, but allows for restricts on top-level document
|
||||
* fields, such as schema_type. Clients should be able to limit their query to documents of
|
||||
* a certain schema_type (e.g. “match documents that are of the ‘Email’ schema_type”).
|
||||
* Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will match documents
|
||||
* that contain the query term ‘dog’ and are of either the ‘Email’ schema type or the
|
||||
* ‘Video’ schema type.
|
||||
* <li>AND
|
||||
* <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and ‘cat’”).
|
||||
* Example: hello world matches documents that have both ‘hello’ and ‘world’
|
||||
* <li>OR
|
||||
* <p>OR joins (e.g. “match documents that have either the term ‘dog’ or ‘cat’”). Example:
|
||||
* dog OR puppy
|
||||
* <li>Exclusion
|
||||
* <p>Exclude a term (e.g. “match documents that do not have the term ‘dog’”). Example:
|
||||
* -dog excludes the term ‘dog’
|
||||
* <li>Grouping terms
|
||||
* <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
|
||||
* “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
|
||||
* Example: (dog puppy) (cat kitten) two one group containing two terms.
|
||||
* <li>Property restricts
|
||||
* <p>Specifies which properties of a document to specifically match terms in (e.g. “match
|
||||
* documents where the ‘subject’ property contains ‘important’”). Example:
|
||||
* subject:important matches documents with the term ‘important’ in the ‘subject’ property
|
||||
* <li>Schema type restricts
|
||||
* <p>This is similar to property restricts, but allows for restricts on top-level
|
||||
* document fields, such as schema_type. Clients should be able to limit their query to
|
||||
* documents of a certain schema_type (e.g. “match documents that are of the ‘Email’
|
||||
* schema_type”). Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will
|
||||
* match documents that contain the query term ‘dog’ and are of either the ‘Email’ schema
|
||||
* type or the ‘Video’ schema type.
|
||||
* </ul>
|
||||
*
|
||||
* @param queryExpression Query String to search.
|
||||
* @param searchSpec Spec for setting filters, raw query etc.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
*
|
||||
* @deprecated use AppSearchSession#query instead.
|
||||
* @hide
|
||||
* @deprecated use AppSearchSession#query instead.
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchResult<List<SearchResult>> query(
|
||||
@@ -416,7 +426,11 @@ public class AppSearchManager {
|
||||
// them in one big list.
|
||||
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.query(DEFAULT_DATABASE_NAME, queryExpression, searchSpec.getBundle(),
|
||||
mService.query(
|
||||
getPackageName(),
|
||||
DEFAULT_DATABASE_NAME,
|
||||
queryExpression,
|
||||
searchSpec.getBundle(),
|
||||
mContext.getUserId(),
|
||||
new IAppSearchResultCallback.Stub() {
|
||||
public void onResult(AppSearchResult result) {
|
||||
@@ -425,8 +439,8 @@ public class AppSearchManager {
|
||||
});
|
||||
AppSearchResult<Bundle> bundleResult = getFutureOrThrow(future);
|
||||
if (!bundleResult.isSuccess()) {
|
||||
return AppSearchResult.newFailedResult(bundleResult.getResultCode(),
|
||||
bundleResult.getErrorMessage());
|
||||
return AppSearchResult.newFailedResult(
|
||||
bundleResult.getResultCode(), bundleResult.getErrorMessage());
|
||||
}
|
||||
SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
|
||||
return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
|
||||
@@ -444,21 +458,23 @@ public class AppSearchManager {
|
||||
* provided by JetPack.
|
||||
*
|
||||
* @param request Request containing URIs to be removed.
|
||||
* @return The pending result of performing this operation. The keys of the returned
|
||||
* {@link AppSearchBatchResult} are the input URIs. The values are {@code null} on success,
|
||||
* or a failed {@link AppSearchResult} otherwise. URIs that are not found will return a
|
||||
* failed {@link AppSearchResult} with a result code of
|
||||
* {@link AppSearchResult#RESULT_NOT_FOUND}.
|
||||
* @return The pending result of performing this operation. The keys of the returned {@link
|
||||
* AppSearchBatchResult} are the input URIs. The values are {@code null} on success, or a
|
||||
* failed {@link AppSearchResult} otherwise. URIs that are not found will return a failed
|
||||
* {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
*
|
||||
* @deprecated use {@link AppSearchSession#removeByUri} instead.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#removeByUri} instead.
|
||||
*/
|
||||
public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) {
|
||||
List<String> uris = new ArrayList<>(request.getUris());
|
||||
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
|
||||
try {
|
||||
mService.removeByUri(DEFAULT_DATABASE_NAME, request.getNamespace(), uris,
|
||||
mService.removeByUri(
|
||||
getPackageName(),
|
||||
DEFAULT_DATABASE_NAME,
|
||||
request.getNamespace(),
|
||||
uris,
|
||||
mContext.getUserId(),
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -475,6 +491,12 @@ public class AppSearchManager {
|
||||
return getFutureOrThrow(future);
|
||||
}
|
||||
|
||||
/** Returns the package name that should be used for uid verification. */
|
||||
@NonNull
|
||||
private String getPackageName() {
|
||||
return mContext.getOpPackageName();
|
||||
}
|
||||
|
||||
private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
|
||||
try {
|
||||
return future.get();
|
||||
|
||||
@@ -45,6 +45,7 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public final class AppSearchSession implements Closeable {
|
||||
private static final String TAG = "AppSearchSession";
|
||||
private final String mPackageName;
|
||||
private final String mDatabaseName;
|
||||
@UserIdInt
|
||||
private final int mUserId;
|
||||
@@ -52,14 +53,20 @@ public final class AppSearchSession implements Closeable {
|
||||
private boolean mIsMutated = false;
|
||||
private boolean mIsClosed = false;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a search session for the client, defined by the {@code userId} and
|
||||
* {@code packageName}.
|
||||
*/
|
||||
static void createSearchSession(
|
||||
@NonNull AppSearchManager.SearchContext searchContext,
|
||||
@NonNull IAppSearchManager service,
|
||||
@UserIdInt int userId,
|
||||
@NonNull String packageName,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
|
||||
AppSearchSession searchSession =
|
||||
new AppSearchSession(service, userId, searchContext.mDatabaseName);
|
||||
new AppSearchSession(service, userId, packageName, searchContext.mDatabaseName);
|
||||
searchSession.initialize(executor, callback);
|
||||
}
|
||||
|
||||
@@ -87,10 +94,11 @@ public final class AppSearchSession implements Closeable {
|
||||
}
|
||||
|
||||
private AppSearchSession(@NonNull IAppSearchManager service, @UserIdInt int userId,
|
||||
@NonNull String databaseName) {
|
||||
mDatabaseName = databaseName;
|
||||
@NonNull String packageName, @NonNull String databaseName) {
|
||||
mService = service;
|
||||
mUserId = userId;
|
||||
mPackageName = packageName;
|
||||
mDatabaseName = databaseName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +152,7 @@ public final class AppSearchSession implements Closeable {
|
||||
* Visibility settings for a schema type do not apply or persist across
|
||||
* {@link SetSchemaRequest}s.
|
||||
*
|
||||
* @param request The schema update request.
|
||||
* @param request The schema update request.
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback Callback to receive errors resulting from setting the schema. If the
|
||||
* operation succeeds, the callback will be invoked with {@code null}.
|
||||
@@ -175,6 +183,7 @@ public final class AppSearchSession implements Closeable {
|
||||
}
|
||||
try {
|
||||
mService.setSchema(
|
||||
mPackageName,
|
||||
mDatabaseName,
|
||||
schemaBundles,
|
||||
new ArrayList<>(request.getSchemasNotVisibleToSystemUi()),
|
||||
@@ -206,6 +215,7 @@ public final class AppSearchSession implements Closeable {
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
try {
|
||||
mService.getSchema(
|
||||
mPackageName,
|
||||
mDatabaseName,
|
||||
mUserId,
|
||||
new IAppSearchResultCallback.Stub() {
|
||||
@@ -261,7 +271,7 @@ public final class AppSearchSession implements Closeable {
|
||||
documentBundles.add(documents.get(i).getBundle());
|
||||
}
|
||||
try {
|
||||
mService.putDocuments(mDatabaseName, documentBundles, mUserId,
|
||||
mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserId,
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
executor.execute(() -> callback.onResult(result));
|
||||
@@ -280,7 +290,7 @@ public final class AppSearchSession implements Closeable {
|
||||
/**
|
||||
* Retrieves {@link GenericDocument}s by URI.
|
||||
*
|
||||
* @param request {@link GetByUriRequest} containing URIs to be retrieved.
|
||||
* @param request {@link GetByUriRequest} containing URIs to be retrieved.
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback Callback to receive the pending result of performing this operation. The keys
|
||||
* of the returned {@link AppSearchBatchResult} are the input URIs. The values
|
||||
@@ -301,7 +311,7 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(callback);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
try {
|
||||
mService.getDocuments(mDatabaseName, request.getNamespace(),
|
||||
mService.getDocuments(mPackageName, mDatabaseName, request.getNamespace(),
|
||||
new ArrayList<>(request.getUris()), mUserId,
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -405,14 +415,14 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(searchSpec);
|
||||
Objects.requireNonNull(executor);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
return new SearchResults(mService, mDatabaseName, queryExpression, searchSpec, mUserId,
|
||||
executor);
|
||||
return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression,
|
||||
searchSpec, mUserId, executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes {@link GenericDocument}s from the index by URI.
|
||||
*
|
||||
* @param request Request containing URIs to be removed.
|
||||
* @param request Request containing URIs to be removed.
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback Callback to receive the pending result of performing this operation. The keys
|
||||
* of the returned {@link AppSearchBatchResult} are the input URIs. The values
|
||||
@@ -432,7 +442,7 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(callback);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
try {
|
||||
mService.removeByUri(mDatabaseName, request.getNamespace(),
|
||||
mService.removeByUri(mPackageName, mDatabaseName, request.getNamespace(),
|
||||
new ArrayList<>(request.getUris()), mUserId,
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -478,7 +488,8 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(callback);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
try {
|
||||
mService.removeByQuery(mDatabaseName, queryExpression, searchSpec.getBundle(), mUserId,
|
||||
mService.removeByQuery(mPackageName, mDatabaseName, queryExpression,
|
||||
searchSpec.getBundle(), mUserId,
|
||||
new IAppSearchResultCallback.Stub() {
|
||||
public void onResult(AppSearchResult result) {
|
||||
executor.execute(() -> callback.accept(result));
|
||||
|
||||
@@ -37,16 +37,25 @@ import java.util.function.Consumer;
|
||||
public class GlobalSearchSession implements Closeable {
|
||||
|
||||
private final IAppSearchManager mService;
|
||||
|
||||
@UserIdInt
|
||||
private final int mUserId;
|
||||
private boolean mIsClosed = false;
|
||||
|
||||
private final String mPackageName;
|
||||
|
||||
/**
|
||||
* Creates a search session for the client, defined by the {@code userId} and
|
||||
* {@code packageName}.
|
||||
*/
|
||||
static void createGlobalSearchSession(
|
||||
@NonNull IAppSearchManager service,
|
||||
@UserIdInt int userId,
|
||||
@NonNull String packageName,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
|
||||
GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userId);
|
||||
GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userId,
|
||||
packageName);
|
||||
globalSearchSession.initialize(executor, callback);
|
||||
}
|
||||
|
||||
@@ -73,9 +82,11 @@ public class GlobalSearchSession implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
private GlobalSearchSession(@NonNull IAppSearchManager service, @UserIdInt int userId) {
|
||||
private GlobalSearchSession(@NonNull IAppSearchManager service, @UserIdInt int userId,
|
||||
@NonNull String packageName) {
|
||||
mService = service;
|
||||
mUserId = userId;
|
||||
mPackageName = packageName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +142,7 @@ public class GlobalSearchSession implements Closeable {
|
||||
Objects.requireNonNull(searchSpec);
|
||||
Objects.requireNonNull(executor);
|
||||
Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
|
||||
return new SearchResults(mService, /*databaseName=*/null, queryExpression,
|
||||
return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression,
|
||||
searchSpec, mUserId, executor);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Updates the AppSearch schema for this database.
|
||||
*
|
||||
* @param packageName The name of the package that owns this schema.
|
||||
* @param databaseName The name of the database where this schema lives.
|
||||
* @param schemaBundles List of {@link AppSearchSchema} bundles.
|
||||
* @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
|
||||
@@ -43,6 +44,7 @@ interface IAppSearchManager {
|
||||
* {@link AppSearchResult}<{@link Void}>.
|
||||
*/
|
||||
void setSchema(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in List<Bundle> schemaBundles,
|
||||
in List<String> schemasNotPlatformSurfaceable,
|
||||
@@ -54,17 +56,23 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Retrieves the AppSearch schema for this database.
|
||||
*
|
||||
* @param packageName The name of the package that owns the schema.
|
||||
* @param databaseName The name of the database to retrieve.
|
||||
* @param userId Id of the calling user
|
||||
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an
|
||||
* {@link AppSearchResult}<{@link List}<{@link Bundle}>>, where the value are
|
||||
* AppSearchSchema bundle.
|
||||
*/
|
||||
void getSchema(in String databaseName, in int userId, in IAppSearchResultCallback callback);
|
||||
void getSchema(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in int userId,
|
||||
in IAppSearchResultCallback callback);
|
||||
|
||||
/**
|
||||
* Inserts documents into the index.
|
||||
*
|
||||
* @param packageName The name of the package that owns this document.
|
||||
* @param databaseName The name of the database where this document lives.
|
||||
* @param documentBundes List of GenericDocument bundles.
|
||||
* @param userId Id of the calling user
|
||||
@@ -76,6 +84,7 @@ interface IAppSearchManager {
|
||||
* where the keys are document URIs, and the values are {@code null}.
|
||||
*/
|
||||
void putDocuments(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in List<Bundle> documentBundles,
|
||||
in int userId,
|
||||
@@ -84,6 +93,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Retrieves documents from the index.
|
||||
*
|
||||
* @param packageName The name of the package that owns this document.
|
||||
* @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
|
||||
@@ -96,6 +106,7 @@ interface IAppSearchManager {
|
||||
* where the keys are document URIs, and the values are Document bundles.
|
||||
*/
|
||||
void getDocuments(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in String namespace,
|
||||
in List<String> uris,
|
||||
@@ -105,6 +116,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Searches a document based on a given specifications.
|
||||
*
|
||||
* @param packageName The name of the package to query over.
|
||||
* @param databaseName The databaseName this query for.
|
||||
* @param queryExpression String to search for
|
||||
* @param searchSpecBundle SearchSpec bundle
|
||||
@@ -113,6 +125,7 @@ interface IAppSearchManager {
|
||||
* operation.
|
||||
*/
|
||||
void query(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in String queryExpression,
|
||||
in Bundle searchSpecBundle,
|
||||
@@ -123,6 +136,7 @@ interface IAppSearchManager {
|
||||
* Executes a global query, i.e. over all permitted databases, against the AppSearch index and
|
||||
* returns results.
|
||||
*
|
||||
* @param packageName The name of the package making the query.
|
||||
* @param queryExpression String to search for
|
||||
* @param searchSpecBundle SearchSpec bundle
|
||||
* @param userId Id of the calling user
|
||||
@@ -130,6 +144,7 @@ interface IAppSearchManager {
|
||||
* operation.
|
||||
*/
|
||||
void globalQuery(
|
||||
in String packageName,
|
||||
in String queryExpression,
|
||||
in Bundle searchSpecBundle,
|
||||
in int userId,
|
||||
@@ -158,6 +173,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Removes documents by URI.
|
||||
*
|
||||
* @param packageName The name of the package the document is in.
|
||||
* @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
|
||||
@@ -171,6 +187,7 @@ interface IAppSearchManager {
|
||||
* failure where the {@code throwable} is {@code null}.
|
||||
*/
|
||||
void removeByUri(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in String namespace,
|
||||
in List<String> uris,
|
||||
@@ -180,6 +197,7 @@ interface IAppSearchManager {
|
||||
/**
|
||||
* Removes documents by given query.
|
||||
*
|
||||
* @param packageName The name of the package to query over.
|
||||
* @param databaseName The databaseName this query for.
|
||||
* @param queryExpression String to search for
|
||||
* @param searchSpecBundle SearchSpec bundle
|
||||
@@ -188,6 +206,7 @@ interface IAppSearchManager {
|
||||
* {@link AppSearchResult}<{@link Void}>.
|
||||
*/
|
||||
void removeByQuery(
|
||||
in String packageName,
|
||||
in String databaseName,
|
||||
in String queryExpression,
|
||||
in Bundle searchSpecBundle,
|
||||
|
||||
@@ -47,6 +47,9 @@ public class SearchResults implements Closeable {
|
||||
|
||||
private final IAppSearchManager mService;
|
||||
|
||||
// The package name of the caller.
|
||||
private final String mPackageName;
|
||||
|
||||
// The database name to search over. If null, this will search over all database names.
|
||||
@Nullable
|
||||
private final String mDatabaseName;
|
||||
@@ -68,12 +71,14 @@ public class SearchResults implements Closeable {
|
||||
|
||||
SearchResults(
|
||||
@NonNull IAppSearchManager service,
|
||||
@NonNull String packageName,
|
||||
@Nullable String databaseName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@UserIdInt int userId,
|
||||
@NonNull @CallbackExecutor Executor executor) {
|
||||
mService = Objects.requireNonNull(service);
|
||||
mPackageName = packageName;
|
||||
mDatabaseName = databaseName;
|
||||
mQueryExpression = Objects.requireNonNull(queryExpression);
|
||||
mSearchSpec = Objects.requireNonNull(searchSpec);
|
||||
@@ -98,13 +103,12 @@ public class SearchResults implements Closeable {
|
||||
mIsFirstLoad = false;
|
||||
if (mDatabaseName == null) {
|
||||
// Global query, there's no one package-database combination to check.
|
||||
mService.globalQuery(mQueryExpression, mSearchSpec.getBundle(), mUserId,
|
||||
wrapCallback(callback));
|
||||
mService.globalQuery(mPackageName, mQueryExpression,
|
||||
mSearchSpec.getBundle(), mUserId, wrapCallback(callback));
|
||||
} else {
|
||||
// Normal local query, pass in specified database.
|
||||
mService.query(
|
||||
mDatabaseName, mQueryExpression, mSearchSpec.getBundle(), mUserId,
|
||||
wrapCallback(callback));
|
||||
mService.query(mPackageName, mDatabaseName, mQueryExpression,
|
||||
mSearchSpec.getBundle(), mUserId, wrapCallback(callback));
|
||||
}
|
||||
} else {
|
||||
mService.getNextPage(mNextPageToken, mUserId, wrapCallback(callback));
|
||||
|
||||
@@ -31,14 +31,17 @@ import android.app.appsearch.PackageIdentifier;
|
||||
import android.app.appsearch.SearchResultPage;
|
||||
import android.app.appsearch.SearchSpec;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelableException;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||
|
||||
@@ -46,11 +49,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TODO(b/142567528): add comments when implement this class
|
||||
*/
|
||||
/** TODO(b/142567528): add comments when implement this class */
|
||||
public class AppSearchManagerService extends SystemService {
|
||||
private static final String TAG = "AppSearchManagerService";
|
||||
private PackageManagerInternal mPackageManagerInternal;
|
||||
|
||||
public AppSearchManagerService(Context context) {
|
||||
super(context);
|
||||
@@ -59,11 +61,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
@Override
|
||||
public void onStart() {
|
||||
publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
|
||||
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
|
||||
}
|
||||
|
||||
private class Stub extends IAppSearchManager.Stub {
|
||||
@Override
|
||||
public void setSchema(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull List<Bundle> schemaBundles,
|
||||
@NonNull List<String> schemasNotPlatformSurfaceable,
|
||||
@@ -71,6 +75,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
boolean forceOverride,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(schemaBundles);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -78,6 +83,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
|
||||
for (int i = 0; i < schemaBundles.size(); i++) {
|
||||
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
|
||||
@@ -94,7 +100,6 @@ public class AppSearchManagerService extends SystemService {
|
||||
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
|
||||
}
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
impl.setSchema(
|
||||
packageName,
|
||||
databaseName,
|
||||
@@ -102,8 +107,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
schemasNotPlatformSurfaceable,
|
||||
schemasPackageAccessible,
|
||||
forceOverride);
|
||||
invokeCallbackOnResult(callback,
|
||||
AppSearchResult.newSuccessfulResult(/*result=*/ null));
|
||||
invokeCallbackOnResult(
|
||||
callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
|
||||
} catch (Throwable t) {
|
||||
invokeCallbackOnError(callback, t);
|
||||
} finally {
|
||||
@@ -113,24 +118,26 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void getSchema(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(callback);
|
||||
int callingUid = Binder.getCallingUidOrThrow();
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
List<AppSearchSchema> schemas = impl.getSchema(packageName, databaseName);
|
||||
List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
|
||||
for (int i = 0; i < schemas.size(); i++) {
|
||||
schemaBundles.add(schemas.get(i).getBundle());
|
||||
}
|
||||
invokeCallbackOnResult(callback,
|
||||
AppSearchResult.newSuccessfulResult(schemaBundles));
|
||||
invokeCallbackOnResult(
|
||||
callback, AppSearchResult.newSuccessfulResult(schemaBundles));
|
||||
} catch (Throwable t) {
|
||||
invokeCallbackOnError(callback, t);
|
||||
} finally {
|
||||
@@ -140,10 +147,12 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void putDocuments(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull List<Bundle> documentBundles,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchBatchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(documentBundles);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -151,10 +160,10 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
for (int i = 0; i < documentBundles.size(); i++) {
|
||||
GenericDocument document = new GenericDocument(documentBundles.get(i));
|
||||
try {
|
||||
@@ -176,11 +185,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void getDocuments(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String namespace,
|
||||
@NonNull List<String> uris,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchBatchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(namespace);
|
||||
Preconditions.checkNotNull(uris);
|
||||
@@ -189,15 +200,15 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
for (int i = 0; i < uris.size(); i++) {
|
||||
String uri = uris.get(i);
|
||||
try {
|
||||
GenericDocument document = impl.getDocument(packageName, databaseName,
|
||||
namespace, uri);
|
||||
GenericDocument document =
|
||||
impl.getDocument(packageName, databaseName, namespace, uri);
|
||||
resultBuilder.setSuccess(uri, document.getBundle());
|
||||
} catch (Throwable t) {
|
||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||
@@ -214,11 +225,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
// TODO(sidchhabra): Do this in a threadpool.
|
||||
@Override
|
||||
public void query(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull Bundle searchSpecBundle,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(queryExpression);
|
||||
Preconditions.checkNotNull(searchSpecBundle);
|
||||
@@ -227,14 +240,16 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
SearchResultPage searchResultPage = impl.query(
|
||||
packageName,
|
||||
databaseName,
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
invokeCallbackOnResult(callback,
|
||||
SearchResultPage searchResultPage =
|
||||
impl.query(
|
||||
packageName,
|
||||
databaseName,
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
invokeCallbackOnResult(
|
||||
callback,
|
||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||
} catch (Throwable t) {
|
||||
invokeCallbackOnError(callback, t);
|
||||
@@ -245,10 +260,12 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void globalQuery(
|
||||
@NonNull String packageName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull Bundle searchSpecBundle,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(queryExpression);
|
||||
Preconditions.checkNotNull(searchSpecBundle);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -256,11 +273,12 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
SearchResultPage searchResultPage = impl.globalQuery(
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
invokeCallbackOnResult(callback,
|
||||
SearchResultPage searchResultPage =
|
||||
impl.globalQuery(queryExpression, new SearchSpec(searchSpecBundle));
|
||||
invokeCallbackOnResult(
|
||||
callback,
|
||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||
} catch (Throwable t) {
|
||||
invokeCallbackOnError(callback, t);
|
||||
@@ -270,7 +288,9 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNextPage(long nextPageToken, @UserIdInt int userId,
|
||||
public void getNextPage(
|
||||
long nextPageToken,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(callback);
|
||||
int callingUid = Binder.getCallingUid();
|
||||
@@ -281,7 +301,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
try {
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
|
||||
invokeCallbackOnResult(callback,
|
||||
invokeCallbackOnResult(
|
||||
callback,
|
||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||
} catch (Throwable t) {
|
||||
invokeCallbackOnError(callback, t);
|
||||
@@ -307,11 +328,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void removeByUri(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String namespace,
|
||||
@NonNull List<String> uris,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchBatchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(uris);
|
||||
Preconditions.checkNotNull(callback);
|
||||
@@ -319,15 +342,15 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||
new AppSearchBatchResult.Builder<>();
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
for (int i = 0; i < uris.size(); i++) {
|
||||
String uri = uris.get(i);
|
||||
try {
|
||||
impl.remove(packageName, databaseName, namespace, uri);
|
||||
resultBuilder.setSuccess(uri, /*result= */null);
|
||||
resultBuilder.setSuccess(uri, /*result= */ null);
|
||||
} catch (Throwable t) {
|
||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||
}
|
||||
@@ -342,11 +365,13 @@ public class AppSearchManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void removeByQuery(
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull Bundle searchSpecBundle,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(queryExpression);
|
||||
Preconditions.checkNotNull(searchSpecBundle);
|
||||
@@ -355,9 +380,12 @@ public class AppSearchManagerService extends SystemService {
|
||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
verifyCallingPackage(callingUid, packageName);
|
||||
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
|
||||
String packageName = convertUidToPackageName(callingUid);
|
||||
impl.removeByQuery(packageName, databaseName, queryExpression,
|
||||
impl.removeByQuery(
|
||||
packageName,
|
||||
databaseName,
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
||||
} catch (Throwable t) {
|
||||
@@ -398,28 +426,22 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a package 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 convertUidToPackageName(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);
|
||||
if (callingUidName == null) {
|
||||
// Not sure how this is possible --- maybe app was uninstalled?
|
||||
throw new IllegalStateException(
|
||||
"Failed to look up package name for uid " + callingUid);
|
||||
private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
|
||||
Preconditions.checkNotNull(callingPackage);
|
||||
if (mPackageManagerInternal.getPackageUid(
|
||||
callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
|
||||
!= callingUid) {
|
||||
throw new SecurityException(
|
||||
"Specified calling package ["
|
||||
+ callingPackage
|
||||
+ "] does not match the calling uid "
|
||||
+ callingUid);
|
||||
}
|
||||
return callingUidName;
|
||||
}
|
||||
|
||||
/** Invokes the {@link IAppSearchResultCallback} with the result. */
|
||||
private void invokeCallbackOnResult(IAppSearchResultCallback callback,
|
||||
AppSearchResult<?> result) {
|
||||
private void invokeCallbackOnResult(
|
||||
IAppSearchResultCallback callback, AppSearchResult<?> result) {
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -428,8 +450,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
|
||||
/** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
|
||||
private void invokeCallbackOnResult(IAppSearchBatchResultCallback callback,
|
||||
AppSearchBatchResult<?, ?> result) {
|
||||
private void invokeCallbackOnResult(
|
||||
IAppSearchBatchResultCallback callback, AppSearchBatchResult<?, ?> result) {
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -455,8 +477,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
*
|
||||
* <p>The throwable is converted to {@link ParcelableException}.
|
||||
*/
|
||||
private void invokeCallbackOnError(IAppSearchBatchResultCallback callback,
|
||||
Throwable throwable) {
|
||||
private void invokeCallbackOnError(
|
||||
IAppSearchBatchResultCallback callback, Throwable throwable) {
|
||||
try {
|
||||
callback.onSystemError(new ParcelableException(throwable));
|
||||
} catch (RemoteException e) {
|
||||
@@ -465,13 +487,18 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO(b/173553485) verifying that the caller has permission to access target user's data
|
||||
//TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
|
||||
//TODO(b/173553485) Implement SystemService.onUserStopping()
|
||||
// TODO(b/173553485) verifying that the caller has permission to access target user's data
|
||||
// TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
|
||||
// TODO(b/173553485) Implement SystemService.onUserStopping()
|
||||
private static int handleIncomingUser(@UserIdInt int userId, int callingUid) {
|
||||
int callingPid = Binder.getCallingPid();
|
||||
return ActivityManager.handleIncomingUser(callingPid, callingUid, userId,
|
||||
/*allowAll=*/ false, /*requireFull=*/ false,
|
||||
/*name=*/ null, /*callerPackage=*/ null);
|
||||
return ActivityManager.handleIncomingUser(
|
||||
callingPid,
|
||||
callingUid,
|
||||
userId,
|
||||
/*allowAll=*/ false,
|
||||
/*requireFull=*/ false,
|
||||
/*name=*/ null,
|
||||
/*callerPackage=*/ null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user