Merge branch 'dev' of https://github.com/loki-project/session-android into external-file-access-fix

This commit is contained in:
Anton Chekulaev 2020-09-08 15:33:58 +10:00
commit 5acf505994
19 changed files with 138 additions and 144 deletions

View File

@ -1,16 +1,15 @@
import java.security.MessageDigest
buildscript { buildscript {
ext.kotlin_version = "1.3.31" ext.kotlin_version = "1.4.0"
ext.kovenant_version = "3.3.0" ext.kovenant_version = "3.3.0"
repositories { repositories {
mavenLocal() mavenLocal()
google() google()
mavenCentral() mavenCentral()
jcenter()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:3.4.1" classpath "com.android.tools.build:gradle:4.0.1"
classpath files('libs/gradle-witness.jar') classpath files('libs/gradle-witness.jar')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.gms:google-services:4.3.3" classpath "com.google.gms:google-services:4.3.3"
@ -18,8 +17,8 @@ buildscript {
} }
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'witness' apply plugin: 'witness'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
@ -73,14 +72,15 @@ configurations.all {
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.0' implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.2.0' implementation 'androidx.exifinterface:exifinterface:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0' implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
@ -89,7 +89,6 @@ dependencies {
exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
} }
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1' implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1' implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
implementation 'org.conscrypt:conscrypt-android:2.0.0' implementation 'org.conscrypt:conscrypt-android:2.0.0'
@ -141,28 +140,6 @@ dependencies {
exclude group: 'com.fasterxml.jackson.core' exclude group: 'com.fasterxml.jackson.core'
exclude group: 'org.freemarker' exclude group: 'org.freemarker'
} }
testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
testImplementation 'androidx.test:core:1.3.0-rc03'
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
androidTestImplementation ('com.squareup.assertj:assertj-android:1.1.1') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
exclude group: 'com.android.support', module: 'support-annotations'
}
testImplementation 'org.robolectric:robolectric:4.2'
testImplementation 'org.robolectric:shadows-multidex:4.2'
// Loki // Loki
// Local: // Local:
implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install
@ -180,10 +157,32 @@ dependencies {
implementation "com.github.tbruyelle:rxpermissions:0.10.2" implementation "com.github.tbruyelle:rxpermissions:0.10.2"
implementation "com.github.ybq:Android-SpinKit:1.4.0" implementation "com.github.ybq:Android-SpinKit:1.4.0"
implementation "com.opencsv:opencsv:4.6" implementation "com.opencsv:opencsv:4.6"
testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
testImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'androidx.multidex:multidex:2.0.1'
androidTestImplementation 'androidx.multidex:multidex-instrumentation:2.0.0'
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
androidTestImplementation ('com.squareup.assertj:assertj-android:1.1.1') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
exclude group: 'com.android.support', module: 'support-annotations'
}
testImplementation 'org.robolectric:robolectric:4.2'
testImplementation 'org.robolectric:shadows-multidex:4.2'
} }
def canonicalVersionCode = 84 def canonicalVersionCode = 93
def canonicalVersionName = "1.5.0" def canonicalVersionName = "1.5.2"
def postFixSize = 10 def postFixSize = 10
def abiPostFix = ['armeabi-v7a' : 1, def abiPostFix = ['armeabi-v7a' : 1,
@ -208,9 +207,10 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
multiDexEnabled true // Even though we're running API 21+, this is still needed for release builds
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
project.ext.set("archivesBaseName", "Signal") project.ext.set("archivesBaseName", "session")
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L" buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
buildConfigField "String", "SIGNAL_URL", "\"\"" buildConfigField "String", "SIGNAL_URL", "\"\""
@ -349,6 +349,7 @@ android {
} }
} }
/*
def assembleWebsiteDescriptor = { variant, file -> def assembleWebsiteDescriptor = { variant, file ->
if (file.exists()) { if (file.exists()) {
MessageDigest md = MessageDigest.getInstance("SHA-256") MessageDigest md = MessageDigest.getInstance("SHA-256")
@ -372,7 +373,7 @@ def assembleWebsiteDescriptor = { variant, file ->
descriptorFile.write(descriptor) descriptorFile.write(descriptor)
} }
} }
/*
def signProductionRelease = { variant -> def signProductionRelease = { variant ->
variant.outputs.collect { output -> variant.outputs.collect { output ->
String apkName = output.outputFile.name String apkName = output.outputFile.name

View File

@ -5,5 +5,5 @@ repositories {
} }
dependencies { dependencies {
compile 'com.android.tools.build:apksig:3.3.2' implementation 'com.android.tools.build:apksig:4.0.1'
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -23,7 +23,7 @@
android:layout_weight="1" /> android:layout_weight="1" />
<Button <Button
style="@style/Widget.Session.Button.Common.ProminentFilled" style="@style/Widget.Session.Button.Common.ProminentOutline"
android:id="@+id/joinPublicChatButton" android:id="@+id/joinPublicChatButton"
android:layout_width="196dp" android:layout_width="196dp"
android:layout_height="@dimen/medium_button_height" android:layout_height="@dimen/medium_button_height"

View File

@ -90,7 +90,7 @@
android:layout_weight="1" /> android:layout_weight="1" />
<Button <Button
style="@style/Widget.Session.Button.Common.ProminentFilled" style="@style/Widget.Session.Button.Common.ProminentOutline"
android:id="@+id/createPrivateChatButton" android:id="@+id/createPrivateChatButton"
android:layout_width="196dp" android:layout_width="196dp"
android:layout_height="@dimen/medium_button_height" android:layout_height="@dimen/medium_button_height"

View File

@ -21,10 +21,12 @@
android:textSize="@dimen/medium_font_size" /> android:textSize="@dimen/medium_font_size" />
<TextView <TextView
style="@style/SessionIDTextView"
android:id="@+id/seedTextView" android:id="@+id/seedTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing" android:layout_marginTop="@dimen/large_spacing"
android:padding="@dimen/small_spacing"
android:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees" android:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees"
android:textColor="@color/text" android:textColor="@color/text"
android:textSize="@dimen/small_font_size" android:textSize="@dimen/small_font_size"
@ -70,9 +72,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing" android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_seed_disclaimer" android:text="@string/dialog_seed_disclaimer"
android:textStyle="bold"
android:textColor="@color/text" android:textColor="@color/text"
android:textSize="@dimen/very_small_font_size" android:alpha="0.6"
android:textSize="10sp"
android:textAlignment="center" /> android:textAlignment="center" />
</LinearLayout> </LinearLayout>

View File

@ -90,53 +90,53 @@
android:paddingStart="10dp" android:paddingStart="10dp"
android:paddingEnd="40dp"/> android:paddingEnd="40dp"/>
<org.thoughtcrime.securesms.components.AnimatingToggle <!-- <org.thoughtcrime.securesms.components.AnimatingToggle-->
android:id="@+id/button_toggle" <!-- android:id="@+id/button_toggle"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_alignRight="@+id/passphrase_edit" <!-- android:layout_alignRight="@+id/passphrase_edit"-->
android:layout_centerVertical="true" <!-- android:layout_centerVertical="true"-->
android:layout_gravity="center" <!-- android:layout_gravity="center"-->
android:gravity="center"> <!-- android:gravity="center">-->
<ImageButton android:id="@+id/passphrase_visibility" <!-- <ImageButton android:id="@+id/passphrase_visibility"-->
android:src="?ic_visibility" <!-- android:src="?ic_visibility"-->
android:background="@drawable/touch_highlight_background" <!-- android:background="@drawable/touch_highlight_background"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:paddingStart="8dp" <!-- android:paddingStart="8dp"-->
android:paddingEnd="8dp" <!-- android:paddingEnd="8dp"-->
android:paddingTop="3dp" <!-- android:paddingTop="3dp"-->
android:paddingBottom="3dp" <!-- android:paddingBottom="3dp"-->
android:layout_centerVertical="true" /> <!-- android:layout_centerVertical="true" />-->
<ImageButton android:id="@+id/passphrase_visibility_off" <!-- <ImageButton android:id="@+id/passphrase_visibility_off"-->
android:src="?ic_visibility_off" <!-- android:src="?ic_visibility_off"-->
android:background="@drawable/touch_highlight_background" <!-- android:background="@drawable/touch_highlight_background"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:paddingStart="8dp" <!-- android:paddingStart="8dp"-->
android:paddingEnd="8dp" <!-- android:paddingEnd="8dp"-->
android:paddingTop="3dp" <!-- android:paddingTop="3dp"-->
android:paddingBottom="3dp" <!-- android:paddingBottom="3dp"-->
android:layout_centerVertical="true" /> <!-- android:layout_centerVertical="true" />-->
</org.thoughtcrime.securesms.components.AnimatingToggle> <!-- </org.thoughtcrime.securesms.components.AnimatingToggle>-->
<ImageButton android:id="@+id/ok_button" <!-- <ImageButton android:id="@+id/ok_button"-->
android:src="?ic_arrow_forward" <!-- android:src="?ic_arrow_forward"-->
android:contentDescription="@string/PassphrasePromptActivity_ok_button_content_description" <!-- android:contentDescription="@string/PassphrasePromptActivity_ok_button_content_description"-->
android:background="@null" <!-- android:background="@null"-->
android:text="@string/prompt_passphrase_activity__unlock" <!-- android:text="@string/prompt_passphrase_activity__unlock"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_alignParentEnd="true" <!-- android:layout_alignParentEnd="true"-->
android:layout_centerVertical="true" <!-- android:layout_centerVertical="true"-->
android:textAppearance="?android:attr/textAppearanceMedium" <!-- android:textAppearance="?android:attr/textAppearanceMedium"-->
android:paddingStart="5dp" <!-- android:paddingStart="5dp"-->
android:paddingTop="5dp" <!-- android:paddingTop="5dp"-->
android:paddingEnd="10dp" <!-- android:paddingEnd="10dp"-->
android:paddingBottom="5dp"/> <!-- android:paddingBottom="5dp"/>-->
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@ -8,7 +8,7 @@
<dimen name="small_font_size">13sp</dimen> <dimen name="small_font_size">13sp</dimen>
<dimen name="medium_font_size">15sp</dimen> <dimen name="medium_font_size">15sp</dimen>
<dimen name="large_font_size">20sp</dimen> <dimen name="large_font_size">20sp</dimen>
<dimen name="very_large_font_size">25sp</dimen> <dimen name="very_large_font_size">24sp</dimen>
<dimen name="massive_font_size">50sp</dimen> <dimen name="massive_font_size">50sp</dimen>
<!-- Session --> <!-- Session -->

View File

@ -8,7 +8,7 @@
<dimen name="small_font_size">15sp</dimen> <dimen name="small_font_size">15sp</dimen>
<dimen name="medium_font_size">17sp</dimen> <dimen name="medium_font_size">17sp</dimen>
<dimen name="large_font_size">22sp</dimen> <dimen name="large_font_size">22sp</dimen>
<dimen name="very_large_font_size">27sp</dimen> <dimen name="very_large_font_size">26sp</dimen>
<dimen name="massive_font_size">50sp</dimen> <dimen name="massive_font_size">50sp</dimen>
<!-- Element Sizes --> <!-- Element Sizes -->

View File

@ -1851,7 +1851,7 @@
<string name="activity_select_contacts_title">Select Contacts</string> <string name="activity_select_contacts_title">Select Contacts</string>
<string name="dialog_seed_disclaimer">*Please note that it is not possible to use the same Session ID on multiple devices simultaneously</string> <string name="dialog_seed_disclaimer">It is not possible to use the same Session ID on multiple devices simultaneously</string>
<string name="view_reset_secure_session_done_message">Secure session reset done</string> <string name="view_reset_secure_session_done_message">Secure session reset done</string>

View File

@ -16,18 +16,17 @@
*/ */
package org.thoughtcrime.securesms; package org.thoughtcrime.securesms;
import android.app.Application; import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver; import androidx.multidex.MultiDexApplication;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceId;
@ -116,10 +115,10 @@ import org.whispersystems.signalservice.loki.protocol.closedgroups.SharedSenderK
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager; import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager;
import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol; import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol;
import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities; import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities;
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocol;
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocolDelegate;
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink; import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink;
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol; import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol;
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocol;
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocolDelegate;
import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol; import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol;
import java.io.File; import java.io.File;
@ -145,10 +144,11 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
* *
* @author Moxie Marlinspike * @author Moxie Marlinspike
*/ */
public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate, public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate,
SessionManagementProtocolDelegate, SharedSenderKeysImplementationDelegate { SessionManagementProtocolDelegate, SharedSenderKeysImplementationDelegate {
private static final String TAG = ApplicationContext.class.getSimpleName(); private static final String TAG = ApplicationContext.class.getSimpleName();
private final static int OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB
private ExpiringMessageManager expiringMessageManager; private ExpiringMessageManager expiringMessageManager;
private TypingStatusRepository typingStatusRepository; private TypingStatusRepository typingStatusRepository;

View File

@ -76,8 +76,8 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private Button lockScreenButton; private Button lockScreenButton;
private EditText passphraseText; private EditText passphraseText;
private ImageButton showButton; // private ImageButton showButton;
private ImageButton hideButton; // private ImageButton hideButton;
private AnimatingToggle visibilityToggle; private AnimatingToggle visibilityToggle;
private FingerprintManagerCompat fingerprintManager; private FingerprintManagerCompat fingerprintManager;
@ -203,11 +203,11 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private void initializeResources() { private void initializeResources() {
ImageButton okButton = findViewById(R.id.ok_button); // ImageButton okButton = findViewById(R.id.ok_button);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
showButton = findViewById(R.id.passphrase_visibility); // showButton = findViewById(R.id.passphrase_visibility);
hideButton = findViewById(R.id.passphrase_visibility_off); // hideButton = findViewById(R.id.passphrase_visibility_off);
visibilityToggle = findViewById(R.id.button_toggle); visibilityToggle = findViewById(R.id.button_toggle);
passphraseText = findViewById(R.id.passphrase_edit); passphraseText = findViewById(R.id.passphrase_edit);
passphraseAuthContainer = findViewById(R.id.password_auth_container); passphraseAuthContainer = findViewById(R.id.password_auth_container);
@ -217,17 +217,17 @@ public class PassphrasePromptActivity extends PassphraseActivity {
fingerprintCancellationSignal = new CancellationSignal(); fingerprintCancellationSignal = new CancellationSignal();
fingerprintListener = new FingerprintListener(); fingerprintListener = new FingerprintListener();
setSupportActionBar(toolbar); // setSupportActionBar(toolbar);
getSupportActionBar().setTitle(""); // getSupportActionBar().setTitle("");
SpannableString hint = new SpannableString(" " + getString(R.string.PassphrasePromptActivity_enter_passphrase)); SpannableString hint = new SpannableString(" " + getString(R.string.PassphrasePromptActivity_enter_passphrase));
hint.setSpan(new RelativeSizeSpan(0.9f), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); hint.setSpan(new RelativeSizeSpan(0.9f), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
hint.setSpan(new TypefaceSpan("sans-serif"), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); hint.setSpan(new TypefaceSpan("sans-serif"), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
passphraseText.setHint(hint); passphraseText.setHint(hint);
okButton.setOnClickListener(new OkButtonClickListener()); // okButton.setOnClickListener(new OkButtonClickListener());
showButton.setOnClickListener(new ShowButtonOnClickListener()); // showButton.setOnClickListener(new ShowButtonOnClickListener());
hideButton.setOnClickListener(new HideButtonOnClickListener()); // hideButton.setOnClickListener(new HideButtonOnClickListener());
passphraseText.setOnEditorActionListener(new PassphraseActionListener()); passphraseText.setOnEditorActionListener(new PassphraseActionListener());
passphraseText.setImeActionLabel(getString(R.string.prompt_passphrase_activity__unlock), passphraseText.setImeActionLabel(getString(R.string.prompt_passphrase_activity__unlock),
EditorInfo.IME_ACTION_DONE); EditorInfo.IME_ACTION_DONE);
@ -316,7 +316,7 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private class ShowButtonOnClickListener implements OnClickListener { private class ShowButtonOnClickListener implements OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
visibilityToggle.display(hideButton); // visibilityToggle.display(hideButton);
setPassphraseVisibility(true); setPassphraseVisibility(true);
} }
} }
@ -324,7 +324,7 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private class HideButtonOnClickListener implements OnClickListener { private class HideButtonOnClickListener implements OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
visibilityToggle.display(showButton); // visibilityToggle.display(showButton);
setPassphraseVisibility(false); setPassphraseVisibility(false);
} }
} }

View File

@ -6,9 +6,6 @@ import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
@ -17,11 +14,16 @@ import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
@ -209,7 +211,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName); authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName);
// We use the raw color resource because Android 4.x was struggling with tints here // We use the raw color resource because Android 4.x was struggling with tints here
quoteBarView.setImageResource(R.color.accent); int colorID = UiModeUtilities.isDayUiMode(getContext()) ? R.color.black : R.color.accent;
quoteBarView.setImageResource(colorID);
mainView.setBackgroundColor(ThemeUtil.getThemedColor(getContext(), mainView.setBackgroundColor(ThemeUtil.getThemedColor(getContext(),
outgoing ? R.attr.message_received_background_color : R.attr.message_sent_background_color)); outgoing ? R.attr.message_received_background_color : R.attr.message_sent_background_color));
} }

