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

Commit 4d7cee1e authored by Brian Colonna's avatar Brian Colonna
Browse files

Properly laying out FaceLock on lockscreen

- FaceLock area now specified in layout files instead of trying to
  grab an existing view, which was only practical if pattern was
  backup method

- Now fills area it is supposed to and works with pin as well as
  pattern backup

- Backup method is no longer exposed behind FaceLock just before it
  starts or just after it tells the lockscreen to unlock

- Added synchronized blocks so FaceLock cannot be told to stopUI by
  two different threads at the same time

Change-Id: I3bfad6b44dbe0e3c2ea3c87d2978451c22a7484c
parent 62bb0cdc
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -178,4 +178,17 @@
        android:layout_height="0dip"
        />

    <!-- Area to overlay FaceLock -->
    <TextView android:id="@+id/faceLockAreaView"
        android:visibility="gone"
        android:layout_row="3"
        android:layout_column="0"
        android:layout_rowSpan="2"
        android:layout_columnSpan="1"
        android:layout_gravity="fill"
        android:layout_width="0dip"
        android:layout_height="0dip"
        android:background="@color/facelock_color_background"
    />

</GridLayout>
+15 −0
Original line number Diff line number Diff line
@@ -171,4 +171,19 @@
        android:layout_height="0dip"
        />

    <!-- Area to overlay FaceLock -->
    <TextView android:id="@+id/faceLockAreaView"
        android:visibility="gone"
        android:layout_row="4"
        android:layout_column="0"
        android:layout_rowSpan="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_width="0dip"
        android:layout_height="0dip"
        android:background="@color/facelock_color_background"
    />

</GridLayout>
+3 −0
Original line number Diff line number Diff line
@@ -112,6 +112,9 @@
    <color name="lockscreen_clock_am_pm">#ff9a9a9a</color>
    <color name="lockscreen_owner_info">#ff9a9a9a</color>

    <!-- FaceLock -->
    <color name="facelock_color_background">#000000</color>

    <!-- For holo theme -->
      <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
      <drawable name="screen_background_holo_dark">#ff000000</drawable>
+84 −34
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -74,7 +76,7 @@ import java.io.IOException;
 * {@link com.android.internal.policy.impl.KeyguardViewManager}
 * via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate.
 */
public class LockPatternKeyguardView extends KeyguardViewBase {
public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback {

    private static final int TRANSPORT_USERACTIVITY_TIMEOUT = 10000;

@@ -103,9 +105,15 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
    // The following were added to support FaceLock
    private IFaceLockInterface mFaceLockService;
    private boolean mBoundToFaceLockService = false;
    private boolean mFaceLockServiceRunning = false;
    private View mFaceLockAreaView;

    private boolean mFaceLockServiceRunning = false;
    private final Object mFaceLockServiceRunningLock = new Object();

    private Handler mHandler;
    private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
    private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;

    /**
     * The current {@link KeyguardScreen} will use this to communicate back to us.
     */
@@ -244,6 +252,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
            KeyguardWindowController controller) {
        super(context);

        mHandler = new Handler(this);
        mConfiguration = context.getResources().getConfiguration();
        mEnableFallback = false;
        mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
@@ -704,12 +713,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
                    mKeyguardScreenCallback,
                    mUpdateMonitor.getFailedAttempts());
            view.setEnableFallback(mEnableFallback);

            // TODO(bcolonna): For pattern unlock, it can give us the view where the pattern is
            // displayed and FaceLock can draw in that area.
            // For other views it's not so simple and we should probably change how the FaceLock
            // area is determined.
            mFaceLockAreaView = view.getUnlockAreaView();
            unlockView = view;
        } else if (unlockMode == UnlockMode.SimPuk) {
            unlockView = new SimPukUnlockScreen(
@@ -759,6 +762,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
            throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
        }
        initializeTransportControlView(unlockView);
        initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled

        mUnlockScreenMode = unlockMode;
        return unlockView;
    }
