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

Commit 5ff58de7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Grant target implicit visibility onExecuteAppFunctions" into main

parents 0d258c4e 1f40027e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ package com.android.server.appfunctions;
import android.annotation.NonNull;
import android.app.appfunctions.AppFunctionManagerConfiguration;
import android.content.Context;
import android.content.pm.PackageManagerInternal;

import com.android.server.LocalServices;
import com.android.server.SystemService;

/** Service that manages app functions. */
@@ -28,7 +30,9 @@ public class AppFunctionManagerService extends SystemService {

    public AppFunctionManagerService(Context context) {
        super(context);
        mServiceImpl = new AppFunctionManagerServiceImpl(context);
        mServiceImpl =
                new AppFunctionManagerServiceImpl(
                        context, LocalServices.getService(PackageManagerInternal.class));
    }

    @Override
+27 −3
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.app.appsearch.observer.ObserverSpec;
import android.app.appsearch.observer.SchemaChangeInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.CancellationSignal;
import android.os.IBinder;
@@ -87,8 +88,10 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
    private final Context mContext;
    private final Map<String, Object> mLocks = new WeakHashMap<>();
    private final AppFunctionsLoggerWrapper mLoggerWrapper;
    private final PackageManagerInternal mPackageManagerInternal;

    public AppFunctionManagerServiceImpl(@NonNull Context context) {
    public AppFunctionManagerServiceImpl(
            @NonNull Context context, @NonNull PackageManagerInternal packageManagerInternal) {
        this(
                context,
                new RemoteServiceCallerImpl<>(
@@ -96,7 +99,8 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
                new CallerValidatorImpl(context),
                new ServiceHelperImpl(context),
                new ServiceConfigImpl(),
                new AppFunctionsLoggerWrapper(context));
                new AppFunctionsLoggerWrapper(context),
                packageManagerInternal);
    }

    @VisibleForTesting
@@ -106,13 +110,15 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
            CallerValidator callerValidator,
            ServiceHelper appFunctionInternalServiceHelper,
            ServiceConfig serviceConfig,
            AppFunctionsLoggerWrapper loggerWrapper) {
            AppFunctionsLoggerWrapper loggerWrapper,
            PackageManagerInternal packageManagerInternal) {
        mContext = Objects.requireNonNull(context);
        mRemoteServiceCaller = Objects.requireNonNull(remoteServiceCaller);
        mCallerValidator = Objects.requireNonNull(callerValidator);
        mInternalServiceHelper = Objects.requireNonNull(appFunctionInternalServiceHelper);
        mServiceConfig = serviceConfig;
        mLoggerWrapper = loggerWrapper;
        mPackageManagerInternal = Objects.requireNonNull(packageManagerInternal);
    }

    /** Called when the user is unlocked. */
@@ -260,6 +266,24 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
                                                "Cannot find the target service."));
                                return;
                            }
                            // Grant target app implicit visibility to the caller
                            final int grantRecipientUserId = targetUser.getIdentifier();
                            final int grantRecipientAppId =
                                    UserHandle.getAppId(
                                            mPackageManagerInternal.getPackageUid(
                                                    requestInternal
                                                            .getClientRequest()
                                                            .getTargetPackageName(),
                                                    /* flags= */ 0,
                                                    /* userId= */ grantRecipientUserId));
                            if (grantRecipientAppId > 0) {
                                mPackageManagerInternal.grantImplicitAccess(
                                        grantRecipientUserId,
                                        serviceIntent,
                                        grantRecipientAppId,
                                        callingUid,
                                        /* direct= */ true);
                            }
                            bindAppFunctionServiceUnchecked(
                                    requestInternal,
                                    serviceIntent,
+0 −2
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ import java.util.Objects;
class ServiceHelperImpl implements ServiceHelper {
    private final Context mContext;

    // TODO(b/357551503): Keep track of unlocked users.

    ServiceHelperImpl(@NonNull Context context) {
        mContext = Objects.requireNonNull(context);
    }
+9 −2
Original line number Diff line number Diff line
@@ -18,28 +18,35 @@ package com.android.server.appfunctions

import android.app.appfunctions.flags.Flags
import android.content.Context
import android.content.pm.PackageManagerInternal
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.CheckFlagsRule
import android.platform.test.flag.junit.DeviceFlagsValueProvider
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.modules.utils.testing.ExtendedMockitoRule
import com.android.server.LocalServices
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock

@RunWith(AndroidJUnit4::class)
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
class AppFunctionManagerServiceImplTest {
    @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()

    @get:Rule
    val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
    val extendedMockitoRule =
        ExtendedMockitoRule.Builder(this).mockStatic(LocalServices::class.java).build()

    private val context: Context
        get() = ApplicationProvider.getApplicationContext()

    private val serviceImpl = AppFunctionManagerServiceImpl(context)
    private val serviceImpl = AppFunctionManagerServiceImpl(context, mock<PackageManagerInternal>())

    @Test
    fun testGetLockForPackage_samePackage() {
+38 −18
Original line number Diff line number Diff line
@@ -25,11 +25,13 @@ import android.app.appfunctions.SafeOneTimeExecuteAppFunctionCallback
import android.app.appsearch.GenericDocument
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManagerInternal
import android.os.UserHandle
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.modules.utils.testing.ExtendedMockitoRule
import com.android.server.LocalServices
import com.google.common.util.concurrent.MoreExecutors
import org.junit.Before
import org.junit.Rule
@@ -40,24 +42,25 @@ import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever


/**
 * Tests that AppFunctionsStatsLog logs AppFunctionsRequestReported with the expected values.
 */
/** Tests that AppFunctionsStatsLog logs AppFunctionsRequestReported with the expected values. */
@RunWith(AndroidJUnit4::class)
class AppFunctionsLoggingTest {
    @get:Rule
    val mExtendedMockitoRule: ExtendedMockitoRule =
        ExtendedMockitoRule.Builder(this)
            .mockStatic(AppFunctionsStatsLog::class.java)
            .mockStatic(LocalServices::class.java)
            .build()
    private val mContext: Context get() = ApplicationProvider.getApplicationContext()
    private val mContext: Context
        get() = ApplicationProvider.getApplicationContext()

    private val mMockPackageManager = mock<PackageManager>()
    private val mAppFunctionsLoggerWrapper =
        AppFunctionsLoggerWrapper(
            mMockPackageManager,
            MoreExecutors.directExecutor(),
            { TEST_CURRENT_TIME_MILLIS })
            { TEST_CURRENT_TIME_MILLIS },
        )
    private lateinit var mSafeCallback: SafeOneTimeExecuteAppFunctionCallback

    private val mServiceImpl =
@@ -67,25 +70,40 @@ class AppFunctionsLoggingTest {
            mock<CallerValidator>(),
            mock<ServiceHelper>(),
            ServiceConfigImpl(),
            mAppFunctionsLoggerWrapper)
            mAppFunctionsLoggerWrapper,
            mock<PackageManagerInternal>(),
        )

    private val mRequestInternal = ExecuteAppFunctionAidlRequest(
    private val mRequestInternal =
        ExecuteAppFunctionAidlRequest(
            ExecuteAppFunctionRequest.Builder(TEST_TARGET_PACKAGE, TEST_FUNCTION_ID).build(),
        UserHandle.CURRENT, TEST_CALLING_PKG, TEST_INITIAL_REQUEST_TIME_MILLIS
            UserHandle.CURRENT,
            TEST_CALLING_PKG,
            TEST_INITIAL_REQUEST_TIME_MILLIS,
        )

    @Before
    fun setup() {
        whenever(mMockPackageManager.getPackageUid(eq(TEST_TARGET_PACKAGE), any<Int>())).thenReturn(TEST_TARGET_UID)
        mSafeCallback = mServiceImpl.initializeSafeExecuteAppFunctionCallback(mRequestInternal, mock<IExecuteAppFunctionCallback>(), TEST_CALLING_UID)
        whenever(mMockPackageManager.getPackageUid(eq(TEST_TARGET_PACKAGE), any<Int>()))
            .thenReturn(TEST_TARGET_UID)
        mSafeCallback =
            mServiceImpl.initializeSafeExecuteAppFunctionCallback(
                mRequestInternal,
                mock<IExecuteAppFunctionCallback>(),
                TEST_CALLING_UID,
            )
        mSafeCallback.setExecutionStartTimeAfterBindMillis(TEST_EXECUTION_TIME_AFTER_BIND_MILLIS)
    }

    @Test
    fun testOnSuccess_logsSuccessResponse() {
        val response =
            ExecuteAppFunctionResponse(GenericDocument.Builder<GenericDocument.Builder<*>>("", "", "")
                .setPropertyLong("longProperty", 42L).setPropertyString("stringProperty", "text").build())
            ExecuteAppFunctionResponse(
                GenericDocument.Builder<GenericDocument.Builder<*>>("", "", "")
                    .setPropertyLong("longProperty", 42L)
                    .setPropertyString("stringProperty", "text")
                    .build()
            )

        mSafeCallback.onResult(response)

@@ -98,14 +116,16 @@ class AppFunctionsLoggingTest {
                /* requestSizeBytes= */ eq<Int>(mRequestInternal.clientRequest.requestDataSize),
                /* responseSizeBytes= */ eq<Int>(response.responseDataSize),
                /* requestDurationMs= */ eq<Long>(TEST_EXPECTED_E2E_DURATION_MILLIS),
                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS)
                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS),
            )
        }
    }

    @Test
    fun testOnError_logsFailureResponse() {
        mSafeCallback.onError(AppFunctionException(AppFunctionException.ERROR_DENIED, "Error: permission denied"))
        mSafeCallback.onError(
            AppFunctionException(AppFunctionException.ERROR_DENIED, "Error: permission denied")
        )

        ExtendedMockito.verify {
            AppFunctionsStatsLog.write(
@@ -116,7 +136,7 @@ class AppFunctionsLoggingTest {
                /* requestSizeBytes= */ eq<Int>(mRequestInternal.clientRequest.requestDataSize),
                /* responseSizeBytes= */ eq<Int>(0),
                /* requestDurationMs= */ eq<Long>(TEST_EXPECTED_E2E_DURATION_MILLIS),
                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS)
                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS),
            )
        }
    }