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

Commit 499f005e authored by Pavel Grafov's avatar Pavel Grafov
Browse files

Add DPM methods to allow org owned PO to suspend personal apps

* When personal apps are suspended, only dialer, IMEs, a11y, launcher
  are some other critical apps are exempted.
* User is presented with notification, clicking on which invokes an
  activity in the DPC.

Bug: 147414651
Test: manual via TestDPC
Change-Id: I09f8dad08e54b0ce8201cd5c76b3f34342e0da8f
parent b3191a33
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -6853,6 +6853,7 @@ package android.app.admin {
    method @Nullable public java.util.List<java.lang.String> getPermittedAccessibilityServices(@NonNull android.content.ComponentName);
    method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName);
    method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName);
    method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName);
    method @NonNull public java.util.List<java.lang.String> getProtectedPackages(@NonNull android.content.ComponentName);
    method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName);
    method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName);
@@ -6979,6 +6980,7 @@ package android.app.admin {
    method public boolean setPermittedAccessibilityServices(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
    method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
    method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
    method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
    method public void setProfileEnabled(@NonNull android.content.ComponentName);
    method public void setProfileName(@NonNull android.content.ComponentName, String);
    method public void setProtectedPackages(@NonNull android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
@@ -7014,6 +7016,7 @@ package android.app.admin {
    field public static final String ACTION_ADMIN_POLICY_COMPLIANCE = "android.app.action.ADMIN_POLICY_COMPLIANCE";
    field public static final String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
    field public static final String ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE = "android.app.action.BIND_SECONDARY_LOCKSCREEN_SERVICE";
    field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
    field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
    field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
    field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
@@ -7137,6 +7140,8 @@ package android.app.admin {
    field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
    field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
    field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
    field public static final int PERSONAL_APPS_NOT_SUSPENDED = 0; // 0x0
    field public static final int PERSONAL_APPS_SUSPENDED_EXPLICITLY = 1; // 0x1
    field public static final String POLICY_DISABLE_CAMERA = "policy_disable_camera";
    field public static final String POLICY_DISABLE_SCREEN_CAPTURE = "policy_disable_screen_capture";
    field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1
+78 −0
Original line number Diff line number Diff line
@@ -2390,6 +2390,28 @@ public class DevicePolicyManager {
    public static final String ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE =
            "android.app.action.BIND_SECONDARY_LOCKSCREEN_SERVICE";
    /**
     * Return value for {@link #getPersonalAppsSuspendedReasons} when personal apps are not
     * suspended.
     */
    public static final int PERSONAL_APPS_NOT_SUSPENDED = 0;
    /**
     * Flag for {@link #getPersonalAppsSuspendedReasons} return value. Set when personal
     * apps are suspended by an admin explicitly via {@link #setPersonalAppsSuspended}.
     */
    public static final int PERSONAL_APPS_SUSPENDED_EXPLICITLY = 1 << 0;
    /**
     * @hide
     */
    @IntDef(flag = true, prefix = { "PERSONAL_APPS_" }, value = {
            PERSONAL_APPS_NOT_SUSPENDED,
            PERSONAL_APPS_SUSPENDED_EXPLICITLY
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PersonalAppSuspensionReason {}
    /**
     * Return true if the given administrator component is currently active (enabled) in the system.
     *
@@ -4565,6 +4587,18 @@ public class DevicePolicyManager {
    public static final String ACTION_START_ENCRYPTION
            = "android.app.action.START_ENCRYPTION";
    /**
     * Activity action: launch the DPC to check policy compliance. This intent is launched when
     * the user taps on the notification about personal apps suspension. When handling this intent
     * the DPC must check if personal apps should still be suspended and either unsuspend them or
     * instruct the user on how to resolve the noncompliance causing the suspension.
     *
     * @see #setPersonalAppsSuspended
     */
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_CHECK_POLICY_COMPLIANCE =
            "android.app.action.CHECK_POLICY_COMPLIANCE";
    /**
     * Broadcast action: notify managed provisioning that new managed user is created.
     *
@@ -11650,4 +11684,48 @@ public class DevicePolicyManager {
        }
        return false;
    }
    /**
     * Called by profile owner of an organization-owned managed profile to check whether
     * personal apps are suspended.
     *
     * @return a bitmask of reasons for personal apps suspension or
     *     {@link #PERSONAL_APPS_NOT_SUSPENDED} if apps are not suspended.
     * @see #setPersonalAppsSuspended
     */
    public @PersonalAppSuspensionReason int getPersonalAppsSuspendedReasons(
            @NonNull ComponentName admin) {
        throwIfParentInstance("getPersonalAppsSuspendedReasons");
        if (mService != null) {
            try {
                return mService.getPersonalAppsSuspendedReasons(admin);
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }
        }
        return 0;
    }
    /**
     * Called by a profile owner of an organization-owned managed profile to suspend personal
     * apps on the device. When personal apps are suspended the device can only be used for calls.
     *
     * <p>When personal apps are suspended, an ongoing notification about that is shown to the user.
     * When the user taps the notification, system invokes {@link #ACTION_CHECK_POLICY_COMPLIANCE}
     * in the profile owner package. Profile owner implementation that uses personal apps suspension
     * must handle this intent.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with
     * @param suspended Whether personal apps should be suspended.
     */
    public void setPersonalAppsSuspended(@NonNull ComponentName admin, boolean suspended) {
        throwIfParentInstance("setPersonalAppsSuspended");
        if (mService != null) {
            try {
                mService.setPersonalAppsSuspended(admin, suspended);
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -470,4 +470,7 @@ interface IDevicePolicyManager {

    void setCommonCriteriaModeEnabled(in ComponentName admin, boolean enabled);
    boolean isCommonCriteriaModeEnabled(in ComponentName admin);

    int getPersonalAppsSuspendedReasons(in ComponentName admin);
    void setPersonalAppsSuspended(in ComponentName admin, boolean suspended);
}
+7 −0
Original line number Diff line number Diff line
@@ -4326,6 +4326,13 @@
         generation). -->
    <bool name="config_customBugreport">false</bool>

    <!-- Names of packages that should not be suspended when personal use is blocked by policy. -->
    <string-array name="config_packagesExemptFromSuspension" translatable="false">
        <!-- Add packages here, example: -->
        <!-- <item>com.android.settings</item> -->
    </string-array>


    <!-- Class name of the custom country detector to be used. -->
    <string name="config_customCountryDetector" translatable="false">com.android.server.location.ComprehensiveCountryDetector</string>

+6 −0
Original line number Diff line number Diff line
@@ -425,6 +425,12 @@
    <!-- A toast message displayed when printing is attempted but disabled by policy. -->
    <string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string>

    <!-- Content title for a notification that personal apps are suspended [CHAR LIMIT=NONE] -->
    <string name="personal_apps_suspended_notification_title">Personal apps have been suspended by an admin</string>

    <!-- Message for a notification about personal apps suspension when work profile is off. [CHAR LIMIT=NONE] -->
    <string name="personal_apps_suspended_notification_text">Tap here to check policy compliance.</string>

    <!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
    <string name="me">Me</string>

Loading