package org.thoughtcrime.securesms; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.IBinder; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.service.KeyCachingService; public class PassphraseRequiredMixin { private KeyCachingServiceConnection serviceConnection; private BroadcastReceiver clearKeyReceiver; private BroadcastReceiver newKeyReceiver; public void onCreate(Context context, PassphraseRequiredActivity activity) { initializeClearKeyReceiver(context, activity); } public void onResume(Context context, PassphraseRequiredActivity activity) { initializeNewKeyReceiver(context, activity); initializeServiceConnection(context, activity); KeyCachingService.registerPassphraseActivityStarted(context); } public void onPause(Context context, PassphraseRequiredActivity activity) { removeNewKeyReceiver(context); removeServiceConnection(context); KeyCachingService.registerPassphraseActivityStopped(context); } public void onDestroy(Context context, PassphraseRequiredActivity activity) { removeClearKeyReceiver(context); } private void initializeClearKeyReceiver(Context context, final PassphraseRequiredActivity activity) { this.clearKeyReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { activity.onMasterSecretCleared(); } }; IntentFilter filter = new IntentFilter(KeyCachingService.CLEAR_KEY_EVENT); context.registerReceiver(clearKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null); } private void initializeNewKeyReceiver(Context context, final PassphraseRequiredActivity activity) { this.newKeyReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { activity.onNewMasterSecret((MasterSecret)intent.getParcelableExtra("master_secret")); } }; IntentFilter filter = new IntentFilter(KeyCachingService.NEW_KEY_EVENT); context.registerReceiver(newKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null); } private void initializeServiceConnection(Context context, PassphraseRequiredActivity activity) { Intent cachingIntent = new Intent(context, KeyCachingService.class); context.startService(cachingIntent); this.serviceConnection = new KeyCachingServiceConnection(activity); Intent bindIntent = new Intent(context, KeyCachingService.class); context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); } private void removeClearKeyReceiver(Context context) { if (clearKeyReceiver != null) { context.unregisterReceiver(clearKeyReceiver); clearKeyReceiver = null; } } private void removeNewKeyReceiver(Context context) { if (newKeyReceiver != null) { context.unregisterReceiver(newKeyReceiver); newKeyReceiver = null; } } private void removeServiceConnection(Context context) { if (this.serviceConnection != null && this.serviceConnection.isBound()) { context.unbindService(this.serviceConnection); } } private static class KeyCachingServiceConnection implements ServiceConnection { private final PassphraseRequiredActivity activity; private boolean isBound; public KeyCachingServiceConnection(PassphraseRequiredActivity activity) { this.activity = activity; this.isBound = false; } @Override public void onServiceConnected(ComponentName name, IBinder service) { KeyCachingService keyCachingService = ((KeyCachingService.KeyCachingBinder)service).getService(); MasterSecret masterSecret = keyCachingService.getMasterSecret(); this.isBound = true; if (masterSecret == null) { activity.onMasterSecretCleared(); } else { activity.onNewMasterSecret(masterSecret); } } @Override public void onServiceDisconnected(ComponentName name) { this.isBound = false; } public boolean isBound() { return this.isBound; } } }