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

Commit 97fceffe authored by Alexander Dorokhine's avatar Alexander Dorokhine Committed by Automerger Merge Worker
Browse files

Merge "Move to non-hidden APIs for handleUser and broadcast registration."...

Merge "Move to non-hidden APIs for handleUser and broadcast registration." into sc-dev am: 6756cce8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14669986

Change-Id: I267020b9d83aa903a1472c3550cbf658c27d1cdf
parents e1201390 6756cce8
Loading
Loading
Loading
Loading
+48 −26
Original line number Diff line number Diff line
@@ -17,11 +17,10 @@ package com.android.server.appsearch;

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

import android.Manifest;
import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.appsearch.AppSearchBatchResult;
import android.app.appsearch.AppSearchMigrationHelper;
import android.app.appsearch.AppSearchResult;
@@ -63,6 +62,7 @@ import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.stats.LoggerInstanceManager;
import com.android.server.appsearch.stats.PlatformLogger;
import com.android.server.appsearch.util.PackageUtil;
import com.android.server.usage.StorageStatsManagerLocal;
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;

@@ -124,8 +124,10 @@ public class AppSearchManagerService extends SystemService {
    }

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

        //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
@@ -135,8 +137,10 @@ public class AppSearchManagerService extends SystemService {
        packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
        packageChangedFilter.addDataScheme("package");
        packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        mContext.registerReceiverAsUser(new PackageChangedReceiver(), UserHandle.ALL,
                packageChangedFilter, /*broadcastPermission=*/ null,
        mContext.registerReceiverForAllUsers(
                new PackageChangedReceiver(),
                packageChangedFilter,
                /*broadcastPermission=*/ null,
                /*scheduler=*/ null);
    }

@@ -148,12 +152,13 @@ public class AppSearchManagerService extends SystemService {

            switch (intent.getAction()) {
                case Intent.ACTION_USER_REMOVED:
                    int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                    if (userId == USER_NULL) {
                        Log.e(TAG, "userId is missing in the intent: " + intent);
                    UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
                    if (userHandle == null) {
                        Log.e(TAG, "Extra "
                                + Intent.EXTRA_USER + " is missing in the intent: " + intent);
                        return;
                    }
                    handleUserRemoved(UserHandle.of(userId));
                    handleUserRemoved(userHandle);
                    break;
                default:
                    Log.e(TAG, "Received unknown intent: " + intent);
@@ -1183,13 +1188,9 @@ public class AppSearchManagerService extends SystemService {
            Objects.requireNonNull(actualCallingUser);
            Objects.requireNonNull(claimedCallingPackage);

            int claimedCallingUid;
            try {
                Context claimedCallingContext =
                        mContext.createContextAsUser(actualCallingUser, /*flags=*/ 0);
                claimedCallingUid = claimedCallingContext.getPackageManager().getPackageUid(
                        claimedCallingPackage, /*flags=*/ 0);
            } catch (PackageManager.NameNotFoundException e) {
            int claimedCallingUid = PackageUtil.getPackageUidAsUser(
                    mContext, claimedCallingPackage, actualCallingUser);
            if (claimedCallingUid == INVALID_UID) {
                throw new SecurityException(
                        "Specified calling package [" + claimedCallingPackage + "] not found");
            }
@@ -1257,23 +1258,44 @@ public class AppSearchManagerService extends SystemService {
     *
     * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
     *
     * @param requestedUser The user which the caller is requesting to execute as.
     * @param callingUid The actual uid of the caller as determined by Binder.
     * @return the user handle that the call should run as. Will always be a concrete user.
     */
    // TODO(b/173553485) verifying that the caller has permission to access target user's data
    // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
    // TODO(b/173553485) Implement SystemService.onUserStopping()
    @NonNull
    private static UserHandle handleIncomingUser(@NonNull UserHandle userHandle, int callingUid) {
    private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
        int callingPid = Binder.getCallingPid();
        int finalUserId = ActivityManager.handleIncomingUser(
        UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
        if (callingUser.equals(requestedUser)) {
            return requestedUser;
        }
        // Duplicates UserController#ensureNotSpecialUser
        if (requestedUser.getIdentifier() < 0) {
            throw new IllegalArgumentException(
                    "Call does not support special user " + requestedUser);
        }
        boolean canInteractAcrossUsers = mContext.checkPermission(
                Manifest.permission.INTERACT_ACROSS_USERS,
                callingPid,
                callingUid,
                userHandle.getIdentifier(),
                /*allowAll=*/ false,
                /*requireFull=*/ false,
                /*name=*/ null,
                /*callerPackage=*/ null);
        return UserHandle.of(finalUserId);
                callingUid) == PackageManager.PERMISSION_GRANTED;
        if (!canInteractAcrossUsers) {
            canInteractAcrossUsers = mContext.checkPermission(
                    Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    callingPid,
                    callingUid) == PackageManager.PERMISSION_GRANTED;
        }
        if (canInteractAcrossUsers) {
            return requestedUser;
        }
        throw new SecurityException(
                "Permission denied while calling from uid " + callingUid
                        + " with " + requestedUser + "; Need to run as either the calling user ("
                        + callingUser + "), or with one of the following permissions: "
                        + Manifest.permission.INTERACT_ACROSS_USERS + " or "
                        + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
    }

    // TODO(b/179160886): Cache the previous storage stats.
+1 −6
Original line number Diff line number Diff line
@@ -172,11 +172,6 @@ public final class ImplInstanceManager {
            @Nullable AppSearchLogger logger)
            throws AppSearchException {
        File appSearchDir = getAppSearchDir(userHandle);
        // TODO(b/181787682): Swap AppSearchImpl and VisibilityStore to accept a UserHandle too
        return AppSearchImpl.create(
                appSearchDir,
                userContext,
                userHandle.getIdentifier(),
                /*logger=*/ null);
        return AppSearchImpl.create(appSearchDir, userContext, /*logger=*/ null);
    }
}
+2 −5
Original line number Diff line number Diff line
@@ -201,7 +201,6 @@ public final class AppSearchImpl implements Closeable {
    public static AppSearchImpl create(
            @NonNull File icingDir,
            @NonNull Context userContext,
            int userId,
            @Nullable AppSearchLogger logger)
            throws AppSearchException {
        Objects.requireNonNull(icingDir);
@@ -213,8 +212,7 @@ public final class AppSearchImpl implements Closeable {
            initStatsBuilder = new InitializeStats.Builder();
        }

        AppSearchImpl appSearchImpl =
                new AppSearchImpl(icingDir, userContext, userId, initStatsBuilder);
        AppSearchImpl appSearchImpl = new AppSearchImpl(icingDir, userContext, initStatsBuilder);

        long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
        appSearchImpl.initializeVisibilityStore();
@@ -238,7 +236,6 @@ public final class AppSearchImpl implements Closeable {
    private AppSearchImpl(
            @NonNull File icingDir,
            @NonNull Context userContext,
            int userId,
            @Nullable InitializeStats.Builder initStatsBuilder)
            throws AppSearchException {
        mReadWriteLock.writeLock().lock();
@@ -256,7 +253,7 @@ public final class AppSearchImpl implements Closeable {
                    "Constructing IcingSearchEngine, response",
                    Objects.hashCode(mIcingSearchEngineLocked));

            mVisibilityStoreLocked = new VisibilityStore(this, userContext, userId);
            mVisibilityStoreLocked = new VisibilityStore(this, userContext);

            // The core initialization procedure. If any part of this fails, we bail into
            // resetLocked(), deleting all data (but hopefully allowing AppSearchImpl to come up).
+7 −15
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -36,6 +35,7 @@ import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
import com.android.server.appsearch.util.PackageUtil;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
@@ -493,21 +493,13 @@ public final class PlatformLogger implements AppSearchLogger {
    @GuardedBy("mLock")
    private int getPackageUidAsUserLocked(@NonNull String packageName) {
        Integer packageUid = mPackageUidCacheLocked.get(packageName);
        if (packageUid != null) {
            return packageUid;
        }

        // TODO(b/173532925) since VisibilityStore has the same method, we can make this a
        //  utility function
        try {
            packageUid = mContext.getPackageManager().getPackageUidAsUser(
                    packageName, mUserHandle.getIdentifier());
        if (packageUid == null) {
            packageUid = PackageUtil.getPackageUidAsUser(mContext, packageName, mUserHandle);
            if (packageUid != Process.INVALID_UID) {
                mPackageUidCacheLocked.put(packageName, packageUid);
            return packageUid;
        } catch (PackageManager.NameNotFoundException e) {
            // Package doesn't exist, continue
            }
        return Process.INVALID_UID;
        }
        return packageUid;
    }

    //
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 com.android.server.appsearch.util;

import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.UserHandle;

/**
 * Utilities for interacting with {@link android.content.pm.PackageManager},
 * {@link android.os.UserHandle}, and other parts of dealing with apps and binder.
 *
 * @hide
 */
public class PackageUtil {
    private PackageUtil() {}

    /**
     * Finds the UID of the {@code packageName}. Returns {@link Process#INVALID_UID} if unable to
     * find the UID.
     */
    public static int getPackageUidAsUser(
            @NonNull Context context, @NonNull String packageName, @NonNull UserHandle user) {
        Context userContext = context.createContextAsUser(user, /*flags=*/ 0);
        return getPackageUid(userContext, packageName);
    }

    /**
     * Finds the UID of the {@code packageName} in the given {@code context}. Returns
     * {@link Process#INVALID_UID} if unable to find the UID.
     */
    public static int getPackageUid(@NonNull Context context, @NonNull String packageName) {
        try {
            return context.getPackageManager().getPackageUid(packageName, /*flags=*/ 0);
        } catch (PackageManager.NameNotFoundException e) {
            return Process.INVALID_UID;
        }
    }
}
Loading