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

Commit a7b4121e authored by Terry Wang's avatar Terry Wang Committed by Android (Google) Code Review
Browse files

Merge "Update Framework from Jetpack."

parents 4a34d3ba 4aba0d84
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import android.os.Bundle;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.util.ArrayList;
import java.util.List;
@@ -39,10 +42,13 @@ import java.util.function.Consumer;
 * This class is thread safe.
 */
public final class AppSearchSession {
    private static final String TAG = "AppSearchSession";
    private final String mDatabaseName;
    @UserIdInt
    private final int mUserId;
    private final IAppSearchManager mService;
    private boolean mIsMutated = false;
    private boolean mIsClosed = false;

    static void createSearchSession(
            @NonNull AppSearchManager.SearchContext searchContext,
@@ -150,6 +156,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(request);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
        for (AppSearchSchema schema : request.getSchemas()) {
            schemaBundles.add(schema.getBundle());
@@ -166,6 +173,7 @@ public final class AppSearchSession {
                            executor.execute(() -> callback.accept(result));
                        }
                    });
            mIsMutated = true;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -182,6 +190,7 @@ public final class AppSearchSession {
            @NonNull Consumer<AppSearchResult<Set<AppSearchSchema>>> callback) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        try {
            mService.getSchema(
                    mDatabaseName,
@@ -232,6 +241,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(request);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        List<GenericDocument> documents = request.getDocuments();
        List<Bundle> documentBundles = new ArrayList<>(documents.size());
        for (int i = 0; i < documents.size(); i++) {
@@ -248,6 +258,7 @@ public final class AppSearchSession {
                            executor.execute(() -> callback.onSystemError(exception.getCause()));
                        }
                    });
            mIsMutated = true;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -275,6 +286,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(request);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        try {
            mService.getDocuments(mDatabaseName, request.getNamespace(),
                    new ArrayList<>(request.getUris()), mUserId,
@@ -379,6 +391,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(queryExpression);
        Objects.requireNonNull(searchSpec);
        Objects.requireNonNull(executor);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        return new SearchResults(mService, mDatabaseName, queryExpression, searchSpec, mUserId,
                executor);
    }
@@ -404,6 +417,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(request);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        try {
            mService.removeByUri(mDatabaseName, request.getNamespace(),
                    new ArrayList<>(request.getUris()), mUserId,
@@ -416,6 +430,7 @@ public final class AppSearchSession {
                            executor.execute(() -> callback.onSystemError(exception.getCause()));
                        }
                    });
            mIsMutated = true;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -448,6 +463,7 @@ public final class AppSearchSession {
        Objects.requireNonNull(searchSpec);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
        try {
            mService.removeByQuery(mDatabaseName, queryExpression, searchSpec.getBundle(), mUserId,
                    new IAppSearchResultCallback.Stub() {
@@ -455,8 +471,26 @@ public final class AppSearchSession {
                            executor.execute(() -> callback.accept(result));
                        }
                    });
            mIsMutated = true;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Closes the SearchSessionImpl to persists all update/delete requests to the disk.
     *
     * @hide
     */
    // TODO(b/175637134) when unhide it, implement Closeable and remove this method.
    public void close() {
        if (mIsMutated && !mIsClosed) {
            try {
                mService.persistToDisk(mUserId);
                mIsClosed = true;
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to close the AppSearchSession", e);
            }
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -192,6 +192,13 @@ interface IAppSearchManager {
        in int userId,
        in IAppSearchResultCallback callback);

    /**
     * Persists all update/delete requests to the disk.
     *
     * @param userId Id of the calling user
     */
    void persistToDisk(in int userId);

    /**
     * Creates and initializes AppSearchImpl for the calling app.
     *
+12 −4
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.io.Closeable;
import java.util.List;
import java.util.Objects;
@@ -62,6 +64,8 @@ public class SearchResults implements Closeable {

    private boolean mIsFirstLoad = true;

    private boolean mIsClosed = false;

    SearchResults(
            @NonNull IAppSearchManager service,
            @Nullable String databaseName,
@@ -88,6 +92,7 @@ public class SearchResults implements Closeable {
     * @param callback Callback to receive the pending result of performing this operation.
     */
    public void getNextPage(@NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
        Preconditions.checkState(!mIsClosed, "SearchResults has already been closed");
        try {
            if (mIsFirstLoad) {
                mIsFirstLoad = false;
@@ -111,10 +116,13 @@ public class SearchResults implements Closeable {

    @Override
    public void close() {
        if (!mIsClosed) {
            try {
                mService.invalidateNextPageToken(mNextPageToken, mUserId);
                mIsClosed = true;
            } catch (RemoteException e) {
            Log.d(TAG, "Unable to close the SearchResults", e);
                Log.e(TAG, "Unable to close the SearchResults", e);
            }
        }
    }

+20 −5
Original line number Diff line number Diff line
@@ -279,7 +279,7 @@ public class AppSearchManagerService extends SystemService {
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                impl.invalidateNextPageToken(nextPageToken);
            } catch (Throwable t) {
                Log.d(TAG, "Unable to invalidate the query page token", t);
                Log.e(TAG, "Unable to invalidate the query page token", t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
@@ -347,6 +347,21 @@ public class AppSearchManagerService extends SystemService {
            }
        }

        @Override
        public void persistToDisk(@UserIdInt int userId) {
            int callingUid = Binder.getCallingUidOrThrow();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                impl.persistToDisk();
            } catch (Throwable t) {
                Log.e(TAG, "Unable to persist the data to disk", t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
        }

        @Override
        public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
            Preconditions.checkNotNull(callback);
@@ -388,7 +403,7 @@ public class AppSearchManagerService extends SystemService {
            try {
                callback.onResult(result);
            } catch (RemoteException e) {
                Log.d(TAG, "Unable to send result to the callback", e);
                Log.e(TAG, "Unable to send result to the callback", e);
            }
        }

@@ -398,7 +413,7 @@ public class AppSearchManagerService extends SystemService {
            try {
                callback.onResult(result);
            } catch (RemoteException e) {
                Log.d(TAG, "Unable to send result to the callback", e);
                Log.e(TAG, "Unable to send result to the callback", e);
            }
        }

@@ -411,7 +426,7 @@ public class AppSearchManagerService extends SystemService {
            try {
                callback.onResult(throwableToFailedResult(throwable));
            } catch (RemoteException e) {
                Log.d(TAG, "Unable to send result to the callback", e);
                Log.e(TAG, "Unable to send result to the callback", e);
            }
        }

@@ -425,7 +440,7 @@ public class AppSearchManagerService extends SystemService {
            try {
                callback.onSystemError(new ParcelableException(throwable));
            } catch (RemoteException e) {
                Log.d(TAG, "Unable to send error to the callback", e);
                Log.e(TAG, "Unable to send error to the callback", e);
            }
        }
    }
+19 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.google.android.icing.proto.GetSchemaResultProto;
import com.google.android.icing.proto.IcingSearchEngineOptions;
import com.google.android.icing.proto.InitializeResultProto;
import com.google.android.icing.proto.OptimizeResultProto;
import com.google.android.icing.proto.PersistToDiskResultProto;
import com.google.android.icing.proto.PropertyConfigProto;
import com.google.android.icing.proto.PropertyProto;
import com.google.android.icing.proto.PutResultProto;
@@ -630,6 +631,24 @@ public final class AppSearchImpl {
                deleteResultProto.getStatus(), StatusProto.Code.OK, StatusProto.Code.NOT_FOUND);
    }

    /**
     * Persists all update/delete requests to the disk.
     *
     * <p>If the app crashes after a call to PersistToDisk(), Icing would be able to fully recover
     * all data written up to this point without a costly recovery process.
     *
     * <p>If the app crashes before a call to PersistToDisk(), Icing would trigger a costly recovery
     * process in next initialization. After that, Icing would still be able to recover all written
     * data.
     *
     * @throws AppSearchException
     */
    public void persistToDisk() throws AppSearchException {
        PersistToDiskResultProto persistToDiskResultProto =
                mIcingSearchEngineLocked.persistToDisk();
        checkSuccess(persistToDiskResultProto.getStatus());
    }

    /**
     * Clears documents and schema across all packages and databaseNames.
     *
Loading