/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.keyguard;

import com.android.internal.policy.IFaceLockCallback;
import com.android.internal.policy.IFaceLockInterface;
import com.android.internal.widget.LockPatternUtils;

import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.View;

public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {

    private static final boolean DEBUG = KeyguardConstants.DEBUG;
    private static final String TAG = "FULLockscreen";
    private static final String FACE_LOCK_PACKAGE = "com.android.facelock";

    private final Context mContext;
    private final LockPatternUtils mLockPatternUtils;

    // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null?
    private boolean mServiceRunning = false;
    // TODO: now that the code has been restructure to do almost all operations from a handler, this
    // lock may no longer be necessary.
    private final Object mServiceRunningLock = new Object();
    private IFaceLockInterface mService;
    private boolean mBoundToService = false;
    private View mFaceUnlockView;

    private Handler mHandler;
    private final int MSG_SERVICE_CONNECTED = 0;
    private final int MSG_SERVICE_DISCONNECTED = 1;
    private final int MSG_UNLOCK = 2;
    private final int MSG_CANCEL = 3;
    private final int MSG_REPORT_FAILED_ATTEMPT = 4;
    private final int MSG_POKE_WAKELOCK = 5;

    // TODO: This was added for the purpose of adhering to what the biometric interface expects
    // the isRunning() function to return.  However, it is probably not necessary to have both
    // mRunning and mServiceRunning.  I'd just rather wait to change that logic.
    private volatile boolean mIsRunning = false;

    KeyguardSecurityCallback mKeyguardScreenCallback;

    /**
     * Stores some of the structures that Face Unlock will need to access and creates the handler
     * will be used to execute messages on the UI thread.
     */
    public FaceUnlock(Context context) {
        mContext = context;
        mLockPatternUtils = new LockPatternUtils(context);
        mHandler = new Handler(this);
    }

    public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) {
        mKeyguardScreenCallback = keyguardScreenCallback;
    }

    /**
     * Stores and displays the view that Face Unlock is allowed to draw within.
     * TODO: since the layout object will eventually be shared by multiple biometric unlock
     * methods, we will have to add our other views (background, cancel button) here.
     */
    public void initializeView(View biometricUnlockView) {
        Log.d(TAG, "initializeView()");
        mFaceUnlockView = biometricUnlockView;
    }

    /**
     * Indicates whether Face Unlock is currently running.
     */
    public boolean isRunning() {
        return mIsRunning;
    }

    /**
     * Dismisses face unlock and goes to the backup lock
     */
    public void stopAndShowBackup() {
        if (DEBUG) Log.d(TAG, "stopAndShowBackup()");
        mHandler.sendEmptyMessage(MSG_CANCEL);
    }

    /**
     * Binds to the Face Unlock service.  Face Unlock will be started when the bind completes.  The
     * Face Unlock view is displayed to hide the backup lock while the service is starting up.
     * Called on the UI thread.
     */
    public boolean start() {
        if (DEBUG) Log.d(TAG, "start()");
        if (mHandler.getLooper() != Looper.myLooper()) {
            Log.e(TAG, "start() called off of the UI thread");
        }

        if (mIsRunning) {
            Log.w(TAG, "start() called when already running");
        }

        if (!mBoundToService) {
            Log.d(TAG, "Binding to Face Unlock service for user="
                    + mLockPatternUtils.getCurrentUser());
            mContext.bindServiceAsUser(
                    new Intent(IFaceLockInterface.class.getName()).setPackage(FACE_LOCK_PACKAGE),
                    mConnection,
                    Context.BIND_AUTO_CREATE,
                    new UserHandle(mLockPatternUtils.getCurrentUser()));
            mBoundToService = true;
        } else {
            Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
        }

        mIsRunning = true;
        return true;
    }

    /**
     * Stops Face Unlock and unbinds from the service.  Called on the UI thread.
     */
    public boolean stop() {
        if (DEBUG) Log.d(TAG, "stop()");
        if (mHandler.getLooper() != Looper.myLooper()) {
            Log.e(TAG, "stop() called from non-UI thread");
        }

        // Clearing any old service connected messages.
        mHandler.removeMessages(MSG_SERVICE_CONNECTED);

        boolean mWasRunning = mIsRunning;

        stopUi();

        if (mBoundToService) {
            if (mService != null) {
                try {
                    mService.unregisterCallback(mFaceUnlockCallback);
                } catch (RemoteException e) {
                    // Not much we can do
                }
            }
            Log.d(TAG, "Unbinding from Face Unlock service");
            mContext.unbindService(mConnection);
            mBoundToService = false;
        } else {
            // This is usually not an error when this happens.  Sometimes we will tell it to
            // unbind multiple times because it's called from both onWindowFocusChanged and
            // onDetachedFromWindow.
            if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound");
        }
        mIsRunning = false;
        return mWasRunning;
    }

    /**
     * Frees up resources used by Face Unlock and stops it if it is still running.
     */
    public void cleanUp() {
        if (DEBUG) Log.d(TAG, "cleanUp()");
        if (mService != null) {
            try {
                mService.unregisterCallback(mFaceUnlockCallback);
            } catch (RemoteException e) {
                // Not much we can do
            }
            stopUi();
            mService = null;
        }
    }

    /**
     * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK.
     */
    public int getQuality() {
        return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
    }

    /**
     * Handles messages such that everything happens on the UI thread in a deterministic order.
     * Calls from the Face Unlock service come from binder threads.  Calls from lockscreen typically
     * come from the UI thread.  This makes sure there are no race conditions between those calls.
     */
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_SERVICE_CONNECTED:
                handleServiceConnected();
                break;
            case MSG_SERVICE_DISCONNECTED:
                handleServiceDisconnected();
                break;
            case MSG_UNLOCK:
                handleUnlock(msg.arg1);
                break;
            case MSG_CANCEL:
                handleCancel();
                break;
            case MSG_REPORT_FAILED_ATTEMPT:
                handleReportFailedAttempt();
                break;
            case MSG_POKE_WAKELOCK:
                handlePokeWakelock(msg.arg1);
                break;
            default:
                Log.e(TAG, "Unhandled message");
                return false;
        }
        return true;
    }

    /**
     * Tells the service to start its UI via an AIDL interface.  Called when the
     * onServiceConnected() callback is received.
     */
    void handleServiceConnected() {
        Log.d(TAG, "handleServiceConnected()");

        // It is possible that an unbind has occurred in the time between the bind and when this
        // function is reached.  If an unbind has already occurred, proceeding on to call startUi()
        // can result in a fatal error.  Note that the onServiceConnected() callback is
        // asynchronous, so this possibility would still exist if we executed this directly in
        // onServiceConnected() rather than using a handler.
        if (!mBoundToService) {
            Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
            return;
        }

        try {
            mService.registerCallback(mFaceUnlockCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString());
            mService = null;
            mBoundToService = false;
            mIsRunning = false;
            return;
        }

        if (mFaceUnlockView != null) {
            IBinder windowToken = mFaceUnlockView.getWindowToken();
            if (windowToken != null) {
                // When switching between portrait and landscape view while Face Unlock is running,
                // the screen will eventually go dark unless we poke the wakelock when Face Unlock
                // is restarted.
                mKeyguardScreenCallback.userActivity();

                int[] position;
                position = new int[2];
                mFaceUnlockView.getLocationInWindow(position);
                startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(),
                        mFaceUnlockView.getHeight());
            } else {
                Log.e(TAG, "windowToken is null in handleServiceConnected()");
            }
        }
    }

    /**
     * Called when the onServiceDisconnected() callback is received.  This should not happen during
     * normal operation.  It indicates an error has occurred.
     */
    void handleServiceDisconnected() {
        Log.e(TAG, "handleServiceDisconnected()");
        // TODO: this lock may no longer be needed now that everything is being called from a
        // handler
        synchronized (mServiceRunningLock) {
            mService = null;
            mServiceRunning = false;
        }
        mBoundToService = false;
        mIsRunning = false;
    }

    /**
     * Stops the Face Unlock service and tells the device to grant access to the user.
     */
    void handleUnlock(int authenticatedUserId) {
        if (DEBUG) Log.d(TAG, "handleUnlock()");
        stop();
        int currentUserId = mLockPatternUtils.getCurrentUser();
        if (authenticatedUserId == currentUserId) {
            if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId);
            mKeyguardScreenCallback.reportUnlockAttempt(true);
            mKeyguardScreenCallback.dismiss(true);
        } else {
            Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId +
                    ") because the current user is " + currentUserId);
        }
    }

    /**
     * Stops the Face Unlock service and goes to the backup lock.
     */
    void handleCancel() {
        if (DEBUG) Log.d(TAG, "handleCancel()");
        // We are going to the backup method, so we don't want to see Face Unlock again until the
        // next time the user visits keyguard.
        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);

        mKeyguardScreenCallback.showBackupSecurity();
        stop();
        mKeyguardScreenCallback.userActivity();
    }

    /**
     * Increments the number of failed Face Unlock attempts.
     */
    void handleReportFailedAttempt() {
        if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
        // We are going to the backup method, so we don't want to see Face Unlock again until the
        // next time the user visits keyguard.
        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);

        mKeyguardScreenCallback.reportUnlockAttempt(false);
    }

    /**
     * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific
     * amount of time.
     */
    void handlePokeWakelock(int millis) {
      PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
      if (powerManager.isScreenOn()) {
        mKeyguardScreenCallback.userActivity();
      }
    }

    /**
     * Implements service connection methods.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        /**
         * Called when the Face Unlock service connects after calling bind().
         */
        public void onServiceConnected(ComponentName className, IBinder iservice) {
            Log.d(TAG, "Connected to Face Unlock service");
            mService = IFaceLockInterface.Stub.asInterface(iservice);
            mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED);
        }

        /**
         * Called if the Face Unlock service unexpectedly disconnects.  This indicates an error.
         */
        public void onServiceDisconnected(ComponentName className) {
            Log.e(TAG, "Unexpected disconnect from Face Unlock service");
            mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED);
        }
    };

    /**
     * Tells the Face Unlock service to start displaying its UI and start processing.
     */
    private void startUi(IBinder windowToken, int x, int y, int w, int h) {
        if (DEBUG) Log.d(TAG, "startUi()");
        synchronized (mServiceRunningLock) {
            if (!mServiceRunning) {
                Log.d(TAG, "Starting Face Unlock");
                try {
                    mService.startUi(windowToken, x, y, w, h,
                            mLockPatternUtils.isBiometricWeakLivelinessEnabled());
                } catch (RemoteException e) {
                    Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
                    return;
                }
                mServiceRunning = true;
            } else {
                Log.w(TAG, "startUi() attempted while running");
            }
        }
    }

    /**
     * Tells the Face Unlock service to stop displaying its UI and stop processing.
     */
    private void stopUi() {
        if (DEBUG) Log.d(TAG, "stopUi()");
        // Note that attempting to stop Face Unlock when it's not running is not an issue.
        // Face Unlock can return, which stops it and then we try to stop it when the
        // screen is turned off.  That's why we check.
        synchronized (mServiceRunningLock) {
            if (mServiceRunning) {
                Log.d(TAG, "Stopping Face Unlock");
                try {
                    mService.stopUi();
                } catch (RemoteException e) {
                    Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString());
                }
                mServiceRunning = false;
            } else {
                // This is usually not an error when this happens.  Sometimes we will tell it to
                // stop multiple times because it's called from both onWindowFocusChanged and
                // onDetachedFromWindow.
                if (DEBUG) Log.d(TAG, "stopUi() attempted while not running");
            }
        }
    }

    /**
     * Implements the AIDL biometric unlock service callback interface.
     */
    private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() {
        /**
         * Called when Face Unlock wants to grant access to the user.
         */
        public void unlock() {
            if (DEBUG) Log.d(TAG, "unlock()");
            Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1);
            mHandler.sendMessage(message);
        }

        /**
         * Called when Face Unlock wants to go to the backup.
         */
        public void cancel() {
            if (DEBUG) Log.d(TAG, "cancel()");
            mHandler.sendEmptyMessage(MSG_CANCEL);
        }

        /**
         * Called when Face Unlock wants to increment the number of failed attempts.
         */
        public void reportFailedAttempt() {
            if (DEBUG) Log.d(TAG, "reportFailedAttempt()");
            mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT);
        }

        /**
         * Called when Face Unlock wants to keep the screen alive and active for a specific amount
         * of time.
         */
        public void pokeWakelock(int millis) {
            if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
            Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
            mHandler.sendMessage(message);
        }

    };
}
