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

Commit 73e86500 authored by Andrey Yepin's avatar Andrey Yepin Committed by Automerger Merge Worker
Browse files

Merge "Sanitize cross-profile intents." into tm-dev am: 013d4318 am: f11809e5 am: c62e1fd3

parents b6b59740 c62e1fd3
Loading
Loading
Loading
Loading
+35 −2
Original line number Diff line number Diff line
@@ -923,16 +923,21 @@ public class ChooserActivity extends ResolverActivity implements
            List<ResolveInfo> rList,
            boolean filterLastUsed) {
        int selectedProfile = findSelectedProfile();
        List<Intent> crossProfileIntents = sanitizePayloadIntents(mIntents);
        ChooserGridAdapter personalAdapter = createChooserGridAdapter(
                /* context */ this,
                /* payloadIntents */ mIntents,
                /* payloadIntents */ selectedProfile == PROFILE_PERSONAL
                        ? mIntents
                        : crossProfileIntents,
                selectedProfile == PROFILE_PERSONAL ? initialIntents : null,
                rList,
                filterLastUsed,
                /* userHandle */ getPersonalProfileUserHandle());
        ChooserGridAdapter workAdapter = createChooserGridAdapter(
                /* context */ this,
                /* payloadIntents */ mIntents,
                /* payloadIntents */ selectedProfile == PROFILE_WORK
                        ? mIntents
                        : crossProfileIntents,
                selectedProfile == PROFILE_WORK ? initialIntents : null,
                rList,
                filterLastUsed,
@@ -4361,4 +4366,32 @@ public class ChooserActivity extends ResolverActivity implements
                target.getComponentName(),
                target.getIntentExtras());
    }

    /**
     * Returns a copy of provided intents with explicit targeting information is removed from each
     * intent in the list, as well as from its selector {@link Intent#getSelector}. Specifically,
     * the values that would be returned by {@link Intent#getPackage} and
     * {@link Intent#getComponent} are cleared for both the main intent and its selector. This
     * sanitization is performed because explicit intents could otherwise be used to bypass the
     * device's cross-profile sharing policy settings.
     */
    @NonNull
    @VisibleForTesting
    public static List<Intent> sanitizePayloadIntents(@NonNull List<Intent> intents) {
        return intents.stream().map((intent) -> {
            if (intent == null) {
                return null;
            }
            Intent sanitized = new Intent(intent);
            sanitized.setPackage(null);
            sanitized.setComponent(null);
            if (sanitized.getSelector() != null) {
                Intent selector = new Intent(sanitized.getSelector());
                selector.setPackage(null);
                selector.setComponent(null);
                sanitized.setSelector(selector);
            }
            return sanitized;
        }).collect(Collectors.toList());
    }
}
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.internal.app;

import static android.content.Intent.ACTION_SEND;

import static com.google.common.truth.Truth.assertThat;

import android.content.ComponentName;
import android.content.Intent;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ChooserActivityCrossProfileIntentsTest {
    @Test
    public void test_sanitizePayloadIntents() {
        final Intent intentOne = new Intent(ACTION_SEND);
        intentOne.setPackage("org.test.example");
        final Intent intentTwo = new Intent(ACTION_SEND);
        intentTwo.setComponent(ComponentName.unflattenFromString("org.test.example/.TestActivity"));
        final Intent intentThree = new Intent(ACTION_SEND);
        intentThree.setSelector(new Intent(intentOne));
        final Intent intentFour = new Intent(ACTION_SEND);
        intentFour.setSelector(new Intent(intentTwo));
        ArrayList<Intent> intents = new ArrayList<>();
        Collections.addAll(intents, intentOne, intentTwo, intentThree, intentFour);

        List<Intent> sanitizedIntents = ChooserActivity.sanitizePayloadIntents(intents);

        assertThat(sanitizedIntents).hasSize(intents.size());
        for (Intent intent : sanitizedIntents) {
            assertThat(intent.getPackage()).isNull();
            assertThat(intent.getComponent()).isNull();
            Intent selector = intent.getSelector();
            if (selector != null) {
                assertThat(selector.getPackage()).isNull();
                assertThat(selector.getComponent()).isNull();
            }
        }
    }
}