Skip to content

Commit b1df951

Browse files
committed
Merge remote-tracking branch 'upstream/master' into cust_remove_call_confirm
Resolved conflict in ci config
2 parents f7e1a4f + b809008 commit b1df951

95 files changed

Lines changed: 5817 additions & 2658 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/android.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ jobs:
2626

2727
- name: Build with Gradle
2828
run: ./gradlew qa
29+
- name: Archive reports for failed build
30+
if: ${{ failure() }}
31+
uses: actions/upload-artifact@v2
32+
with:
33+
name: reports
34+
path: '*/build/reports'
2935
apk:
3036
name: Generate APK
3137
runs-on: ubuntu-18.04

app/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ protobuf {
6161
}
6262
}
6363

64-
def canonicalVersionCode = 793
65-
def canonicalVersionName = "5.4.7"
64+
def canonicalVersionCode = 794
65+
def canonicalVersionName = "5.4.8"
6666

6767
def postFixSize = 100
6868
def abiPostFix = ['universal' : 0,
@@ -312,6 +312,7 @@ dependencies {
312312
implementation "androidx.camera:camera-view:1.0.0-alpha18"
313313
implementation "androidx.concurrent:concurrent-futures:1.0.0"
314314
implementation "androidx.autofill:autofill:1.0.0"
315+
implementation "androidx.biometric:biometric:1.1.0"
315316

316317
implementation ('com.google.firebase:firebase-messaging:20.2.0') {
317318
exclude group: 'com.google.firebase', module: 'firebase-core'
@@ -335,7 +336,7 @@ dependencies {
335336
implementation project(':video')
336337

337338
implementation 'org.signal:zkgroup-android:0.7.0'
338-
implementation 'org.whispersystems:signal-client-android:0.1.5'
339+
implementation 'org.whispersystems:signal-client-android:0.1.7'
339340
implementation 'com.google.protobuf:protobuf-javalite:3.10.0'
340341
implementation 'org.signal:argon2:13.1@aar'
341342

app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ public void onCreate() {
145145
Conscrypt.setUseEngineSocketByDefault(true);
146146
}
147147
})
148+
.addBlocking("blob-provider", this::initializeBlobProvider)
148149
.addNonBlocking(this::initializeRevealableMessageManager)
149150
.addNonBlocking(this::initializeGcmCheck)
150151
.addNonBlocking(this::initializeSignedPreKeyCheck)
@@ -158,7 +159,6 @@ public void onCreate() {
158159
.addNonBlocking(StorageSyncHelper::scheduleRoutineSync)
159160
.addNonBlocking(() -> ApplicationDependencies.getJobManager().beginJobLoop())
160161
.addPostRender(this::initializeExpiringMessageManager)
161-
.addPostRender(this::initializeBlobProvider)
162162
.execute();
163163

164164
Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms");
@@ -387,7 +387,7 @@ private void initializePendingMessages() {
387387

388388
@WorkerThread
389389
private void initializeBlobProvider() {
390-
BlobProvider.getInstance().onSessionStart(this);
390+
BlobProvider.getInstance().initialize(this);
391391
}
392392

393393
@WorkerThread

app/src/main/java/org/thoughtcrime/securesms/ConfirmIdentityDialog.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import androidx.appcompat.app.AlertDialog;
1313

14+
import org.thoughtcrime.securesms.crypto.DatabaseSessionLock;
1415
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
1516
import org.thoughtcrime.securesms.database.DatabaseFactory;
1617
import org.thoughtcrime.securesms.database.MessageDatabase;
@@ -27,13 +28,12 @@
2728
import org.thoughtcrime.securesms.util.VerifySpan;
2829
import org.whispersystems.libsignal.SignalProtocolAddress;
2930
import org.whispersystems.libsignal.util.guava.Optional;
31+
import org.whispersystems.signalservice.api.SignalSessionLock;
3032
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
3133
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
3234

3335
import java.io.IOException;
3436

35-
import static org.whispersystems.libsignal.SessionCipher.SESSION_LOCK;
36-
3737
public class ConfirmIdentityDialog extends AlertDialog {
3838

3939
@SuppressWarnings("unused")
@@ -94,7 +94,7 @@ public void onClick(DialogInterface dialog, int which) {
9494
{
9595
@Override
9696
protected Void doInBackground(Void... params) {
97-
synchronized (SESSION_LOCK) {
97+
try (SignalSessionLock.Lock unused = DatabaseSessionLock.INSTANCE.acquire()) {
9898
SignalProtocolAddress mismatchAddress = new SignalProtocolAddress(Recipient.resolved(recipientId).requireServiceId(), 1);
9999
TextSecureIdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(getContext());
100100

@@ -136,7 +136,6 @@ private void processOutgoingMessageRecord(MessageRecord messageRecord) {
136136

137137
private void processIncomingMessageRecord(MessageRecord messageRecord) {
138138
try {
139-
PushDatabase pushDatabase = DatabaseFactory.getPushDatabase(getContext());
140139
MessageDatabase smsDatabase = DatabaseFactory.getSmsDatabase(getContext());
141140

142141
smsDatabase.removeMismatchedIdentity(messageRecord.getId(),
@@ -155,9 +154,7 @@ private void processIncomingMessageRecord(MessageRecord messageRecord) {
155154
0,
156155
null);
157156

158-
long pushId = pushDatabase.insert(envelope);
159-
160-
ApplicationDependencies.getJobManager().add(new PushDecryptMessageJob(getContext(), pushId, messageRecord.getId()));
157+
ApplicationDependencies.getJobManager().add(new PushDecryptMessageJob(getContext(), envelope, messageRecord.getId()));
161158
} catch (IOException e) {
162159
throw new AssertionError(e);
163160
}

app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java

Lines changed: 51 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.thoughtcrime.securesms;
1818

1919
import android.animation.Animator;
20-
import android.annotation.SuppressLint;
2120
import android.app.KeyguardManager;
2221
import android.content.Context;
2322
import android.content.Intent;
@@ -46,9 +45,11 @@
4645
import android.widget.ImageView;
4746
import android.widget.TextView;
4847

48+
import androidx.annotation.NonNull;
4949
import androidx.appcompat.widget.Toolbar;
50-
import androidx.core.hardware.fingerprint.FingerprintManagerCompat;
51-
import androidx.core.os.CancellationSignal;
50+
import androidx.biometric.BiometricManager;
51+
import androidx.biometric.BiometricManager.Authenticators;
52+
import androidx.biometric.BiometricPrompt;
5253

5354
import org.signal.core.util.logging.Log;
5455
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
@@ -70,7 +71,10 @@
7071
*/
7172
public class PassphrasePromptActivity extends PassphraseActivity {
7273

73-
private static final String TAG = PassphrasePromptActivity.class.getSimpleName();
74+
private static final String TAG = Log.tag(PassphrasePromptActivity.class);
75+
private static final int BIOMETRIC_AUTHENTICATORS = Authenticators.BIOMETRIC_STRONG | Authenticators.BIOMETRIC_WEAK;
76+
private static final int ALLOWED_AUTHENTICATORS = BIOMETRIC_AUTHENTICATORS | Authenticators.DEVICE_CREDENTIAL;
77+
private static final short AUTHENTICATE_REQUEST_CODE = 1007;
7478

7579
private DynamicIntroTheme dynamicTheme = new DynamicIntroTheme();
7680
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@@ -84,12 +88,12 @@ public class PassphrasePromptActivity extends PassphraseActivity {
8488
private ImageButton hideButton;
8589
private AnimatingToggle visibilityToggle;
8690

87-
private FingerprintManagerCompat fingerprintManager;
88-
private CancellationSignal fingerprintCancellationSignal;
89-
private FingerprintListener fingerprintListener;
91+
private BiometricManager biometricManager;
92+
private BiometricPrompt biometricPrompt;
93+
private BiometricPrompt.PromptInfo biometricPromptInfo;
9094

9195
private boolean authenticated;
92-
private boolean failure;
96+
private boolean hadFailure;
9397

9498
@Override
9599
public void onCreate(Bundle savedInstanceState) {
@@ -112,20 +116,11 @@ public void onResume() {
112116

113117
setLockTypeVisibility();
114118

115-
if (TextSecurePreferences.isScreenLockEnabled(this) && !authenticated && !failure) {
119+
if (TextSecurePreferences.isScreenLockEnabled(this) && !authenticated && !hadFailure) {
116120
resumeScreenLock();
117121
}
118122

119-
failure = false;
120-
}
121-
122-
@Override
123-
public void onPause() {
124-
super.onPause();
125-
126-
if (TextSecurePreferences.isScreenLockEnabled(this)) {
127-
pauseScreenLock();
128-
}
123+
hadFailure = false;
129124
}
130125

131126
@Override
@@ -160,15 +155,16 @@ public boolean onOptionsItemSelected(MenuItem item) {
160155
}
161156

162157
@Override
163-
@SuppressLint("MissingSuperCall") // no fragments to dispatch to
164-
public void onActivityResult(int requestCode, int resultcode, Intent data) {
165-
if (requestCode != 1) return;
158+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
159+
super.onActivityResult(requestCode, resultCode, data);
166160

167-
if (resultcode == RESULT_OK) {
161+
if (requestCode != AUTHENTICATE_REQUEST_CODE) return;
162+
163+
if (resultCode == RESULT_OK) {
168164
handleAuthenticated();
169165
} else {
170166
Log.w(TAG, "Authentication failed");
171-
failure = true;
167+
hadFailure = true;
172168
}
173169
}
174170

@@ -219,16 +215,20 @@ private void initializeResources() {
219215
ImageButton okButton = findViewById(R.id.ok_button);
220216
Toolbar toolbar = findViewById(R.id.toolbar);
221217

222-
showButton = findViewById(R.id.passphrase_visibility);
223-
hideButton = findViewById(R.id.passphrase_visibility_off);
224-
visibilityToggle = findViewById(R.id.button_toggle);
225-
passphraseText = findViewById(R.id.passphrase_edit);
226-
passphraseAuthContainer = findViewById(R.id.password_auth_container);
227-
fingerprintPrompt = findViewById(R.id.fingerprint_auth_container);
228-
lockScreenButton = findViewById(R.id.lock_screen_auth_container);
229-
fingerprintManager = FingerprintManagerCompat.from(this);
230-
fingerprintCancellationSignal = new CancellationSignal();
231-
fingerprintListener = new FingerprintListener();
218+
showButton = findViewById(R.id.passphrase_visibility);
219+
hideButton = findViewById(R.id.passphrase_visibility_off);
220+
visibilityToggle = findViewById(R.id.button_toggle);
221+
passphraseText = findViewById(R.id.passphrase_edit);
222+
passphraseAuthContainer = findViewById(R.id.password_auth_container);
223+
fingerprintPrompt = findViewById(R.id.fingerprint_auth_container);
224+
lockScreenButton = findViewById(R.id.lock_screen_auth_container);
225+
biometricManager = BiometricManager.from(this);
226+
biometricPrompt = new BiometricPrompt(this, new BiometricAuthenticationListener());
227+
biometricPromptInfo = new BiometricPrompt.PromptInfo
228+
.Builder()
229+
.setAllowedAuthenticators(ALLOWED_AUTHENTICATORS)
230+
.setTitle(getString(R.string.PassphrasePromptActivity_unlock_signal))
231+
.build();
232232

233233
setSupportActionBar(toolbar);
234234
getSupportActionBar().setTitle("");
@@ -254,14 +254,9 @@ private void initializeResources() {
254254
private void setLockTypeVisibility() {
255255
if (TextSecurePreferences.isScreenLockEnabled(this)) {
256256
passphraseAuthContainer.setVisibility(View.GONE);
257-
258-
if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) {
259-
fingerprintPrompt.setVisibility(View.VISIBLE);
260-
lockScreenButton.setVisibility(View.GONE);
261-
} else {
262-
fingerprintPrompt.setVisibility(View.GONE);
263-
lockScreenButton.setVisibility(View.VISIBLE);
264-
}
257+
fingerprintPrompt.setVisibility(biometricManager.canAuthenticate(BIOMETRIC_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS ? View.VISIBLE
258+
: View.GONE);
259+
lockScreenButton.setVisibility(View.VISIBLE);
265260
} else {
266261
passphraseAuthContainer.setVisibility(View.VISIBLE);
267262
fingerprintPrompt.setVisibility(View.GONE);
@@ -280,26 +275,19 @@ private void resumeScreenLock() {
280275
return;
281276
}
282277

283-
if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) {
284-
Log.i(TAG, "Listening for fingerprints...");
285-
fingerprintCancellationSignal = new CancellationSignal();
286-
fingerprintManager.authenticate(null, 0, fingerprintCancellationSignal, fingerprintListener, null);
278+
if (biometricManager.canAuthenticate(ALLOWED_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS) {
279+
Log.i(TAG, "Listening for biometric authentication...");
280+
biometricPrompt.authenticate(biometricPromptInfo);
287281
} else if (Build.VERSION.SDK_INT >= 21){
288282
Log.i(TAG, "firing intent...");
289283
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(getString(R.string.PassphrasePromptActivity_unlock_signal), "");
290-
startActivityForResult(intent, 1);
284+
startActivityForResult(intent, AUTHENTICATE_REQUEST_CODE);
291285
} else {
292286
Log.w(TAG, "Not compatible...");
293287
handleAuthenticated();
294288
}
295289
}
296290

297-
private void pauseScreenLock() {
298-
if (fingerprintCancellationSignal != null) {
299-
fingerprintCancellationSignal.cancel();
300-
}
301-
}
302-
303291
private void sendEmailToSupport() {
304292
String body = SupportEmailUtil.generateSupportEmailBody(this,
305293
R.string.PassphrasePromptActivity_signal_android_lock_screen,
@@ -359,15 +347,19 @@ protected void cleanup() {
359347
System.gc();
360348
}
361349

362-
private class FingerprintListener extends FingerprintManagerCompat.AuthenticationCallback {
350+
private class BiometricAuthenticationListener extends BiometricPrompt.AuthenticationCallback {
363351
@Override
364-
public void onAuthenticationError(int errMsgId, CharSequence errString) {
365-
Log.w(TAG, "Authentication error: " + errMsgId + " " + errString);
366-
onAuthenticationFailed();
352+
public void onAuthenticationError(int errorCode, @NonNull CharSequence errorString) {
353+
Log.w(TAG, "Authentication error: " + errorCode);
354+
hadFailure = true;
355+
356+
if (errorCode != BiometricPrompt.ERROR_CANCELED && errorCode != BiometricPrompt.ERROR_USER_CANCELED) {
357+
onAuthenticationFailed();
358+
}
367359
}
368360

369361
@Override
370-
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
362+
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
371363
Log.i(TAG, "onAuthenticationSucceeded");
372364
fingerprintPrompt.setImageResource(R.drawable.ic_check_white_48dp);
373365
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.green_500), PorterDuff.Mode.SRC_IN);
@@ -384,8 +376,7 @@ public void onAnimationEnd(Animator animation) {
384376

385377
@Override
386378
public void onAuthenticationFailed() {
387-
Log.w(TAG, "onAuthenticatoinFailed()");
388-
FingerprintManagerCompat.AuthenticationCallback callback = this;
379+
Log.w(TAG, "onAuthenticationFailed()");
389380

390381
fingerprintPrompt.setImageResource(R.drawable.ic_close_white_48dp);
391382
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.red_500), PorterDuff.Mode.SRC_IN);
@@ -409,6 +400,5 @@ public void onAnimationRepeat(Animation animation) {}
409400

410401
fingerprintPrompt.startAnimation(shake);
411402
}
412-
413403
}
414404
}

0 commit comments

Comments
 (0)