View File

@ -3103,15 +3103,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void updateSubtitleTextView() { private void updateSubtitleTextView() {
muteIndicatorImageView.setVisibility(View.GONE); muteIndicatorImageView.setVisibility(View.GONE);
subtitleTextView.setVisibility(View.VISIBLE); subtitleTextView.setVisibility(View.VISIBLE);
if (messageStatus != null) { if (recipient.isMuted()) {
switch (messageStatus) {
case "calculatingPoW": subtitleTextView.setText("Encrypting message"); break;
case "contactingNetwork": subtitleTextView.setText("Tracing a path"); break;
case "sendingMessage": subtitleTextView.setText("Sending message"); break;
case "messageSent": subtitleTextView.setText("Message sent securely"); break;
case "messageFailed": subtitleTextView.setText("Message failed to send"); break;
}
} else if (recipient.isMuted()) {
muteIndicatorImageView.setVisibility(View.VISIBLE); muteIndicatorImageView.setVisibility(View.VISIBLE);
subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())); subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) { } else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) {
@ -3125,10 +3117,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else { } else {
subtitleTextView.setVisibility(View.GONE); subtitleTextView.setVisibility(View.GONE);
} }
} else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) {
String ourMasterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(this);
String hexEncodedPublicKey = (recipient.isLocalNumber() && ourMasterHexEncodedPublicKey != null) ? ourMasterHexEncodedPublicKey : recipient.getAddress().toPhoneString();
subtitleTextView.setText(hexEncodedPublicKey);
} else { } else {
subtitleTextView.setVisibility(View.GONE); subtitleTextView.setVisibility(View.GONE);
} }

