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

Commit d129d9bf authored by Jiaming Liu's avatar Jiaming Liu Committed by Android (Google) Code Review
Browse files

Merge "Allow application level knownActivityEmbeddingCerts" into main

parents 7b3abf1c 55e726fb
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -732,17 +732,30 @@ class TaskFragment extends WindowContainer<WindowContainer> {
            return true;
        }

        final AndroidPackage hostPackage = mAtmService.getPackageManagerInternalLocked()
                .getPackage(uid);

        return hostPackage != null
                && isAllowedToEmbedActivityInTrustedModeByHostPackage(a, hostPackage);
    }

    @VisibleForTesting
    boolean isAllowedToEmbedActivityInTrustedModeByHostPackage(
            @NonNull ActivityRecord a, @NonNull AndroidPackage hostPackage) {

        // Known certs declared in the <activity> tag
        Set<String> knownActivityEmbeddingCerts = a.info.getKnownActivityEmbeddingCerts();

        // If the activity-level value is specified, it takes precedence. Otherwise, we read the
        // application-level value.
        if (knownActivityEmbeddingCerts.isEmpty()) {
            // An application must either declare that it allows untrusted embedding, or specify
            // a set of app certificates that are allowed to embed it in trusted mode.
            return false;
            // Known certs declared in the <application> tag
            knownActivityEmbeddingCerts = a.info.applicationInfo.getKnownActivityEmbeddingCerts();
        }

        AndroidPackage hostPackage = mAtmService.getPackageManagerInternalLocked()
                .getPackage(uid);

        return hostPackage != null && hostPackage.getSigningDetails().hasAncestorOrSelfWithDigest(
        // An application must specify a set of app certificates that are allowed to embed it in
        // trusted mode.
        return hostPackage.getSigningDetails().hasAncestorOrSelfWithDigest(
                knownActivityEmbeddingCerts);
    }

+6 −0
Original line number Diff line number Diff line
@@ -425,6 +425,12 @@ public class ActivityStarterTests extends WindowTestsBase {
        doNothing().when(mMockPackageManager).notifyPackageUse(anyString(), anyInt());
        doReturn(mock(PackageArchiver.class)).when(mMockPackageManager).getPackageArchiver();

        final AndroidPackage mockPackage = mock(AndroidPackage.class);
        final SigningDetails signingDetails = mock(SigningDetails.class);
        doReturn(mockPackage).when(mMockPackageManager).getPackage(anyInt());
        doReturn(signingDetails).when(mockPackage).getSigningDetails();
        doReturn(false).when(signingDetails).hasAncestorOrSelfWithDigest(any());

        final Intent intent = new Intent();
        intent.addFlags(launchFlags);
        intent.setComponent(ActivityBuilder.getDefaultComponent());
+52 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK;
import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_TASK_FRAGMENT;
@@ -46,7 +47,9 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;

import android.content.pm.SigningDetails;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
@@ -61,12 +64,17 @@ import android.window.TaskFragmentOrganizer;

import androidx.test.filters.MediumTest;

import com.android.server.pm.pkg.AndroidPackage;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Collections;
import java.util.Set;

/**
 * Test class for {@link TaskFragment}.
 *
@@ -536,6 +544,49 @@ public class TaskFragmentTest extends WindowTestsBase {
                taskFragment.isAllowedToEmbedActivity(activity));
    }

    @Test
    public void testIsAllowedToEmbedActivityInTrustedModeByHostPackage() {
        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
                .setCreateParentTask()
                .createActivityCount(1)
                .build();
        final ActivityRecord activity = taskFragment.getTopMostActivity();

        final String mockCert = "MOCKCERT";
        final AndroidPackage hostPackage = mock(AndroidPackage.class);
        final SigningDetails signingDetails = mock(SigningDetails.class);
        when(signingDetails.hasAncestorOrSelfWithDigest(any()))
                .thenAnswer(invocation -> ((Set) invocation.getArgument(0)).contains(mockCert));
        doReturn(signingDetails).when(hostPackage).getSigningDetails();

        // Should return false when no certs are specified
        assertFalse(taskFragment.isAllowedToEmbedActivityInTrustedModeByHostPackage(
                activity, hostPackage));

        // Should return true when the cert is specified in <activity>
        activity.info.setKnownActivityEmbeddingCerts(Set.of(mockCert));
        assertTrue(taskFragment.isAllowedToEmbedActivityInTrustedModeByHostPackage(
                activity, hostPackage));

        // Should return false when the certs specified in <activity> doesn't match
        activity.info.setKnownActivityEmbeddingCerts(Set.of("WRONGCERT"));
        assertFalse(taskFragment.isAllowedToEmbedActivityInTrustedModeByHostPackage(
                activity, hostPackage));

        // Should return true when the certs is specified in <application>
        activity.info.setKnownActivityEmbeddingCerts(Collections.emptySet());
        activity.info.applicationInfo.setKnownActivityEmbeddingCerts(Set.of(mockCert));
        assertTrue(taskFragment.isAllowedToEmbedActivityInTrustedModeByHostPackage(
                activity, hostPackage));

        // When the certs is specified in both <activity> and <application>, <activity> takes
        // precedence
        activity.info.setKnownActivityEmbeddingCerts(Set.of("WRONGCERT"));
        activity.info.applicationInfo.setKnownActivityEmbeddingCerts(Set.of(mockCert));
        assertFalse(taskFragment.isAllowedToEmbedActivityInTrustedModeByHostPackage(
                activity, hostPackage));
    }

    @Test
    public void testIgnoreRequestedOrientationForActivityEmbeddingSplit() {
        // Setup two activities in ActivityEmbedding split.