That fuck shit the fascists are using
1package org.tm.archive;
2
3import android.content.BroadcastReceiver;
4import android.content.Context;
5import android.content.Intent;
6import android.content.IntentFilter;
7import android.os.Bundle;
8
9import androidx.annotation.IdRes;
10import androidx.annotation.NonNull;
11import androidx.annotation.Nullable;
12import androidx.fragment.app.Fragment;
13
14import org.greenrobot.eventbus.EventBus;
15import org.signal.core.util.logging.Log;
16import org.signal.core.util.tracing.Tracer;
17import org.signal.devicetransfer.TransferStatus;
18import org.tm.archive.components.settings.app.changenumber.ChangeNumberLockActivity;
19import org.tm.archive.crypto.MasterSecretUtil;
20import org.tm.archive.dependencies.ApplicationDependencies;
21import org.tm.archive.devicetransfer.olddevice.OldDeviceTransferActivity;
22import org.tm.archive.keyvalue.SignalStore;
23import org.tm.archive.lock.v2.CreateSvrPinActivity;
24import org.tm.archive.migrations.ApplicationMigrationActivity;
25import org.tm.archive.migrations.ApplicationMigrations;
26import org.tm.archive.pin.PinRestoreActivity;
27import org.tm.archive.profiles.edit.CreateProfileActivity;
28import org.tm.archive.push.SignalServiceNetworkAccess;
29import org.tm.archive.recipients.Recipient;
30import org.tm.archive.registration.RegistrationNavigationActivity;
31import org.tm.archive.service.KeyCachingService;
32import org.tm.archive.util.AppStartup;
33import org.tm.archive.util.TextSecurePreferences;
34
35import java.util.Locale;
36
37public abstract class PassphraseRequiredActivity extends BaseActivity implements MasterSecretListener {
38 private static final String TAG = Log.tag(PassphraseRequiredActivity.class);
39
40 public static final String LOCALE_EXTRA = "locale_extra";
41 public static final String NEXT_INTENT_EXTRA = "next_intent";
42
43 private static final int STATE_NORMAL = 0;
44 private static final int STATE_CREATE_PASSPHRASE = 1;
45 private static final int STATE_PROMPT_PASSPHRASE = 2;
46 private static final int STATE_UI_BLOCKING_UPGRADE = 3;
47 private static final int STATE_WELCOME_PUSH_SCREEN = 4;
48 private static final int STATE_ENTER_SIGNAL_PIN = 5;
49 private static final int STATE_CREATE_PROFILE_NAME = 6;
50 private static final int STATE_CREATE_SIGNAL_PIN = 7;
51 private static final int STATE_TRANSFER_ONGOING = 8;
52 private static final int STATE_TRANSFER_LOCKED = 9;
53 private static final int STATE_CHANGE_NUMBER_LOCK = 10;
54
55 private SignalServiceNetworkAccess networkAccess;
56 private BroadcastReceiver clearKeyReceiver;
57
58 @Override
59 protected final void onCreate(Bundle savedInstanceState) {
60 Tracer.getInstance().start(Log.tag(getClass()) + "#onCreate()");
61 AppStartup.getInstance().onCriticalRenderEventStart();
62 this.networkAccess = ApplicationDependencies.getSignalServiceNetworkAccess();
63 onPreCreate();
64
65 final boolean locked = KeyCachingService.isLocked(this);
66 routeApplicationState(locked);
67
68 super.onCreate(savedInstanceState);
69
70 if (!isFinishing()) {
71 initializeClearKeyReceiver();
72 onCreate(savedInstanceState, true);
73 }
74
75 AppStartup.getInstance().onCriticalRenderEventEnd();
76 Tracer.getInstance().end(Log.tag(getClass()) + "#onCreate()");
77 }
78
79 protected void onPreCreate() {}
80 protected void onCreate(Bundle savedInstanceState, boolean ready) {}
81
82 @Override
83 protected void onDestroy() {
84 super.onDestroy();
85 removeClearKeyReceiver(this);
86 }
87
88 @Override
89 public void onMasterSecretCleared() {
90 Log.d(TAG, "onMasterSecretCleared()");
91 if (ApplicationDependencies.getAppForegroundObserver().isForegrounded()) routeApplicationState(true);
92 else finish();
93 }
94
95 protected <T extends Fragment> T initFragment(@IdRes int target,
96 @NonNull T fragment)
97 {
98 return initFragment(target, fragment, null);
99 }
100
101 protected <T extends Fragment> T initFragment(@IdRes int target,
102 @NonNull T fragment,
103 @Nullable Locale locale)
104 {
105 return initFragment(target, fragment, locale, null);
106 }
107
108 protected <T extends Fragment> T initFragment(@IdRes int target,
109 @NonNull T fragment,
110 @Nullable Locale locale,
111 @Nullable Bundle extras)
112 {
113 Bundle args = new Bundle();
114 args.putSerializable(LOCALE_EXTRA, locale);
115
116 if (extras != null) {
117 args.putAll(extras);
118 }
119
120 fragment.setArguments(args);
121 getSupportFragmentManager().beginTransaction()
122 .replace(target, fragment)
123 .commitAllowingStateLoss();
124 return fragment;
125 }
126
127 private void routeApplicationState(boolean locked) {
128 Intent intent = getIntentForState(getApplicationState(locked));
129 if (intent != null) {
130 startActivity(intent);
131 finish();
132 }
133 }
134
135 private Intent getIntentForState(int state) {
136 Log.d(TAG, "routeApplicationState(), state: " + state);
137
138 switch (state) {
139 case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
140 case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
141 case STATE_UI_BLOCKING_UPGRADE: return getUiBlockingUpgradeIntent();
142 case STATE_WELCOME_PUSH_SCREEN: return getPushRegistrationIntent();
143 case STATE_ENTER_SIGNAL_PIN: return getEnterSignalPinIntent();
144 case STATE_CREATE_SIGNAL_PIN: return getCreateSignalPinIntent();
145 case STATE_CREATE_PROFILE_NAME: return getCreateProfileNameIntent();
146 case STATE_TRANSFER_ONGOING: return getOldDeviceTransferIntent();
147 case STATE_TRANSFER_LOCKED: return getOldDeviceTransferLockedIntent();
148 case STATE_CHANGE_NUMBER_LOCK: return getChangeNumberLockIntent();
149 default: return null;
150 }
151 }
152
153 private int getApplicationState(boolean locked) {
154 if (!MasterSecretUtil.isPassphraseInitialized(this)) {
155 return STATE_CREATE_PASSPHRASE;
156 } else if (locked) {
157 return STATE_PROMPT_PASSPHRASE;
158 } else if (ApplicationMigrations.isUpdate(this) && ApplicationMigrations.isUiBlockingMigrationRunning()) {
159 return STATE_UI_BLOCKING_UPGRADE;
160 } else if (!TextSecurePreferences.hasPromptedPushRegistration(this)) {
161 return STATE_WELCOME_PUSH_SCREEN;
162 } else if (SignalStore.storageService().needsAccountRestore()) {
163 return STATE_ENTER_SIGNAL_PIN;
164 } else if (userHasSkippedOrForgottenPin()) {
165 return STATE_CREATE_SIGNAL_PIN;
166 } else if (userMustSetProfileName()) {
167 return STATE_CREATE_PROFILE_NAME;
168 } else if (userMustCreateSignalPin()) {
169 return STATE_CREATE_SIGNAL_PIN;
170 } else if (EventBus.getDefault().getStickyEvent(TransferStatus.class) != null && getClass() != OldDeviceTransferActivity.class) {
171 return STATE_TRANSFER_ONGOING;
172 } else if (SignalStore.misc().isOldDeviceTransferLocked()) {
173 return STATE_TRANSFER_LOCKED;
174 } else if (SignalStore.misc().isChangeNumberLocked() && getClass() != ChangeNumberLockActivity.class) {
175 return STATE_CHANGE_NUMBER_LOCK;
176 } else {
177 return STATE_NORMAL;
178 }
179 }
180
181 private boolean userMustCreateSignalPin() {
182 return !SignalStore.registrationValues().isRegistrationComplete() && !SignalStore.svr().hasPin() && !SignalStore.svr().lastPinCreateFailed() && !SignalStore.svr().hasOptedOut();
183 }
184
185 private boolean userHasSkippedOrForgottenPin() {
186 return !SignalStore.registrationValues().isRegistrationComplete() && !SignalStore.svr().hasPin() && !SignalStore.svr().hasOptedOut() && SignalStore.svr().isPinForgottenOrSkipped();
187 }
188
189 private boolean userMustSetProfileName() {
190 return !SignalStore.registrationValues().isRegistrationComplete() && Recipient.self().getProfileName().isEmpty();
191 }
192
193 private Intent getCreatePassphraseIntent() {
194 return getRoutedIntent(PassphraseCreateActivity.class, getIntent());
195 }
196
197 private Intent getPromptPassphraseIntent() {
198 Intent intent = getRoutedIntent(PassphrasePromptActivity.class, getIntent());
199 intent.putExtra(PassphrasePromptActivity.FROM_FOREGROUND, ApplicationDependencies.getAppForegroundObserver().isForegrounded());
200 return intent;
201 }
202
203 private Intent getUiBlockingUpgradeIntent() {
204 return getRoutedIntent(ApplicationMigrationActivity.class,
205 TextSecurePreferences.hasPromptedPushRegistration(this)
206 ? getConversationListIntent()
207 : getPushRegistrationIntent());
208 }
209
210 private Intent getPushRegistrationIntent() {
211 return RegistrationNavigationActivity.newIntentForNewRegistration(this, getIntent());
212 }
213
214 private Intent getEnterSignalPinIntent() {
215 return getRoutedIntent(PinRestoreActivity.class, getIntent());
216 }
217
218 private Intent getCreateSignalPinIntent() {
219
220 final Intent intent;
221 if (userMustSetProfileName()) {
222 intent = getCreateProfileNameIntent();
223 } else {
224 intent = getIntent();
225 }
226
227 return getRoutedIntent(CreateSvrPinActivity.class, intent);
228 }
229
230 private Intent getCreateProfileNameIntent() {
231 Intent intent = CreateProfileActivity.getIntentForUserProfile(this);
232 return getRoutedIntent(intent, getIntent());
233 }
234
235 private Intent getOldDeviceTransferIntent() {
236 Intent intent = new Intent(this, OldDeviceTransferActivity.class);
237 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
238 return intent;
239 }
240
241 private @Nullable Intent getOldDeviceTransferLockedIntent() {
242 if (getClass() == MainActivity.class) {
243 return null;
244 }
245 return MainActivity.clearTop(this);
246 }
247
248 private Intent getChangeNumberLockIntent() {
249 return ChangeNumberLockActivity.createIntent(this);
250 }
251
252 private Intent getRoutedIntent(Intent destination, @Nullable Intent nextIntent) {
253 if (nextIntent != null) destination.putExtra("next_intent", nextIntent);
254 return destination;
255 }
256
257 private Intent getRoutedIntent(Class<?> destination, @Nullable Intent nextIntent) {
258 final Intent intent = new Intent(this, destination);
259 if (nextIntent != null) intent.putExtra("next_intent", nextIntent);
260 return intent;
261 }
262
263 private Intent getConversationListIntent() {
264 // TODO [greyson] Navigation
265 return MainActivity.clearTop(this);
266 }
267
268 private void initializeClearKeyReceiver() {
269 this.clearKeyReceiver = new BroadcastReceiver() {
270 @Override
271 public void onReceive(Context context, Intent intent) {
272 Log.i(TAG, "onReceive() for clear key event. PasswordDisabled: " + TextSecurePreferences.isPasswordDisabled(context) + ", ScreenLock: " + TextSecurePreferences.isScreenLockEnabled(context));
273 if (TextSecurePreferences.isScreenLockEnabled(context) || !TextSecurePreferences.isPasswordDisabled(context)) {
274 onMasterSecretCleared();
275 }
276 }
277 };
278
279 IntentFilter filter = new IntentFilter(KeyCachingService.CLEAR_KEY_EVENT);
280 registerReceiver(clearKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null);
281 }
282
283 private void removeClearKeyReceiver(Context context) {
284 if (clearKeyReceiver != null) {
285 context.unregisterReceiver(clearKeyReceiver);
286 clearKeyReceiver = null;
287 }
288 }
289
290 /**
291 * Puts an extra in {@code intent} so that {@code nextIntent} will be shown after it.
292 */
293 public static @NonNull Intent chainIntent(@NonNull Intent intent, @NonNull Intent nextIntent) {
294 intent.putExtra(NEXT_INTENT_EXTRA, nextIntent);
295 return intent;
296 }
297}