View File

@ -202,7 +202,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
seedReminderView.visibility = View.GONE seedReminderView.visibility = View.GONE
} }
// Multiple device removal notification // Multi device removal sheet
if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) { if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) {
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this) TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
val userPublicKey = TextSecurePreferences.getLocalNumber(this) val userPublicKey = TextSecurePreferences.getLocalNumber(this)
@ -223,7 +223,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
} }
} }
// Light theme introduction // Light theme introduction sheet
if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) && if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) &&
UiModeUtilities.isDayUiMode(this)) { UiModeUtilities.isDayUiMode(this)) {
TextSecurePreferences.setHasSeenLightThemeIntroSheet(this) TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)

View File

@ -33,8 +33,14 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
return TextSecurePreferences.getProfileName(context) return TextSecurePreferences.getProfileName(context)
} else { } else {
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
return database.get(displayNameTable, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor -> val result = database.get(displayNameTable, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor ->
cursor.getString(cursor.getColumnIndexOrThrow(displayName)) cursor.getString(cursor.getColumnIndexOrThrow(displayName))
} ?: return null
val suffix = " (...${publicKey.substring(publicKey.count() - 8)})"
if (result.endsWith(suffix)) {
return result.substring(0..(result.count() - suffix.count()))
} else {
return result
} }
} }
} }

