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

Commit bbc89853 authored by d34d's avatar d34d Committed by Gerrit Code Review
Browse files

Keyguard: Third party keyguard support

Enables support for third party keyguards.  Currently for use with
the themable animated lock screen.

This is currently only for system apps or apps signed with the same
key as the system.

Change-Id: Ifcbf9368d951da3ea7ab8e6205d08acb078d8e5d
parent be1fa864
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -604,6 +604,14 @@ public class DevicePolicyManager {
     */
    public static final int PASSWORD_QUALITY_UNSPECIFIED = 0;

    /**
     * Constant for {@link #setPasswordQuality}: the policy has no requirements
     * for the password.  Used for launching a 3rd party lock screen such as the animated lock
     * screen.  Note that quality constants are ordered so that higher values are more restrictive.
     * @hide
     */
    public static final int PASSWORD_THIRD_PARTY_UNSECURED = 0x800;

    /**
     * Constant for {@link #setPasswordQuality}: the policy allows for low-security biometric
     * recognition technology.  This implies technologies that can recognize the identity of
+63 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.AsyncTask;
@@ -159,6 +160,14 @@ public class LockPatternUtils {

    public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";

    /**
     * Component to start when
     * {@link android.app.admin.DevicePolicyManager#PASSWORD_THIRD_PARTY_UNSECURED} is used as
     * the keyguard.
     * @hide
     */
    public static final String THIRD_PARTY_KEYGUARD_COMPONENT = "lockscreen.third_party";

    private static final String LOCK_SCREEN_OWNER_INFO = Settings.Secure.LOCK_SCREEN_OWNER_INFO;
    private static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
            Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
@@ -496,6 +505,10 @@ public class LockPatternUtils {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
                }
                break;
            case DevicePolicyManager.PASSWORD_THIRD_PARTY_UNSECURED:
                if (isThirdPartyKeyguardEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_THIRD_PARTY_UNSECURED;
                }
        }

        return activePasswordQuality;
