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

Commit cc23ff14 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Limit priority values used with receiver registrations." into main

parents 6db8acc7 62513b64
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -554,7 +554,7 @@ class BroadcastController {
            }
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,
                    receiverId, permission, callingUid, userId, instantApp, visibleToInstantApps,
                    exported);
                    exported, mService.mPlatformCompat);
            if (rl.containsFilter(filter)) {
                Slog.w(TAG, "Receiver with filter " + filter
                        + " already registered for pid " + rl.pid
+44 −1
Original line number Diff line number Diff line
@@ -17,16 +17,33 @@
package com.android.server.am;

import android.annotation.Nullable;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
import android.content.IntentFilter;
import android.os.UserHandle;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.compat.PlatformCompat;

import dalvik.annotation.optimization.NeverCompile;

import java.io.PrintWriter;

public final class BroadcastFilter extends IntentFilter {
    /**
     * Limit priority values defined by non-system apps to
     * ({@link IntentFilter#SYSTEM_LOW_PRIORITY}, {@link IntentFilter#SYSTEM_HIGH_PRIORITY}).
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
    @Overridable
    @VisibleForTesting
    static final long CHANGE_RESTRICT_PRIORITY_VALUES = 371309185L;

    // Back-pointer to the list this filter is in.
    final ReceiverList receiverList;
    final String packageName;
@@ -38,11 +55,12 @@ public final class BroadcastFilter extends IntentFilter {
    final boolean instantApp;
    final boolean visibleToInstantApp;
    public final boolean exported;
    final int initialPriority;

    BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,
            String _packageName, String _featureId, String _receiverId, String _requiredPermission,
            int _owningUid, int _userId, boolean _instantApp, boolean _visibleToInstantApp,
            boolean _exported) {
            boolean _exported, PlatformCompat platformCompat) {
        super(_filter);
        receiverList = _receiverList;
        packageName = _packageName;
@@ -54,6 +72,8 @@ public final class BroadcastFilter extends IntentFilter {
        instantApp = _instantApp;
        visibleToInstantApp = _visibleToInstantApp;
        exported = _exported;
        initialPriority = getPriority();
        setPriority(calculateAdjustedPriority(owningUid, initialPriority, platformCompat));
    }

    public @Nullable String getReceiverClassName() {
@@ -100,6 +120,29 @@ public final class BroadcastFilter extends IntentFilter {
        if (requiredPermission != null) {
            pw.print(prefix); pw.print("requiredPermission="); pw.println(requiredPermission);
        }
        if (initialPriority != getPriority()) {
            pw.print(prefix); pw.print("initialPriority="); pw.println(initialPriority);
        }
    }

    @VisibleForTesting
    static int calculateAdjustedPriority(int owningUid, int priority,
            PlatformCompat platformCompat) {
        if (!Flags.restrictPriorityValues()) {
            return priority;
        }
        if (!platformCompat.isChangeEnabledByUidInternalNoLogging(
                CHANGE_RESTRICT_PRIORITY_VALUES, owningUid)) {
            return priority;
        }
        if (!UserHandle.isCore(owningUid)) {
            if (priority >= SYSTEM_HIGH_PRIORITY) {
                return SYSTEM_HIGH_PRIORITY - 1;
            } else if (priority <= SYSTEM_LOW_PRIORITY) {
                return SYSTEM_LOW_PRIORITY + 1;
            }
        }
        return priority;
    }

    public String toString() {
+8 −0
Original line number Diff line number Diff line
@@ -233,3 +233,11 @@ flag {
    description: "Assign cached oom_score_adj in tiers."
    bug: "369893532"
}

flag {
    name: "restrict_priority_values"
    namespace: "backstage_power"
    description: "Restrict priority values defined by non-system apps"
    is_fixed_read_only: true
    bug: "369487976"
}
+5 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;

import android.annotation.NonNull;
@@ -52,11 +53,11 @@ import com.android.server.AlarmManagerInternal;
import com.android.server.DropBoxManagerInternal;
import com.android.server.LocalServices;
import com.android.server.appop.AppOpsService;
import com.android.server.compat.PlatformCompat;
import com.android.server.wm.ActivityTaskManagerService;

import org.junit.Rule;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.io.File;
@@ -164,7 +165,7 @@ public abstract class BaseBroadcastQueueTest {
        realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
        realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper());
        realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal());
        realAms.mOomAdjuster.mCachedAppOptimizer = Mockito.mock(CachedAppOptimizer.class);
        realAms.mOomAdjuster.mCachedAppOptimizer = mock(CachedAppOptimizer.class);
        realAms.mOomAdjuster = spy(realAms.mOomAdjuster);
        ExtendedMockito.doNothing().when(() -> ProcessList.setOomAdj(anyInt(), anyInt(), anyInt()));
        realAms.mPackageManagerInt = mPackageManagerInt;
@@ -286,7 +287,8 @@ public abstract class BaseBroadcastQueueTest {
        filter.setPriority(priority);
        final BroadcastFilter res = new BroadcastFilter(filter, receiverList,
                receiverList.app.info.packageName, null, null, null, receiverList.uid,
                receiverList.userId, false, false, true);
                receiverList.userId, false, false, true,
                mock(PlatformCompat.class));
        receiverList.add(res);
        return res;
    }
+220 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.am;

import static android.content.IntentFilter.SYSTEM_HIGH_PRIORITY;
import static android.content.IntentFilter.SYSTEM_LOW_PRIORITY;

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

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;

import android.os.Process;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Pair;

import androidx.test.filters.SmallTest;

import com.android.server.compat.PlatformCompat;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@SmallTest
public class BroadcastFilterTest {
    private static final int TEST_APP_UID = Process.FIRST_APPLICATION_UID + 42;

    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Mock
    PlatformCompat mPlatformCompat;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    @EnableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES)
    public void testCalculateAdjustedPriority() {
        doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging(
                eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt());

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForSystemUid(priorityPair.first, priorityPair.second);
            }
        }

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY - 1),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY + 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY - 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY + 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForAppUid(priorityPair.first, priorityPair.second);
            }
        }
    }

    @Test
    @EnableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES)
    public void testCalculateAdjustedPriority_withChangeIdDisabled() {
        doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging(
                eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt());

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForSystemUid(priorityPair.first, priorityPair.second);
            }
        }

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForAppUid(priorityPair.first, priorityPair.second);
            }
        }
    }

    @Test
    @DisableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES)
    public void testCalculateAdjustedPriority_withFlagDisabled() {
        doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging(
                eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt());

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForSystemUid(priorityPair.first, priorityPair.second);
            }
        }

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForAppUid(priorityPair.first, priorityPair.second);
            }
        }
    }

    @Test
    @DisableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES)
    public void testCalculateAdjustedPriority_withFlagDisabled_withChangeIdDisabled() {
        doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging(
                eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt());

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForSystemUid(priorityPair.first, priorityPair.second);
            }
        }

        {
            // Pairs of {initial-priority, expected-adjusted-priority}
            final Pair<Integer, Integer>[] priorities = new Pair[] {
                    Pair.create(SYSTEM_HIGH_PRIORITY, SYSTEM_HIGH_PRIORITY),
                    Pair.create(SYSTEM_LOW_PRIORITY, SYSTEM_LOW_PRIORITY),
                    Pair.create(SYSTEM_HIGH_PRIORITY + 1, SYSTEM_HIGH_PRIORITY + 1),
                    Pair.create(SYSTEM_LOW_PRIORITY - 1, SYSTEM_LOW_PRIORITY - 1),
                    Pair.create(SYSTEM_HIGH_PRIORITY - 2, SYSTEM_HIGH_PRIORITY - 2),
                    Pair.create(SYSTEM_LOW_PRIORITY + 2, SYSTEM_LOW_PRIORITY + 2)
            };
            for (Pair<Integer, Integer> priorityPair : priorities) {
                assertAdjustedPriorityForAppUid(priorityPair.first, priorityPair.second);
            }
        }
    }

    private void assertAdjustedPriorityForSystemUid(int priority, int expectedAdjustedPriority) {
        assertAdjustedPriority(Process.SYSTEM_UID, priority, expectedAdjustedPriority);
    }

    private void assertAdjustedPriorityForAppUid(int priority, int expectedAdjustedPriority) {
        assertAdjustedPriority(TEST_APP_UID, priority, expectedAdjustedPriority);
    }

    private void assertAdjustedPriority(int owningUid, int priority, int expectedAdjustedPriority) {
        final String errorMsg = String.format("owner=%d; actualPriority=%d; expectedPriority=%d",
                owningUid, priority, expectedAdjustedPriority);
        assertWithMessage(errorMsg).that(BroadcastFilter.calculateAdjustedPriority(
                owningUid, priority, mPlatformCompat)).isEqualTo(expectedAdjustedPriority);
    }
}