View File

@ -7,17 +7,18 @@ import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import kotlinx.android.synthetic.main.dialog_seed.view.* import kotlinx.android.synthetic.main.dialog_seed.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
import java.io.File
class SeedDialog : DialogFragment() { class SeedDialog : DialogFragment() {

View File

@ -10,7 +10,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.api.messages.SignalServiceContent
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol
import java.security.MessageDigest import java.security.MessageDigest
object SessionMetaProtocol { object SessionMetaProtocol {
@ -37,24 +36,16 @@ object SessionMetaProtocol {
@JvmStatic @JvmStatic
fun handleProfileUpdateIfNeeded(context: Context, content: SignalServiceContent) { fun handleProfileUpdateIfNeeded(context: Context, content: SignalServiceContent) {
val rawDisplayName = content.senderDisplayName.orNull() ?: return val displayName = content.senderDisplayName.orNull() ?: return
if (rawDisplayName.isBlank()) { return } if (displayName.isBlank()) { return }
val userPublicKey = TextSecurePreferences.getLocalNumber(context) val userPublicKey = TextSecurePreferences.getLocalNumber(context)
val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
val sender = content.sender.toLowerCase() val sender = content.sender.toLowerCase()
if (userMasterPublicKey == sender) { if (userMasterPublicKey == sender) {
// Update the user's local name if the message came from their master device // Update the user's local name if the message came from their master device
TextSecurePreferences.setProfileName(context, rawDisplayName) TextSecurePreferences.setProfileName(context, displayName)
} }
// Don't overwrite if the message came from a linked device; the device name is
// stored as a user name
val allUserDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey)
if (!allUserDevices.contains(sender)) {
val displayName = rawDisplayName + " (..." + sender.substring(sender.length - 8) + ")"
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, displayName) DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, displayName)
} else {
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, rawDisplayName)
}
} }
@JvmStatic @JvmStatic

View File

@ -53,7 +53,9 @@ object MentionUtilities {
} }
val result = SpannableString(text) val result = SpannableString(text)
for (mention in mentions) { for (mention in mentions) {
result.setSpan(ForegroundColorSpan(context.resources.getColorWithID(R.color.accent, context.theme)), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) val isLightMode = UiModeUtilities.isDayUiMode(context)
val colorID = if (isLightMode && isOutgoingMessage) R.color.black else R.color.accent
result.setSpan(ForegroundColorSpan(context.resources.getColorWithID(colorID, context.theme)), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
} }
return result return result