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

Commit 252ed3de authored by Hani Kazmi's avatar Hani Kazmi Committed by Android (Google) Code Review
Browse files

Merge "Add feature flag and toasts for ASM"

parents ed98ef8d ad56407a
Loading
Loading
Loading
Loading
+114 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.wm;

import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;

import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS;

import android.annotation.NonNull;
import android.app.compat.CompatChanges;
import android.content.pm.PackageManager;
import android.provider.DeviceConfig;

import com.android.internal.annotations.GuardedBy;

import java.util.HashSet;
import java.util.concurrent.Executor;

/**
 * Contains utility methods to query whether or not go/activity-security should be enabled
 * asm_start_rules_enabled - Enable rule enforcement in ActivityStarter.java
 * asm_start_rules_toasts_enabled - Show toasts when rules would block from ActivityStarter.java
 * asm_start_rules_exception_list - Comma separated list of packages to exclude from the above
 * 2 rules.
 * TODO(b/258792202) Cleanup once ASM is ready to launch
 */
class ActivitySecurityModelFeatureFlags {
    // TODO(b/230590090): Replace with public documentation once ready
    static final String DOC_LINK = "go/android-asm";

    private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER;
    private static final String KEY_ASM_RESTRICTIONS_ENABLED = "asm_restrictions_enabled";
    private static final String KEY_ASM_TOASTS_ENABLED = "asm_toasts_enabled";
    private static final String KEY_ASM_EXEMPTED_PACKAGES = "asm_exempted_packages";
    private static final int VALUE_DISABLE = 0;
    private static final int VALUE_ENABLE_FOR_U = 1;
    private static final int VALUE_ENABLE_FOR_ALL = 2;

    private static final int DEFAULT_VALUE = VALUE_DISABLE;
    private static final String DEFAULT_EXCEPTION_LIST = "";

    private static int sAsmToastsEnabled;
    private static int sAsmRestrictionsEnabled;
    private static final HashSet<String> sExcludedPackageNames = new HashSet<>();
    private static PackageManager sPm;

    @GuardedBy("ActivityTaskManagerService.mGlobalLock")
    static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) {
        updateFromDeviceConfig();
        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor,
                properties -> updateFromDeviceConfig());
        sPm = pm;
    }

    @GuardedBy("ActivityTaskManagerService.mGlobalLock")
    static boolean shouldShowToast(int uid) {
        return flagEnabledForUid(sAsmToastsEnabled, uid);
    }

    @GuardedBy("ActivityTaskManagerService.mGlobalLock")
    static boolean shouldBlockActivityStart(int uid) {
        return flagEnabledForUid(sAsmRestrictionsEnabled, uid);
    }

    private static boolean flagEnabledForUid(int flag, int uid) {
        boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL
                || (flag == VALUE_ENABLE_FOR_U
                    && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid));

        if (flagEnabled) {
            String[] packageNames = sPm.getPackagesForUid(uid);
            for (int i = 0; i < packageNames.length; i++) {
                if (sExcludedPackageNames.contains(packageNames[i])) {
                    return false;
                }
            }
            return true;
        }

        return false;
    }

    private static void updateFromDeviceConfig() {
        sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED,
                DEFAULT_VALUE);
        sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED,
                DEFAULT_VALUE);

        String rawExceptionList = DeviceConfig.getString(NAMESPACE,
                KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST);
        sExcludedPackageNames.clear();
        String[] packages = rawExceptionList.split(",");
        for (String packageName : packages) {
            String packageNameTrimmed = packageName.trim();
            if (!packageNameTrimmed.isEmpty()) {
                sExcludedPackageNames.add(packageNameTrimmed);
            }
        }
    }
}
+33 −7
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.text.TextUtils;
import android.util.Pools.SynchronizedPool;
import android.util.Slog;
import android.widget.Toast;
import android.window.RemoteTransition;

import com.android.internal.annotations.VisibleForTesting;
@@ -132,6 +133,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.UiThread;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.power.ShutdownCheckPoints;
@@ -168,6 +170,13 @@ class ActivityStarter {
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L;

    /**
     * Feature flag for go/activity-security rules
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    static final long ASM_RESTRICTIONS = 230590090L;

    private final ActivityTaskManagerService mService;
    private final RootWindowContainer mRootWindowContainer;
    private final ActivityTaskSupervisor mSupervisor;
@@ -1859,7 +1868,7 @@ class ActivityStarter {
        }

        if (!checkActivitySecurityModel(r, newTask, targetTask)) {
            return START_SUCCESS;
            return START_ABORTED;
        }

        return START_SUCCESS;
@@ -1925,11 +1934,6 @@ class ActivityStarter {
                : targetTask.getActivity(ar ->
                        !ar.isState(FINISHING) && !ar.isAlwaysOnTop());

        Slog.i(TAG, "Launching r: " + r
                + " from background: " + mSourceRecord
                + ". New task: " + newTask
                + ". Top activity: " + targetTopActivity);

        int action = newTask || mSourceRecord == null
                ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK
                : (mSourceRecord.getTask().equals(targetTask)
@@ -1965,9 +1969,31 @@ class ActivityStarter {
                        && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible()
        );

        boolean shouldBlockActivityStart =
                ActivitySecurityModelFeatureFlags.shouldBlockActivityStart(mCallingUid);

        if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) {
            UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
                    (shouldBlockActivityStart
                            ? "Activity start blocked by "
                            : "Activity start would be blocked by ")
                            + ActivitySecurityModelFeatureFlags.DOC_LINK,
                    Toast.LENGTH_SHORT).show());
        }


        if (shouldBlockActivityStart) {
            Slog.e(TAG, "Abort Launching r: " + r
                    + " as source: " + mSourceRecord
                    + "is in background. New task: " + newTask
                    + ". Top activity: " + targetTopActivity);

            return false;
        }

        return true;
    }

    /**
     * Returns whether embedding of {@code starting} is allowed.
     *
+2 −0
Original line number Diff line number Diff line
@@ -859,6 +859,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mRecentTasks.onSystemReadyLocked();
            mTaskSupervisor.onSystemReady();
            mActivityClientController.onSystemReady();
            // TODO(b/258792202) Cleanup once ASM is ready to launch
            ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor(), pm);
        }
    }