script-astra/Android/Sdk/sources/android-35/android/app/appsearch/AppSearchManager.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

290 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.appsearch;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.annotation.UserHandleAware;
import android.app.appsearch.aidl.AppSearchAttributionSource;
import android.app.appsearch.aidl.IAppSearchManager;
import android.app.appsearch.flags.Flags;
import android.app.appsearch.functions.AppFunctionManager;
import android.content.Context;
import android.os.Process;
import com.android.internal.util.Preconditions;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* Provides access to the centralized AppSearch index maintained by the system.
*
* <p>AppSearch is an offline, on-device search library for managing structured data featuring:
*
* <ul>
* <li>APIs to index and retrieve data via full-text search.
* <li>An API for applications to explicitly grant read-access permission of their data to other
* applications. <b>See: {@link
* SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage}</b>
* <li>An API for applications to opt into or out of having their data displayed on System UI
* surfaces by the System-designated global querier. <b>See: {@link
* SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem}</b>
* </ul>
*
* <p>Applications create a database by opening an {@link AppSearchSession}.
*
* <p>Example:
*
* <pre>
* AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
*
* AppSearchManager.SearchContext searchContext = new AppSearchManager.SearchContext.Builder().
* setDatabaseName(dbName).build());
* appSearchManager.createSearchSession(searchContext, mExecutor, appSearchSessionResult -&gt; {
* mAppSearchSession = appSearchSessionResult.getResultValue();
* });</pre>
*
* <p>After opening the session, a schema must be set in order to define the organizational
* structure of data. The schema is set by calling {@link AppSearchSession#setSchema}. The schema is
* composed of a collection of {@link AppSearchSchema} objects, each of which defines a unique type
* of data.
*
* <p>Example:
*
* <pre>
* AppSearchSchema emailSchemaType = new AppSearchSchema.Builder("Email")
* .addProperty(new StringPropertyConfig.Builder("subject")
* .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
* .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
* .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
* .build()
* ).build();
*
* SetSchemaRequest request = new SetSchemaRequest.Builder().addSchema(emailSchemaType).build();
* mAppSearchSession.set(request, mExecutor, appSearchResult -&gt; {
* if (appSearchResult.isSuccess()) {
* //Schema has been successfully set.
* }
* });</pre>
*
* <p>The basic unit of data in AppSearch is represented as a {@link GenericDocument} object,
* containing an ID, namespace, time-to-live, score, and properties. A namespace organizes a logical
* group of documents. For example, a namespace can be created to group documents on a per-account
* basis. An ID identifies a single document within a namespace. The combination of namespace and ID
* uniquely identifies a {@link GenericDocument} in the database.
*
* <p>Once the schema has been set, {@link GenericDocument} objects can be put into the database and
* indexed by calling {@link AppSearchSession#put}.
*
* <p>Example:
*
* <pre>
* // Although for this example we use GenericDocument directly, we recommend extending
* // GenericDocument to create specific types (i.e. Email) with specific setters/getters.
* GenericDocument email = new GenericDocument.Builder<>(NAMESPACE, ID, EMAIL_SCHEMA_TYPE)
* .setPropertyString(“subject”, EMAIL_SUBJECT)
* .setScore(EMAIL_SCORE)
* .build();
*
* PutDocumentsRequest request = new PutDocumentsRequest.Builder().addGenericDocuments(email)
* .build();
* mAppSearchSession.put(request, mExecutor, appSearchBatchResult -&gt; {
* if (appSearchBatchResult.isSuccess()) {
* //All documents have been successfully indexed.
* }
* });</pre>
*
* <p>Searching within the database is done by calling {@link AppSearchSession#search} and providing
* the query string to search for, as well as a {@link SearchSpec}.
*
* <p>Alternatively, {@link AppSearchSession#getByDocumentId} can be called to retrieve documents by
* namespace and ID.
*
* <p>Document removal is done either by time-to-live expiration, or explicitly calling a remove
* operation. Remove operations can be done by namespace and ID via {@link
* AppSearchSession#remove(RemoveByDocumentIdRequest, Executor, BatchResultCallback)}, or by query
* via {@link AppSearchSession#remove(String, SearchSpec, Executor, Consumer)}.
*/
@SystemService(Context.APP_SEARCH_SERVICE)
public class AppSearchManager {
private final IAppSearchManager mService;
private final Context mContext;
private final AppFunctionManager mAppFunctionManager;
/** @hide */
public AppSearchManager(@NonNull Context context, @NonNull IAppSearchManager service) {
mContext = Objects.requireNonNull(context);
mService = Objects.requireNonNull(service);
mAppFunctionManager = new AppFunctionManager(context, service);
}
/** Contains information about how to create the search session. */
public static final class SearchContext {
final String mDatabaseName;
SearchContext(@NonNull String databaseName) {
mDatabaseName = Objects.requireNonNull(databaseName);
}
/**
* Returns the name of the database to create or open.
*
* <p>Databases with different names are fully separate with distinct types, namespaces, and
* data.
*/
@NonNull
public String getDatabaseName() {
return mDatabaseName;
}
/** Builder for {@link SearchContext} objects. */
public static final class Builder {
private final String mDatabaseName;
private boolean mBuilt = false;
/**
* Creates a new {@link SearchContext.Builder}.
*
* <p>{@link AppSearchSession} will create or open a database under the given name.
*
* <p>Databases with different names are fully separate with distinct types, namespaces,
* and data.
*
* <p>Database name cannot contain {@code '/'}.
*
* @param databaseName The name of the database.
* @throws IllegalArgumentException if the databaseName contains {@code '/'}.
*/
public Builder(@NonNull String databaseName) {
Objects.requireNonNull(databaseName);
Preconditions.checkArgument(
!databaseName.contains("/"), "Database name cannot contain '/'");
mDatabaseName = databaseName;
}
/** Builds a {@link SearchContext} instance. */
@NonNull
public SearchContext build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBuilt = true;
return new SearchContext(mDatabaseName);
}
}
}
/**
* Creates a new {@link AppSearchSession}.
*
* <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 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}&lt;{@link AppSearchSession}&gt; of performing
* this operation. Or a {@link AppSearchResult} with failure reason code and error
* information.
*/
@UserHandleAware
public void createSearchSession(
@NonNull SearchContext searchContext,
@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
Objects.requireNonNull(searchContext);
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
AppSearchSession.createSearchSession(
searchContext,
mService,
mContext.getUser(),
AppSearchAttributionSource.createAttributionSource(
mContext, /* callingPid= */ Process.myPid()),
AppSearchEnvironmentFactory.getEnvironmentInstance().getCacheDir(mContext),
executor,
callback);
}
/**
* Creates a new {@link GlobalSearchSession}.
*
* <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}&lt;{@link GlobalSearchSession}&gt; of performing
* this operation. Or a {@link AppSearchResult} with failure reason code and error
* information.
*/
@UserHandleAware
public void createGlobalSearchSession(
@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
GlobalSearchSession.createGlobalSearchSession(
mService,
mContext.getUser(),
AppSearchAttributionSource.createAttributionSource(
mContext, /* callingPid= */ Process.myPid()),
executor,
callback);
}
/**
* Creates a new {@link EnterpriseGlobalSearchSession}
*
* <p>EnterpriseGlobalSearchSession queries data from the users work profile, allowing apps
* running on the personal profile to access a limited subset of work profile data. Enterprise
* access must be explicitly enabled on schemas, and schemas may also specify additional
* permissions required for enterprise access.
*
* <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}&lt;{@link EnterpriseGlobalSearchSession}&gt; of
* performing this operation. Or a {@link AppSearchResult} with failure reason code and
* error information.
*/
@FlaggedApi(Flags.FLAG_ENABLE_ENTERPRISE_GLOBAL_SEARCH_SESSION)
@UserHandleAware
public void createEnterpriseGlobalSearchSession(
@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<EnterpriseGlobalSearchSession>> callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
EnterpriseGlobalSearchSession.createEnterpriseGlobalSearchSession(
mService,
mContext.getUser(),
AppSearchAttributionSource.createAttributionSource(
mContext, /* callingPid= */ Process.myPid()),
executor,
callback);
}
/** Returns an instance of {@link android.app.appsearch.functions.AppFunctionManager}. */
@FlaggedApi(Flags.FLAG_ENABLE_APP_FUNCTIONS)
@NonNull
public AppFunctionManager getAppFunctionManager() {
return mAppFunctionManager;
}
}