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

Commit 5d5b6852 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7266202 from 9759067e to sc-release

Change-Id: Icce59589fd13439e038ad0a5087918db2e0fae4c
parents 4c2bbf55 9759067e
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -297,11 +297,26 @@ public final class SetSchemaRequest {
        }

        /**
         * Sets the {@link Migrator}.
         * Sets the {@link Migrator} associated with the given SchemaType.
         *
         * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
         * from the current version number stored in AppSearch to the final version set via {@link
         * #setVersion}.
         *
         * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch
         * is different from the final version set via {@link #setVersion} and {@link
         * Migrator#shouldMigrate} returns {@code true}.
         *
         * <p>The target schema type of the output {@link GenericDocument} of {@link
         * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link
         * SetSchemaRequest}.
         *
         * @param schemaType The schema type to set migrator on.
         * @param migrator The migrator translate a document from it's old version to a new
         *     incompatible version.
         * @param migrator The migrator translates a document from its current version to the final
         *     version set via {@link #setVersion}.
         * @see SetSchemaRequest.Builder#setVersion
         * @see SetSchemaRequest.Builder#addSchemas
         * @see AppSearchSession#setSchema
         */
        @NonNull
        @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects.
@@ -313,10 +328,25 @@ public final class SetSchemaRequest {
        }

        /**
         * Sets {@link Migrator}s.
         * Sets a Map of {@link Migrator}s.
         *
         * @param migrators A {@link Map} of migrators that translate a document from its old
         *     version to a new incompatible version.
         * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
         * from the current version number stored in AppSearch to the final version set via {@link
         * #setVersion}.
         *
         * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch
         * is different from the final version set via {@link #setVersion} and {@link
         * Migrator#shouldMigrate} returns {@code true}.
         *
         * <p>The target schema type of the output {@link GenericDocument} of {@link
         * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link
         * SetSchemaRequest}.
         *
         * @param migrators A {@link Map} of migrators that translate a document from it's current
         *     version to the final version set via {@link #setVersion}.
         * @see SetSchemaRequest.Builder#setVersion
         * @see SetSchemaRequest.Builder#addSchemas
         * @see AppSearchSession#setSchema
         */
        @NonNull
        public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
+55 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.appsearch;

import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
import static android.os.UserHandle.USER_NULL;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -34,7 +35,10 @@ import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
import android.app.appsearch.SetSchemaResponse;
import android.app.appsearch.StorageInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.Bundle;
@@ -46,6 +50,7 @@ import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -67,6 +72,7 @@ import java.util.Set;
/** TODO(b/142567528): add comments when implement this class */
public class AppSearchManagerService extends SystemService {
    private static final String TAG = "AppSearchManagerService";
    private final Context mContext;
    private PackageManagerInternal mPackageManagerInternal;
    private ImplInstanceManager mImplInstanceManager;
    private UserManager mUserManager;
@@ -79,14 +85,60 @@ public class AppSearchManagerService extends SystemService {

    public AppSearchManagerService(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public void onStart() {
        publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
        mUserManager = getContext().getSystemService(UserManager.class);
        mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
        mUserManager = mContext.getSystemService(UserManager.class);
        registerReceivers();
    }

    private void registerReceivers() {
        mContext.registerReceiverAsUser(new UserActionReceiver(), UserHandle.ALL,
                new IntentFilter(Intent.ACTION_USER_REMOVED), /*broadcastPermission=*/ null,
                /*scheduler=*/ null);
    }

    private class UserActionReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(@NonNull Context context, @NonNull Intent intent) {
            switch (intent.getAction()) {
                case Intent.ACTION_USER_REMOVED:
                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                    if (userId == USER_NULL) {
                        Slog.e(TAG, "userId is missing in the intent: " + intent);
                        return;
                    }
                    handleUserRemoved(userId);
                    break;
                default:
                    Slog.e(TAG, "Received unknown intent: " + intent);
            }
        }
    }

    /**
     * Handles user removed action.
     *
     * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
     * "credential encrypted" system directory of each user. That directory will be auto-deleted
     * when a user is removed.
     *
     * @param userId The multi-user userId of the user that need to be removed.
     *
     * @see android.os.Environment#getDataSystemCeDirectory
     */
    private void handleUserRemoved(@UserIdInt int userId) {
        try {
            mImplInstanceManager.removeAppSearchImplForUser(userId);
            Slog.i(TAG, "Removed AppSearchImpl instance for user: " + userId);
        } catch (Throwable t) {
            Slog.e(TAG, "Unable to remove data for user: " + userId, t);
        }
    }

    @Override
@@ -663,7 +715,7 @@ public class AppSearchManagerService extends SystemService {
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                verifyUserUnlocked(callingUserId);
                mImplInstanceManager.getOrCreateAppSearchImpl(getContext(), callingUserId);
                mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId);
                invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
            } catch (Throwable t) {
                invokeCallbackOnError(callback, t);
+17 −0
Original line number Diff line number Diff line
@@ -95,6 +95,23 @@ public final class ImplInstanceManager {
        }
    }

