diff --git a/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java b/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java index 2ecad3f..19533be 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java +++ b/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java @@ -5,7 +5,9 @@ import android.content.Intent; import android.os.Build; import org.jivesoftware.smack.android.AndroidSmackInitializer; +import org.jivesoftware.smackx.ping.android.ServerPingWithAlarmManager; import org.mercury_im.messenger.android.di.component.DaggerAppComponent; +import org.mercury_im.messenger.android.util.AndroidLoggingHandler; import org.mercury_im.messenger.core.Messenger; import org.mercury_im.messenger.core.data.repository.AccountRepository; import org.mercury_im.messenger.android.di.component.AppComponent; @@ -43,11 +45,13 @@ public class MercuryImApplication extends Application { public void onCreate() { super.onCreate(); AndroidSmackInitializer.initialize(getApplicationContext()); + AndroidLoggingHandler.reset(new AndroidLoggingHandler()); INSTANCE = this; appComponent = createAppComponent(); appComponent.inject(this); setupClientStateIndication(); + ServerPingWithAlarmManager.onCreate(this); Notifications.initializeNotificationChannels(this); diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java index ea553f7..b9c0918 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java @@ -3,6 +3,7 @@ package org.mercury_im.messenger.android.di.component; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule; import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule; +import org.mercury_im.messenger.android.ui.ox.AndroidOxSecretKeyBackupRestoreViewModel; import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule; import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule; import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule; @@ -80,6 +81,8 @@ public interface AppComponent { void inject(ContactDetailViewModel contactDetailViewModel); + //void inject(AndroidOxSecretKeyBackupRestoreViewModel viewModel); + // Common VMs void inject(LoginViewModel loginViewModel); diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/module/AndroidSchedulersModule.java b/app/src/main/java/org/mercury_im/messenger/android/di/module/AndroidSchedulersModule.java index 7b33011..fe0e5f1 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/module/AndroidSchedulersModule.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/module/AndroidSchedulersModule.java @@ -30,7 +30,6 @@ public class AndroidSchedulersModule { @Provides @Named(value = SchedulersFacade.SCHEDULER_NEW_THREAD) - @Singleton static Scheduler provideNewThread() { return Schedulers.newThread(); } diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/module/AppModule.java b/app/src/main/java/org/mercury_im/messenger/android/di/module/AppModule.java index d4c6668..fd641c6 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/module/AppModule.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/module/AppModule.java @@ -2,7 +2,6 @@ package org.mercury_im.messenger.android.di.module; import android.app.Application; -import org.jivesoftware.smackx.ping.android.ServerPingWithAlarmManager; import org.mercury_im.messenger.android.MercuryImApplication; import javax.inject.Singleton; @@ -17,7 +16,6 @@ public class AppModule { public AppModule(MercuryImApplication application) { this.mApplication = application; - ServerPingWithAlarmManager.onCreate(application); } @Provides diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/MainActivity.java b/app/src/main/java/org/mercury_im/messenger/android/ui/MainActivity.java index 4b22e7d..8306fef 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/MainActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/MainActivity.java @@ -15,6 +15,7 @@ import com.google.android.material.navigation.NavigationView; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.R; +import org.mercury_im.messenger.android.ui.account.AccountDetailsFragment; import org.mercury_im.messenger.android.ui.account.DeleteAccountDialogFragment; import org.mercury_im.messenger.android.ui.account.OnAccountListItemClickListener; import org.mercury_im.messenger.core.data.repository.AccountRepository; @@ -101,7 +102,7 @@ public class MainActivity extends AppCompatActivity @Override public void onAccountListItemClick(Account item) { - + getSupportFragmentManager().beginTransaction().replace(R.id.fragment, new AccountDetailsFragment()).commit(); } @Override diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountDetailsFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountDetailsFragment.java new file mode 100644 index 0000000..e997d49 --- /dev/null +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountDetailsFragment.java @@ -0,0 +1,45 @@ +package org.mercury_im.messenger.android.ui.account; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import org.mercury_im.messenger.R; + +import butterknife.BindView; +import butterknife.ButterKnife; +import de.hdodenhof.circleimageview.CircleImageView; + +public class AccountDetailsFragment extends Fragment { + + @BindView(R.id.avatar) + CircleImageView avatar; + + @BindView(R.id.jid) + TextView jid; + + @BindView(R.id.btn_share) + Button localFingerprintShareButton; + + @BindView(R.id.fingerprint) + TextView localFingerprint; + + @BindView(R.id.fingerprint_list) + ListView externalFingerprintList; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_account_details, container, false); + ButterKnife.bind(this, view); + return view; + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsFragment.java index 2b4a536..6b4b167 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsFragment.java @@ -98,7 +98,6 @@ public class AccountsFragment extends Fragment { } private void displayAddAccountDialog() { - Logger.getAnonymousLogger().log(Level.INFO, "DISPLAY FRAGMENT!!!"); AddAccountDialogFragment addAccountDialogFragment = new AddAccountDialogFragment(); addAccountDialogFragment.show(getParentFragmentManager(), "addAccount"); } diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsRecyclerViewAdapter.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsRecyclerViewAdapter.java index b641d34..7c0aced 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsRecyclerViewAdapter.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/AccountsRecyclerViewAdapter.java @@ -65,9 +65,6 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter viewModel.setAccountEnabled(account, checked)); holder.status.setText(viewItem.getConnectivityState().toString()); - if (viewItem.getFingerprint() != null) { - holder.fingerprint.setText(OpenPgpFingerprintColorizer.formatOpenPgpV4Fingerprint(viewItem.getFingerprint())); - } holder.mView.setOnLongClickListener(v -> { onAccountClickListener.onAccountListItemLongClick(account); @@ -83,7 +80,6 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter { + + private static final Logger LOGGER = Logger.getLogger(AndroidOxSecretKeyBackupRestoreViewModel.class.getName()); + + //@Inject + OxSecretKeyBackupRestoreViewModel commonViewModel; + + private MutableLiveData> restoreError = + new MutableLiveData<>(new Optional<>()); + + public AndroidOxSecretKeyBackupRestoreViewModel(@NonNull Application application) { + super(application); + //MercuryImApplication.getApplication().getAppComponent().inject(this); + + addDisposable(getCommonViewModel().observeBackupRestoreError() + .subscribe(opt -> restoreError.postValue(opt), + e -> LOGGER.log(Level.SEVERE, "Could not subscribe android view model to backup restore errors", e))); + } + + @Override + public OxSecretKeyBackupRestoreViewModel getCommonViewModel() { + return commonViewModel; + } + + public void onRestoreCodeEntered(String code) { + getCommonViewModel().onRestoreCodeEntered(code); + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/ox/OxSecretKeyBackupRestoreFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/ox/OxSecretKeyBackupRestoreFragment.java new file mode 100644 index 0000000..5ed855a --- /dev/null +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/ox/OxSecretKeyBackupRestoreFragment.java @@ -0,0 +1,48 @@ +package org.mercury_im.messenger.android.ui.ox; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.Toast; + +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + +import org.mercury_im.messenger.R; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class OxSecretKeyBackupRestoreFragment extends Fragment { + + @BindView(R.id.toolbar) + Toolbar toolbar; + + @BindView(R.id.backup_code) + EditText backupCode; + + @BindView(R.id.btn_scan) + ImageButton scanButton; + + @BindView(R.id.btn_cancel) + Button cancelButton; + + @BindView(R.id.btn_continue) + Button continueButton; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_ox_restore_backup, container, false); + ButterKnife.bind(this, view); + + scanButton.setOnClickListener(v -> Toast.makeText(getContext(), R.string.not_yet_implemented, Toast.LENGTH_SHORT).show()); + + + return view; + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/android/util/AndroidLoggingHandler.java b/app/src/main/java/org/mercury_im/messenger/android/util/AndroidLoggingHandler.java new file mode 100644 index 0000000..c1207b2 --- /dev/null +++ b/app/src/main/java/org/mercury_im/messenger/android/util/AndroidLoggingHandler.java @@ -0,0 +1,67 @@ +package org.mercury_im.messenger.android.util; + + +import android.util.Log; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * Make JUL work on Android. + */ +public class AndroidLoggingHandler extends Handler { + + public static void reset(Handler rootHandler) { + Logger rootLogger = LogManager.getLogManager().getLogger(""); + Handler[] handlers = rootLogger.getHandlers(); + for (Handler handler : handlers) { + rootLogger.removeHandler(handler); + } + rootLogger.addHandler(rootHandler); + } + + @Override + public void close() { + } + + @Override + public void flush() { + } + + @Override + public void publish(LogRecord record) { + if (!super.isLoggable(record)) + return; + + String name = record.getLoggerName(); + int maxLength = 30; + String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name; + + try { + int level = getAndroidLevel(record.getLevel()); + Log.println(level, tag, record.getMessage()); + if (record.getThrown() != null) { + Log.println(level, tag, Log.getStackTraceString(record.getThrown())); + } + } catch (RuntimeException e) { + Log.e("AndroidLoggingHandler", "Error logging message.", e); + } + } + + static int getAndroidLevel(Level level) { + int value = level.intValue(); + + if (value >= Level.SEVERE.intValue()) { + return Log.ERROR; + } else if (value >= Level.WARNING.intValue()) { + return Log.WARN; + } else if (value >= Level.INFO.intValue()) { + return Log.INFO; + } else { + return Log.DEBUG; + } + } +} diff --git a/app/src/main/res/drawable/ic_qr_code_scanner_black_24dp.xml b/app/src/main/res/drawable/ic_qr_code_scanner_black_24dp.xml new file mode 100644 index 0000000..45a618a --- /dev/null +++ b/app/src/main/res/drawable/ic_qr_code_scanner_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_share_black_24dp.xml b/app/src/main/res/drawable/ic_share_black_24dp.xml new file mode 100644 index 0000000..e3fe874 --- /dev/null +++ b/app/src/main/res/drawable/ic_share_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/dialog_account_details.xml b/app/src/main/res/layout/dialog_account_details.xml deleted file mode 100644 index e3f90dd..0000000 --- a/app/src/main/res/layout/dialog_account_details.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_account_details.xml b/app/src/main/res/layout/fragment_account_details.xml new file mode 100644 index 0000000..f6cea72 --- /dev/null +++ b/app/src/main/res/layout/fragment_account_details.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_fingerprint_card.xml b/app/src/main/res/layout/fragment_fingerprint_card.xml new file mode 100644 index 0000000..d66d021 --- /dev/null +++ b/app/src/main/res/layout/fragment_fingerprint_card.xml @@ -0,0 +1,48 @@ + + + + + + + + + +