Files
mobile/src/ApplicationState.js

184 lines
4.1 KiB
JavaScript

import {AppState} from 'react-native';
import App from "./app"
import KeysManager from "./lib/keysManager"
var _ = require('lodash');
export default class ApplicationState {
// When the app first launches
static Launching = "Launching";
// When the app enters the background completely
static Backgrounding = "Backgrounding";
// When the app resumes from the background
static Resuming = "Resuming";
// When the user enters their local passcode and/or fingerprint
static Locking = "Locking";
// When the user enters their local passcode and/or fingerprint
static Unlocking = "Unlocking";
static instance = null;
static get() {
if (this.instance == null) {
this.instance = new ApplicationState();
}
return this.instance;
}
constructor() {
this.observers = [];
this.locked = true;
AppState.addEventListener('change', this.handleAppStateChange);
this.didLaunch();
}
// Sent from App.js
receiveApplicationStartEvent() {
var authProps = this.getAuthenticationPropsForAppState(ApplicationState.Launching);
if(!authProps.passcode && !authProps.fingerprint) {
this.unlockApplication();
}
}
handleAppStateChange = (nextAppState) => {
this.nextAppState = nextAppState;
var isResuming = nextAppState === "active";
var isEnteringBackground = nextAppState == 'background';
console.log("APP STATE CHANGE FROM", this.mostRecentState,
"TO STATE", nextAppState,
"IS ENTERING BACKGROUND", isEnteringBackground,
"IS RESUMING", isResuming,
);
if(isEnteringBackground) {
this.didEnterBackground();
}
if(isResuming) {
this.didResume();
}
this.mostRecentState = nextAppState;
}
/* State Changes */
didLaunch() {
this.notifyOfState(ApplicationState.Launching);
}
didEnterBackground() {
this.notifyOfState(ApplicationState.Backgrounding);
if(this.shouldLockApplication) {
this.lockApplication();
}
}
didResume() {
this.notifyOfState(ApplicationState.Resuming);
}
/* End State */
getMostRecentState() {
return this.mostRecentState;
}
notifyOfState(state) {
console.log("ApplicationState notifying of state:", state);
for(var observer of this.observers) {
observer.callback(state);
}
}
addStateObserver(callback) {
var observer = {key: Math.random, callback: callback};
this.observers.push(observer);
return observer;
}
removeStateObserver(observer) {
_.pull(this.observers, observer);
}
/* Locking / Unlocking */
isLocked() {
return this.locked;
}
isUnlocked() {
return !this.locked;
}
shouldLockApplication() {
var showPasscode = KeysManager.get().hasOfflinePasscode() && KeysManager.get().passcodeTiming == "immediately";
var showFingerprint = KeysManager.get().hasFingerprint() && KeysManager.get().fingerprintTiming == "immediately";
return showPasscode || showFingerprint;
}
lockApplication() {
this.notifyOfState(ApplicationState.Locking);
this.locked = true;
}
unlockApplication() {
this.notifyOfState(ApplicationState.Unlocking);
this.locked = false;
}
setAuthenticationInProgress(inProgress) {
this.authenticationInProgress = inProgress;
}
isAuthenticationInProgress() {
return this.authenticationInProgress;
}
getAuthenticationPropsForAppState(state) {
if(state == ApplicationState.Unlocking) {
return {};
}
var hasPasscode = KeysManager.get().hasOfflinePasscode();
var hasFingerprint = KeysManager.get().hasFingerprint();
var showPasscode = hasPasscode, showFingerprint = hasFingerprint;
if(state == ApplicationState.Resuming) {
showPasscode = hasPasscode && KeysManager.get().passcodeTiming == "immediately";
showFingerprint = hasFingerprint && KeysManager.get().fingerprintTiming == "immediately";
}
var title = showPasscode && showFingerprint ? "Authentication Required" : (showPasscode ? "Passcode Required" : "Fingerprint Required");
return {
title: title,
passcode: showPasscode || false,
fingerprint: showFingerprint || false,
onAuthenticate: this.unlockApplication.bind(this)
}
}
}