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

Commit 55e726fb authored by Jiaming Liu's avatar Jiaming Liu
Browse files

Allow application level knownActivityEmbeddingCerts

Bug: 289199433
Test: atest TaskFragmentTest
Change-Id: I17ff85774b7ac8a7feebaa1d580008035892885a
parent 698dcbb0
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.