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

Commit 2418ea97 authored by Alex Kershaw's avatar Alex Kershaw
Browse files

Add isManagedKiosk system APIs.

Add system APIs isManagedKiosk and isUnattendedManagedKiosk. These will
be defined in the CDD.

The intention is to have privacy and security-approved definitions that
future features (removing user consent dialogs, stronger APIs) can use
specifically for publicly-accessible dedicated devices.

We use 'kiosk' rather than 'publicly-accessible dedicated device' for
ease-of-use, which is actually consistent with ChromeOS.

Bug: 111384878
Test: Each use will have its own CTS tests. The definitions themselves
will be in CDD. Currently tested by calling the methods in TestDPC.
Change-Id: If080a3b9dae285bc28823e6004750908009130d2
parent 8ec0e5ce
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -597,6 +597,8 @@ package android.app.admin {
    method public boolean isDeviceManaged();
    method public boolean isDeviceProvisioned();
    method public boolean isDeviceProvisioningConfigApplied();
    method public boolean isManagedKiosk();
    method public boolean isUnattendedManagedKiosk();
    method public void notifyPendingSystemUpdate(long);
    method public void notifyPendingSystemUpdate(long, boolean);
    method public boolean packageHasActiveAdmins(java.lang.String);
+69 −0
Original line number Diff line number Diff line
@@ -10239,4 +10239,73 @@ public class DevicePolicyManager {
        }
        return Collections.emptySet();
    }

    /**
     * Returns whether the device is being used as a managed kiosk, as defined in the CDD. As of
     * this release, these requirements are as follows:
     * <ul>
     *     <li>The device is in Lock Task (therefore there is also a Device Owner app on the
     *     device)</li>
     *     <li>The Lock Task feature {@link DevicePolicyManager#LOCK_TASK_FEATURE_SYSTEM_INFO} is
     *     not enabled, so the system info in the status bar is not visible</li>
     *     <li>The device does not have a secure lock screen (e.g. it has no lock screen or has
     *     swipe-to-unlock)</li>
     *     <li>The device is not in the middle of an ephemeral user session</li>
     * </ul>
     *
     * <p>Publicly-accessible dedicated devices don't have the same privacy model as
     * personally-used devices. In particular, user consent popups don't make sense as a barrier to
     * accessing persistent data on these devices since the user giving consent and the user whose
     * data is on the device are unlikely to be the same. These consent popups prevent the true
     * remote management of these devices.
     *
     * <p>This condition is not sufficient to cover APIs that would access data that only lives for
     * the duration of the user's session, since the user has an expectation of privacy in these
     * conditions that more closely resembles use of a personal device. In those cases, see {@link
     * #isUnattendedManagedKiosk()}.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
    public boolean isManagedKiosk() {
        throwIfParentInstance("isManagedKiosk");
        if (mService != null) {
            try {
                return mService.isManagedKiosk();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return false;
    }

    /**
     * Returns whether the device is being used as an unattended managed kiosk, as defined in the
     * CDD. As of this release, these requirements are as follows:
     * <ul>
     *     <li>The device is being used as a managed kiosk, as defined in the CDD and verified at
     *     {@link #isManagedKiosk()}</li>
     *     <li>The device has not received user input for at least 30 minutes</li>
     * </ul>
     *
     * <p>See {@link #isManagedKiosk()} for context. This is a stronger requirement that also
     * ensures that the device hasn't been interacted with recently, making it an appropriate check
     * for privacy-sensitive APIs that wouldn't be appropriate during an active user session.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
    public boolean isUnattendedManagedKiosk() {
        throwIfParentInstance("isUnattendedManagedKiosk");
        if (mService != null) {
            try {
                return mService.isUnattendedManagedKiosk();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return false;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -428,4 +428,7 @@ interface IDevicePolicyManager {
    List<String> getCrossProfileCalendarPackages(in ComponentName admin);
    boolean isPackageAllowedToAccessCalendarForUser(String packageName, int userHandle);
    List<String> getCrossProfileCalendarPackagesForUser(int userHandle);

    boolean isManagedKiosk();
    boolean isUnattendedManagedKiosk();
}
+3 −0
Original line number Diff line number Diff line
@@ -200,4 +200,7 @@ public abstract class PowerManagerInternal {
     * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h
     */
    public abstract void powerHint(int hintId, int data);

    /** Returns whether there hasn't been a user activity event for the given number of ms. */
    public abstract boolean wasDeviceIdleFor(long ms);
}
+19 −0
Original line number Diff line number Diff line
@@ -3221,6 +3221,20 @@ public final class PowerManagerService extends SystemService
        mNativeWrapper.nativeSendPowerHint(hintId, data);
    }

    @VisibleForTesting
    boolean wasDeviceIdleForInternal(long ms) {
        synchronized (mLock) {
            return mLastUserActivityTime + ms < SystemClock.uptimeMillis();
        }
    }

    @VisibleForTesting
    void onUserActivity() {
        synchronized (mLock) {
            mLastUserActivityTime = SystemClock.uptimeMillis();
        }
    }

    /**
     * Low-level function turn the device off immediately, without trying
     * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
@@ -4874,5 +4888,10 @@ public final class PowerManagerService extends SystemService
        public void powerHint(int hintId, int data) {
            powerHintInternal(hintId, data);
        }

        @Override
        public boolean wasDeviceIdleFor(long ms) {
            return wasDeviceIdleForInternal(ms);
        }
    }
}
Loading