@@ -955,6 +968,42 @@ public class LockPatternUtils {
        }
    }

    /**
     * Sets a third party lock screen.
     * @param component
     */
    public void setThirdPartyKeyguard(ComponentName component)
            throws PackageManager.NameNotFoundException {
        if (component != null) {
            // Check that the package this component belongs to has the third party keyguard perm
            final PackageManager pm = mContext.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(component.getPackageName(),
                    PackageManager.GET_PERMISSIONS);
            boolean hasThirdPartyKeyguardPermission = false;
            for (String perm : pi.requestedPermissions) {
                if (Manifest.permission.THIRD_PARTY_KEYGUARD.equals(perm)) {
                    hasThirdPartyKeyguardPermission = true;
                    break;
                }
            }
            if (!hasThirdPartyKeyguardPermission) {
                throw new SecurityException("Package " + component.getPackageName() + " does not" +
                        "have " + Manifest.permission.THIRD_PARTY_KEYGUARD);
            }
        }

        setString(THIRD_PARTY_KEYGUARD_COMPONENT,
                component != null ? component.flattenToString() : "");
        setLong(PASSWORD_TYPE_KEY,
                component != null ? DevicePolicyManager.PASSWORD_THIRD_PARTY_UNSECURED :
                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
    }

    public ComponentName getThirdPartyKeyguardComponent() {
        String component = getString(THIRD_PARTY_KEYGUARD_COMPONENT);
        return component != null ? ComponentName.unflattenFromString(component) : null;
    }

    /**
     * Gets whether the device is encrypted.
     *
@@ -1307,6 +1356,16 @@ public class LockPatternUtils {
        return false;
    }

    /**
     * @return Whether a third party keyguard is set
     */
    public boolean isThirdPartyKeyguardEnabled() {
        String component = getString(THIRD_PARTY_KEYGUARD_COMPONENT);
        long type = getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
        return !TextUtils.isEmpty(component) &&
                type == DevicePolicyManager.PASSWORD_THIRD_PARTY_UNSECURED;
    }

    /**
     * Set whether biometric weak liveliness is enabled.
     */
@@ -1697,6 +1756,10 @@ public class LockPatternUtils {
        }
    }

    private void setString(String secureSettingKey, String value) {
        setString(secureSettingKey, value, getCurrentOrCallingUserId());
    }

    private void setString(String secureSettingKey, String value, int userHandle) {
        try {
            getLockSettings().setString(secureSettingKey, value, userHandle);
+7 −0
Original line number Diff line number Diff line
@@ -3082,6 +3082,13 @@
         android:description="@string/permdesc_accessFingerprintService"
         android:protectionLevel="system|signature" />

    <!-- Allows an application to be used as a third party keyguard
         @hide -->
    <permission android:name="android.permission.THIRD_PARTY_KEYGUARD"
        android:label="@string/permlab_thirdPartyKeyguard"
        android:description="@string/permdesc_thirdPartyKeyguard"
        android:protectionLevel="system|signature" />

    <!-- The system process is explicitly the only one allowed to launch the
         confirmation UI for full backup/restore -->
    <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
+6 −0
Original line number Diff line number Diff line
@@ -351,4 +351,10 @@

    <!-- WiFi turn off notification action text -->
    <string name="notify_turn_wifi_off_title">Turn Wi-Fi off</string>

    <!-- Third party keyguard permission label -->
    <string name="permlab_thirdPartyKeyguard">third party lock screen</string>
    <!-- Third party keyguard permission description -->
    <string name="permdesc_thirdPartyKeyguard">Allows an app to be used as an insecure lock screen.</string>

</resources>
+16 −9
Original line number Diff line number Diff line
@@ -113,26 +113,30 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe

    @Override
    public void onResume(int reason) {
        if (mCurrentSecuritySelection != SecurityMode.None) {
        if (mCurrentSecuritySelection != SecurityMode.None &&
                mCurrentSecuritySelection != SecurityMode.ThirdParty) {
            getSecurityView(mCurrentSecuritySelection).onResume(reason);
        }
    }

    @Override
    public void onPause() {
        if (mCurrentSecuritySelection != SecurityMode.None) {
        if (mCurrentSecuritySelection != SecurityMode.None &&
                mCurrentSecuritySelection != SecurityMode.ThirdParty) {
            getSecurityView(mCurrentSecuritySelection).onPause();
        }
    }

    public void startAppearAnimation() {
        if (mCurrentSecuritySelection != SecurityMode.None) {
        if (mCurrentSecuritySelection != SecurityMode.None &&
                mCurrentSecuritySelection != SecurityMode.ThirdParty) {
            getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
        }
    }

    public boolean startDisappearAnimation(Runnable onFinishRunnable) {
        if (mCurrentSecuritySelection != SecurityMode.None) {
        if (mCurrentSecuritySelection != SecurityMode.None &&
                mCurrentSecuritySelection != SecurityMode.ThirdParty) {
            return getSecurityView(mCurrentSecuritySelection).startDisappearAnimation(
                    onFinishRunnable);
        }
@@ -471,11 +475,12 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
        boolean finish = false;
        if (mUpdateMonitor.getUserHasTrust(mLockPatternUtils.getCurrentUser())) {
            finish = true;
        } else if (SecurityMode.None == mCurrentSecuritySelection) {
        } else if (SecurityMode.None == mCurrentSecuritySelection ||
                SecurityMode.ThirdParty == mCurrentSecuritySelection) {
            SecurityMode securityMode = mSecurityModel.getSecurityMode();
            // Allow an alternate, such as biometric unlock
            securityMode = mSecurityModel.getAlternateFor(securityMode);
            if (SecurityMode.None == securityMode) {
            if (SecurityMode.None == securityMode || SecurityMode.ThirdParty == securityMode) {
                finish = true; // no security required
            } else {
                showSecurityScreen(securityMode); // switch to the alternate security view
@@ -494,7 +499,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
                case SimPuk:
                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
                    if (securityMode != SecurityMode.None) {
                    if (securityMode != SecurityMode.None &&
                            securityMode != SecurityMode.ThirdParty) {
                        showSecurityScreen(securityMode);
                    } else {
                        finish = true;
@@ -532,7 +538,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
            oldView.onPause();
            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
        }
        if (securityMode != SecurityMode.None) {
        if (securityMode != SecurityMode.None && securityMode != SecurityMode.ThirdParty) {
            newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
            newView.setKeyguardCallback(mCallback);
        }
@@ -550,7 +556,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe

        mCurrentSecuritySelection = securityMode;
        mSecurityCallback.onSecurityModeChanged(securityMode,
                securityMode != SecurityMode.None && newView.needsInput());
                securityMode != SecurityMode.None && securityMode != SecurityMode.ThirdParty &&
                        newView.needsInput());
    }

    private KeyguardSecurityViewFlipper getFlipper() {
Loading