@@ -938,6 +943,41 @@ public class LockPatternKeyguardView extends KeyguardViewBase {

    // Everything below pertains to FaceLock - might want to separate this out

    // Only pattern and pin unlock screens actually have a view for the FaceLock area, so it's not
    // uncommon for it to not exist.  But if it does exist, we need to make sure it's showing if
    // FaceLock is enabled, and make sure it's not showing if FaceLock is disabled
    private void initializeFaceLockAreaView(View view) {
        mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
        if (mFaceLockAreaView == null) {
            if (DEBUG) Log.d(TAG, "Layout does not have faceLockAreaView");
        } else {
            if (mLockPatternUtils.usingBiometricWeak()) {
                mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
            } else {
                mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
            }
        }
    }

    // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
    // This needs to be done in a handler because the call could be coming from a callback from the
    // FaceLock service that is in a thread that can't modify the UI
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_SHOW_FACELOCK_AREA_VIEW:
            mFaceLockAreaView.setVisibility(View.VISIBLE);
            break;
        case MSG_HIDE_FACELOCK_AREA_VIEW:
            mFaceLockAreaView.setVisibility(View.GONE);
            break;
        default:
            Log.w(TAG, "Unhandled message");
            return false;
        }
        return true;
    }

    // Binds to FaceLock service, but does not tell it to start
    public void bindToFaceLock() {
        if (mLockPatternUtils.usingBiometricWeak()) {
@@ -986,23 +1026,20 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
                throw new RuntimeException("Remote exception");
            }

            // TODO(bcolonna): Need to set location properly (only works for pattern view now)
            if (mFaceLockAreaView != null) {
                int[] unlockLocationOnScreen = new int[2];
                mFaceLockAreaView.getLocationOnScreen(unlockLocationOnScreen);
                int x = unlockLocationOnScreen[0];
                int y = unlockLocationOnScreen[1];
                int w = mFaceLockAreaView.getWidth();
                int h = mFaceLockAreaView.getHeight();
                if (DEBUG) Log.d(TAG, "(x,y) (wxh): (" + x + "," + y + ") (" + w + "x" + h + ")");
                startFaceLock(mFaceLockAreaView.getWindowToken(), x, y, w, h);
                startFaceLock(mFaceLockAreaView.getWindowToken(),
                        mFaceLockAreaView.getLeft(), mFaceLockAreaView.getTop(),
                        mFaceLockAreaView.getWidth(), mFaceLockAreaView.getHeight());
            }
        }

        // Cleans up if FaceLock service unexpectedly disconnects
        @Override
        public void onServiceDisconnected(ComponentName className) {
            synchronized(mFaceLockServiceRunningLock) {
                mFaceLockService = null;
                mFaceLockServiceRunning = false;
            }
            if (DEBUG) Log.w(TAG, "Unexpected disconnect from FaceLock service");
        }
    };
@@ -1011,6 +1048,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
    public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
    {
        if (mLockPatternUtils.usingBiometricWeak()) {
            synchronized (mFaceLockServiceRunningLock) {
                if (!mFaceLockServiceRunning) {
                    if (DEBUG) Log.d(TAG, "Starting FaceLock");
                    try {
@@ -1024,6 +1062,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
                }
            }
        }
    }

    // Tells the FaceLock service to stop displaying its UI and stop recognition
    public void stopFaceLock()
@@ -1032,6 +1071,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
            // Note that attempting to stop FaceLock when it's not running is not an issue.
            // FaceLock can return, which stops it and then we try to stop it when the
            // screen is turned off.  That's why we check.
            synchronized (mFaceLockServiceRunningLock) {
                if (mFaceLockServiceRunning) {
                    try {
                        if (DEBUG) Log.d(TAG, "Stopping FaceLock");
@@ -1043,6 +1083,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
                }
            }
        }
    }

    // Implements the FaceLock service callback interface defined in AIDL
    private final IFaceLockCallback mFaceLockCallback = new IFaceLockCallback.Stub() {
@@ -1051,6 +1092,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
        @Override
        public void unlock() {
            if (DEBUG) Log.d(TAG, "FaceLock unlock");
            // Note that we don't hide the client FaceLockAreaView because we want to keep the
            // lock screen covered while the phone is unlocked

            stopFaceLock();
            mKeyguardScreenCallback.keyguardDone(true);
            mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
@@ -1061,6 +1105,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
        public void cancel() {
            // In this case, either the user has cancelled out, or FaceLock failed to recognize them
            if (DEBUG) Log.d(TAG, "FaceLock cancel");
            // Here we hide the client FaceLockViewArea to expose the underlying backup method
            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
            stopFaceLock();
        }

@@ -1069,8 +1115,12 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
        public void sleepDevice() {
            // In this case, it appears the phone has been turned on accidentally
            if (DEBUG) Log.d(TAG, "FaceLock accidental turn on");
            // Here we hide the client FaceLockViewArea to expose the underlying backup method
            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
            stopFaceLock();
            // TODO(bcolonna): how do we put the phone back to sleep (i.e., turn off the screen)
            // TODO(bcolonna): this should be removed once the service is no longer calling it
            // because we are just going to let the lockscreen timeout
        }
    };
}
+0 −6
Original line number Diff line number Diff line
@@ -199,12 +199,6 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
        setFocusableInTouchMode(true);
    }

    // TODO(bcolonna): This is to tell FaceLock where to draw...but this covers up the wireless
    // service text, so we will want to change the way the area is specified
    public View getUnlockAreaView() {
        return mLockPatternView;
    }

    public void setEnableFallback(boolean state) {
        if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")");
        mEnableFallback = state;