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

Commit 4aba0d84 authored by Terry Wang's avatar Terry Wang
Browse files

Update Framework from Jetpack.

Changes included:
#efb600e:Add Closeable to AppSearchSession, allow it persist data to disk.

Bug: 162450968
Test: presubmit
Change-Id: Ib00cf83e41f0e3e2f79b4c46d9a50407e72bd9bb
parent 397070ce
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