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

Commit 106bb60b authored by Alex Johnston's avatar Alex Johnston Committed by Android (Google) Code Review
Browse files

Merge "Enterprise exemption for dismissible notificatons"

parents aabd1baa 3ee9c1ea
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1231,6 +1231,7 @@ package android.app.admin {
    field @Deprecated public static final String ACTION_STATE_USER_SETUP_COMPLETE = "android.app.action.STATE_USER_SETUP_COMPLETE";
    field @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP) public static final String ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER = "android.app.action.UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER";
    field public static final int EXEMPT_FROM_APP_STANDBY = 0; // 0x0
    field public static final int EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS = 1; // 0x1
    field public static final String EXTRA_FORCE_UPDATE_ROLE_HOLDER = "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
    field public static final String EXTRA_LOST_MODE_LOCATION = "android.app.extra.LOST_MODE_LOCATION";
    field public static final String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
+12 −1
Original line number Diff line number Diff line
@@ -3876,6 +3876,16 @@ public class DevicePolicyManager {
    @SystemApi
    public static final int EXEMPT_FROM_APP_STANDBY =  0;
    /**
     * Prevent an app from dismissible notifications. Starting from Android U, notifications with
     * the ongoing parameter can be dismissed by a user on an unlocked device. An app with
     * this exemption can create non-dismissable notifications.
     *
     * @hide
     */
    @SystemApi
    public static final int EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS =  1;
    /**
     * Exemptions to platform restrictions, given to an application through
     * {@link #setApplicationExemptions(String, Set)}.
@@ -3883,7 +3893,8 @@ public class DevicePolicyManager {
     * @hide
     */
    @IntDef(prefix = { "EXEMPT_FROM_"}, value = {
            EXEMPT_FROM_APP_STANDBY
            EXEMPT_FROM_APP_STANDBY,
            EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ApplicationExemptionConstants {}
+5 −0
Original line number Diff line number Diff line
@@ -304,4 +304,9 @@ public abstract class DevicePolicyManagerInternal {
     * True if either the entire device or the user is organization managed.
     */
    public abstract boolean isUserOrganizationManaged(@UserIdInt int userId);

    /**
     * Returns whether the application exemptions feature flag is enabled.
     */
    public abstract boolean isApplicationExemptionsFlagEnabled();
}
+16 −4
Original line number Diff line number Diff line
@@ -579,6 +579,8 @@ public class NotificationManagerService extends SystemService {
    private static final boolean ONGOING_DISMISSAL = SystemProperties.getBoolean(
            "persist.sysui.notification.ongoing_dismissal", true);
    @VisibleForTesting
    protected boolean mSystemExemptFromDismissal = false;
    // used as a mutex for access to all active notifications & listeners
    final Object mNotificationLock = new Object();
@@ -2595,6 +2597,8 @@ public class NotificationManagerService extends SystemService {
        mAllowFgsDismissal = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, true);
        mSystemExemptFromDismissal =
                mDpm.isApplicationExemptionsFlagEnabled();
        DeviceConfig.addOnPropertiesChangedListener(
                DeviceConfig.NAMESPACE_SYSTEMUI,
                new HandlerExecutor(mHandler),
@@ -6801,12 +6805,20 @@ public class NotificationManagerService extends SystemService {
        // partition.
        boolean isSystemAppExempt = (ai.flags
                & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0;
        return isSystemAppExempt || notification.isMediaNotification() || isEnterpriseExempted();
        return isSystemAppExempt || notification.isMediaNotification() || isEnterpriseExempted(ai);
    }
    // TODO: b/266237746 Enterprise app exemptions
    private boolean isEnterpriseExempted() {
        return false;
    private boolean isEnterpriseExempted(ApplicationInfo ai) {
        // Check if the app is an organization admin app
        // TODO(b/234609037): Replace with new DPM APIs to check if organization admin
        if (mDpm != null && (mDpm.isActiveProfileOwner(ai.uid)
                || mDpm.isActiveDeviceOwner(ai.uid))) {
            return true;
        }
        // Check if an app has been given system exemption
        return mSystemExemptFromDismissal && mAppOps.checkOpNoThrow(
                AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid,
                ai.packageName) == AppOpsManager.MODE_ALLOWED;
    }
    private void checkRemoteViews(String pkg, String tag, int id, Notification notification) {
+17 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_APP_STANDBY;
import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS;
import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_AFFILIATED;
import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
@@ -55,6 +56,7 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
import static android.app.admin.DevicePolicyManager.EXEMPT_FROM_APP_STANDBY;
import static android.app.admin.DevicePolicyManager.EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_IDS;
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
@@ -703,6 +705,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    static {
        APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.put(
                EXEMPT_FROM_APP_STANDBY, OPSTR_SYSTEM_EXEMPT_FROM_APP_STANDBY);
        APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.put(
                EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS,
                OPSTR_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS);
    }
    /**
@@ -750,6 +755,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    private static final String HEADLESS_FLAG = "headless";
    private static final boolean DEFAULT_HEADLESS_FLAG = true;
    // TODO(b/266831522) remove the flag after rollout.
    private static final String APPLICATION_EXEMPTIONS_FLAG = "application_exemptions";
    private static final boolean DEFAULT_APPLICATION_EXEMPTIONS_FLAG = true;
    /**
     * This feature flag is checked once after boot and this value us used until the next reboot to
     * avoid needing to handle the flag changing on the fly.
@@ -14193,6 +14202,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        public boolean isUserOrganizationManaged(@UserIdInt int userHandle) {
            return getDeviceStateCache().isUserOrganizationManaged(userHandle);
        }
        @Override
        public boolean isApplicationExemptionsFlagEnabled() {
            return DeviceConfig.getBoolean(
                    NAMESPACE_DEVICE_POLICY_MANAGER,
                    APPLICATION_EXEMPTIONS_FLAG,
                    DEFAULT_APPLICATION_EXEMPTIONS_FLAG);
        }
    }
    private Intent createShowAdminSupportIntent(int userId) {
Loading