Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07851bd3 authored by Utkarsh Nigam's avatar Utkarsh Nigam
Browse files

Make SyncAppSearchCallHelper asynchronous.

Change-Id: I37a09881598c57c149653c34ae64d623f8030196
Test: Not needed; simple refactoring
Bug: 357551503
Flag: android.app.appfunctions.flags.enable_app_function_manager
parent 67f04bee
Loading
Loading
Loading
Loading
+66 −50
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * Helper class for interacting with a system server local appsearch session synchronously.
 * Helper class for interacting with a system server local appsearch session asynchronously.
 *
 * <p>Converts the AppSearch Callback API to {@link AndroidFuture}.
 */
@FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
public class SyncAppSearchCallHelper implements Closeable {
@@ -47,7 +49,8 @@ public class SyncAppSearchCallHelper implements Closeable {
    private final AppSearchManager mAppSearchManager;
    private final AndroidFuture<AppSearchResult<AppSearchSession>> mSettableSessionFuture;

    public SyncAppSearchCallHelper(@NonNull AppSearchManager appSearchManager,
    public SyncAppSearchCallHelper(
            @NonNull AppSearchManager appSearchManager,
            @NonNull Executor executor,
            @NonNull SearchContext appSearchContext) {
        Objects.requireNonNull(appSearchManager);
@@ -61,68 +64,81 @@ public class SyncAppSearchCallHelper implements Closeable {
                appSearchContext, mExecutor, mSettableSessionFuture::complete);
    }

    /**
     * Converts a failed app search result codes into an exception.
     */
    /** Converts a failed app search result codes into an exception. */
    @NonNull
    private static Exception failedResultToException(@NonNull AppSearchResult appSearchResult) {
        return switch (appSearchResult.getResultCode()) {
            case AppSearchResult.RESULT_INVALID_ARGUMENT -> new IllegalArgumentException(
                    appSearchResult.getErrorMessage());
            case AppSearchResult.RESULT_IO_ERROR -> new IOException(
                    appSearchResult.getErrorMessage());
            case AppSearchResult.RESULT_SECURITY_ERROR -> new SecurityException(
                    appSearchResult.getErrorMessage());
            case AppSearchResult.RESULT_INVALID_ARGUMENT ->
                    new IllegalArgumentException(appSearchResult.getErrorMessage());
            case AppSearchResult.RESULT_IO_ERROR ->
                    new IOException(appSearchResult.getErrorMessage());
            case AppSearchResult.RESULT_SECURITY_ERROR ->
                    new SecurityException(appSearchResult.getErrorMessage());
            default -> new IllegalStateException(appSearchResult.getErrorMessage());
        };
    }

    private AppSearchSession getSession() throws Exception {
        AppSearchResult<AppSearchSession> sessionResult = mSettableSessionFuture.get();
        if (!sessionResult.isSuccess()) {
            throw failedResultToException(sessionResult);
    private AndroidFuture<AppSearchSession> getSessionAsync() {
        return mSettableSessionFuture.thenApply(
                result -> {
                    if (result.isSuccess()) {
                        return result.getResultValue();
                    } else {
                        throw new RuntimeException(failedResultToException(result));
                    }
        return sessionResult.getResultValue();
                });
    }

    /**
     * Gets the schema for a given app search session.
     */
    @WorkerThread
    public GetSchemaResponse getSchema() throws Exception {
        AndroidFuture<AppSearchResult<GetSchemaResponse>> settableSchemaResponse =
                new AndroidFuture<>();
        getSession().getSchema(mExecutor, settableSchemaResponse::complete);
        AppSearchResult<GetSchemaResponse> schemaResponse = settableSchemaResponse.get();
        if (schemaResponse.isSuccess()) {
            return schemaResponse.getResultValue();
    /** Gets the schema for a given app search session. */
    public AndroidFuture<GetSchemaResponse> getSchema() {
        return getSessionAsync()
                .thenComposeAsync(
                        session -> {
                            AndroidFuture<AppSearchResult<GetSchemaResponse>>
                                    settableSchemaResponse = new AndroidFuture<>();
                            session.getSchema(mExecutor, settableSchemaResponse::complete);
                            return settableSchemaResponse.thenApply(
                                    result -> {
                                        if (result.isSuccess()) {
                                            return result.getResultValue();
                                        } else {
            throw failedResultToException(schemaResponse);
                                            throw new RuntimeException(
                                                    failedResultToException(result));
                                        }
                                    });
                        },
                        mExecutor);
    }

    /**
     * Sets the schema for a given app search session.
     */
    @WorkerThread
    public SetSchemaResponse setSchema(
            @NonNull SetSchemaRequest setSchemaRequest) throws Exception {
        AndroidFuture<AppSearchResult<SetSchemaResponse>> settableSchemaResponse =
                new AndroidFuture<>();
        getSession().setSchema(
                setSchemaRequest, mExecutor, mExecutor, settableSchemaResponse::complete);
        AppSearchResult<SetSchemaResponse> schemaResponse = settableSchemaResponse.get();
        if (schemaResponse.isSuccess()) {
            return schemaResponse.getResultValue();
    /** Sets the schema for a given app search session. */
    public AndroidFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest setSchemaRequest) {
        return getSessionAsync()
                .thenComposeAsync(
                        session -> {
                            AndroidFuture<AppSearchResult<SetSchemaResponse>>
                                    settableSchemaResponse = new AndroidFuture<>();
                            session.setSchema(
                                    setSchemaRequest,
                                    mExecutor,
                                    mExecutor,
                                    settableSchemaResponse::complete);
                            return settableSchemaResponse.thenApply(
                                    result -> {
                                        if (result.isSuccess()) {
                                            return result.getResultValue();
                                        } else {
            throw failedResultToException(schemaResponse);
                                            throw new RuntimeException(
                                                    failedResultToException(result));
                                        }
                                    });
                        },
                        mExecutor);
    }

    @Override
    public void close() throws IOException {
        try {
            getSession().close();
            getSessionAsync().get().close();
        } catch (Exception ex) {
            Slog.e(TAG, "Failed to close app search session", ex);
        }