    /**
     * Remove an instance of {@link AppSearchImpl} for the given user.
     *
     * <p>This method should only be called if {@link AppSearchManagerService} receives an
     * ACTION_USER_REMOVED, which the instance of given user should be removed.
     *
     * <p>If the user is removed, the "credential encrypted" system directory where icing lives will
     * be auto-deleted. So we shouldn't worry about persist data or close the AppSearchImpl.
     *
     * @param userId The multi-user userId of the user that need to be removed.
     */
    @NonNull
    public void removeAppSearchImplForUser(@UserIdInt int userId) {
        synchronized (mInstancesLocked) {
            mInstancesLocked.remove(userId);
        }
    }

    /**
     * Gets an instance of AppSearchImpl for the given user.
+3 −0
Original line number Diff line number Diff line
@@ -3,6 +3,9 @@
    {
      "name": "CtsAppSearchTestCases"
    },
    {
      "name": "CtsAppSearchHostTestCases"
    },
    {
      "name": "FrameworksServicesTests",
      "options": [
+40 −1
Original line number Diff line number Diff line
@@ -1126,6 +1126,40 @@ public final class AppSearchImpl implements Closeable {
        }
    }

    /**
     * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s under the given package.
     *
     * @param packageName The name of package to be removed.
     * @throws AppSearchException if we cannot remove the data.
     */
    public void clearPackageData(@NonNull String packageName) throws AppSearchException {
        mReadWriteLock.writeLock().lock();
        try {
            throwIfClosedLocked();

            SchemaProto existingSchema = getSchemaProtoLocked();
            SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();

            String prefix = createPackagePrefix(packageName);
            for (int i = 0; i < existingSchema.getTypesCount(); i++) {
                if (!existingSchema.getTypes(i).getSchemaType().startsWith(prefix)) {
                    newSchemaBuilder.addTypes(existingSchema.getTypes(i));
                }
            }

            // Apply schema, set force override to true to remove all schemas and documents under
            // that package.
            SetSchemaResultProto setSchemaResultProto =
                    mIcingSearchEngineLocked.setSchema(
                            newSchemaBuilder.build(), /*ignoreErrorsAndDeleteDocuments=*/ true);

            // Determine whether it succeeded.
            checkSuccess(setSchemaResultProto.getStatus());
        } finally {
            mReadWriteLock.writeLock().unlock();
        }
    }

    /**
     * Clears documents and schema across all packages and databaseNames.
     *
@@ -1624,7 +1658,12 @@ public final class AppSearchImpl implements Closeable {

    @NonNull
    static String createPrefix(@NonNull String packageName, @NonNull String databaseName) {
        return packageName + PACKAGE_DELIMITER + databaseName + DATABASE_DELIMITER;
        return createPackagePrefix(packageName) + databaseName + DATABASE_DELIMITER;
    }

    @NonNull
    private static String createPackagePrefix(@NonNull String packageName) {
        return packageName + PACKAGE_DELIMITER;
    }

    /**
Loading