summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/providersetup/activities
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/providersetup/activities')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java216
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java32
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java2
4 files changed, 236 insertions, 16 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
index b2f13e07..a4104e30 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
@@ -5,31 +5,49 @@ import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Guideline;
import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
import butterknife.BindView;
-import butterknife.Optional;
+import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.views.ProviderHeaderView;
+import se.leap.bitmaskclient.tor.TorStatusObservable;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
+import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getBootstrapProgress;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastLogs;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getStringForCurrentStatus;
/**
* Base Activity for configuration wizard activities
@@ -37,7 +55,7 @@ import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
* Created by fupduck on 09.01.18.
*/
-public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
+public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity implements Observer {
private static final String TAG = ConfigWizardBaseActivity.class.getName();
public static final float GUIDE_LINE_COMPACT_DELTA = 0.1f;
@@ -52,12 +70,50 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
protected LinearLayout loadingScreen;
@Nullable
+ @BindView(R.id.btn_connection_detail)
+ protected AppCompatTextView connectionDetailBtn;
+
+ @Nullable
+ @BindView(R.id.connection_detail_header_container)
+ protected RelativeLayout connectionDetailHeaderContainer;
+
+ @Nullable
+ @BindView(R.id.connection_details_title)
+ protected AppCompatTextView connectionDetailsTitle;
+
+ @Nullable
+ @BindView(R.id.connection_detail_container)
+ protected RelativeLayout connectionDetailContainer;
+
+ @Nullable
+ @BindView(R.id.log_container)
+ protected RelativeLayout logsContainer;
+
+ @Nullable
+ @BindView(R.id.tor_state)
+ protected AppCompatTextView torState;
+
+ @Nullable
+ @BindView(R.id.snowflake_state)
+ protected AppCompatTextView snowflakeState;
+
+ @Nullable
+ @BindView(R.id.connection_detail_logs)
+ protected RecyclerView connectionDetailLogs;
+
+ private TorLogAdapter torLogAdapter;
+
+ @Nullable
@BindView(R.id.progressbar)
protected ProgressBar progressBar;
@Nullable
+ @BindView(R.id.progressbar_title)
+ protected AppCompatTextView progressbarTitle;
+
+ @Nullable
@BindView(R.id.progressbar_description)
- protected AppCompatTextView progressbarText;
+ protected AppCompatTextView progressbarDescription;
//Only tablet layouts have guidelines as they are based on a ConstraintLayout
@Nullable
@@ -142,12 +198,15 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
protected void onPause() {
super.onPause();
isActivityShowing = false;
+ TorStatusObservable.getInstance().deleteObserver(this);
}
@Override
protected void onResume() {
super.onResume();
isActivityShowing = true;
+ TorStatusObservable.getInstance().addObserver(this);
+ setProgressbarDescription(getStringForCurrentStatus(this));
}
protected void restoreState(Bundle savedInstanceState) {
@@ -168,10 +227,64 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
providerHeaderView.setTitle(providerHeaderText);
}
+ protected void hideConnectionDetails() {
+ if (loadingScreen == null) {
+ return;
+ }
+
+ connectionDetailHeaderContainer.setVisibility(GONE);
+ connectionDetailContainer.setVisibility(GONE);
+ logsContainer.setVisibility(GONE);
+ }
+
+ protected void showConnectionDetails() {
+ if (loadingScreen == null) {
+ return;
+ }
+ LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+ connectionDetailLogs.setLayoutManager(layoutManager);
+ torLogAdapter = new TorLogAdapter(getLastLogs());
+ connectionDetailLogs.setAdapter(torLogAdapter);
+
+ connectionDetailLogs.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ if (newState != SCROLL_STATE_IDLE) {
+ torLogAdapter.postponeUpdate = true;
+ } else if (newState == SCROLL_STATE_IDLE && getFirstVisibleItemPosion() == 0) {
+ torLogAdapter.postponeUpdate = false;
+ }
+ }
+ });
+
+ snowflakeState.setText(getLastSnowflakeLog());
+ torState.setText(getLastTorLog());
+ connectionDetailBtn.setOnClickListener(v -> {
+ if (logsContainer.getVisibility() == VISIBLE) {
+ logsContainer.setVisibility(GONE);
+ connectionDetailContainer.setVisibility(GONE);
+ connectionDetailsTitle.setVisibility(GONE);
+ connectionDetailBtn.setText(R.string.show_connection_details);
+ } else {
+ logsContainer.setVisibility(VISIBLE);
+ connectionDetailContainer.setVisibility(VISIBLE);
+ connectionDetailsTitle.setVisibility(VISIBLE);
+ connectionDetailBtn.setText(R.string.hide_connection_details);
+ }
+ });
+ connectionDetailHeaderContainer.setVisibility(VISIBLE);
+ }
+
+ private int getFirstVisibleItemPosion() {
+ return ((LinearLayoutManager)connectionDetailLogs.getLayoutManager()).findFirstVisibleItemPosition();
+ }
+
protected void hideProgressBar() {
if (loadingScreen == null) {
return;
}
+ hideConnectionDetails();
loadingScreen.setVisibility(GONE);
content.setVisibility(VISIBLE);
}
@@ -184,11 +297,30 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
loadingScreen.setVisibility(VISIBLE);
}
- protected void setProgressbarText(@StringRes int progressbarText) {
- if (this.progressbarText == null) {
+ protected void setProgressbarTitle(@StringRes int progressbarTitle) {
+ if (loadingScreen == null) {
+ return;
+ }
+ this.progressbarTitle.setText(progressbarTitle);
+ }
+
+ protected void setProgressbarDescription(String progressbarDescription) {
+ if (loadingScreen == null) {
+ return;
+ }
+ this.progressbarDescription.setText(progressbarDescription);
+ }
+
+ protected void setConfigProgress(int value) {
+ if (loadingScreen == null) {
return;
}
- this.progressbarText.setText(progressbarText);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ progressBar.setProgress(value);
+ } else {
+ progressBar.setProgress(value, true);
+ }
+ progressBar.setIndeterminate(value >= 100 || value < 0);
}
@@ -287,4 +419,76 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
});
}
+ @Override
+ public void update(Observable o, Object arg) {
+ if (o instanceof TorStatusObservable) {
+ runOnUiThread(() -> {
+ if (TorStatusObservable.getStatus() != TorStatusObservable.TorStatus.OFF && loadingScreen != null) {
+ if (connectionDetailContainer.getVisibility() == GONE) {
+ showConnectionDetails();
+ } else {
+ setLogs(getLastTorLog(), getLastSnowflakeLog(), getLastLogs());
+ }
+ }
+ setProgressbarDescription(getStringForCurrentStatus(ConfigWizardBaseActivity.this));
+ setConfigProgress(getBootstrapProgress());
+ });
+ }
+ }
+
+ protected void setLogs(String torLog, String snowflakeLog, List<String> lastLogs) {
+ if (loadingScreen == null) {
+ return;
+ }
+ torLogAdapter.updateData(lastLogs);
+ torState.setText(torLog);
+ snowflakeState.setText(snowflakeLog);
+ }
+
+ static class TorLogAdapter extends RecyclerView.Adapter<TorLogAdapter.ViewHolder> {
+ private List<String> values;
+ private boolean postponeUpdate;
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ public AppCompatTextView logTextLabel;
+ public View layout;
+
+ public ViewHolder(View v) {
+ super(v);
+ layout = v;
+ logTextLabel = v.findViewById(android.R.id.text1);
+ }
+ }
+
+ public void updateData(List<String> data) {
+ values = data;
+ if (!postponeUpdate) {
+ notifyDataSetChanged();
+ }
+ }
+
+ public TorLogAdapter(List<String> data) {
+ values = data;
+ }
+
+ @NonNull
+ @Override
+ public TorLogAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ LayoutInflater inflater = LayoutInflater.from(
+ parent.getContext());
+ View v = inflater.inflate(R.layout.v_log_item, parent, false);
+ return new TorLogAdapter.ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(TorLogAdapter.ViewHolder holder, final int position) {
+ final String log = values.get(position);
+ holder.logTextLabel.setText(log);
+ }
+
+ @Override
+ public int getItemCount() {
+ return values.size();
+ }
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java
index a8bac6d8..9a5f31f2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java
@@ -17,7 +17,7 @@ public class LoginActivity extends ProviderCredentialsBaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setProgressbarText(R.string.logging_in);
+ setProgressbarTitle(R.string.logging_in);
setProviderHeaderLogo(R.drawable.logo);
setProviderHeaderText(R.string.login_to_profile);
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java
index 40efd811..e429f776 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -29,15 +30,18 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONException;
import org.json.JSONObject;
+import org.torproject.jni.TorService;
import se.leap.bitmaskclient.base.FragmentManagerEnhanced;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.providersetup.ProviderAPICommand;
-import se.leap.bitmaskclient.providersetup.ProviderDetailActivity;
import se.leap.bitmaskclient.providersetup.ProviderApiSetupBroadcastReceiver;
+import se.leap.bitmaskclient.providersetup.ProviderDetailActivity;
import se.leap.bitmaskclient.providersetup.ProviderManager;
import se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog;
import se.leap.bitmaskclient.providersetup.ProviderSetupInterface;
+import se.leap.bitmaskclient.tor.TorServiceCommand;
+import se.leap.bitmaskclient.tor.TorStatusObservable;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_PROVIDER_API_EVENT;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
@@ -51,13 +55,14 @@ import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.Provide
import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SETTING_UP_PROVIDER;
import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SHOWING_PROVIDER_DETAILS;
import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SHOW_FAILED_DIALOG;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF;
/**
* Created by cyberta on 19.08.18.
*/
public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity implements ProviderSetupInterface, ProviderSetupFailedDialog.DownloadFailedDialogInterface {
- final public static String TAG = "PoviderSetupActivity";
+ final public static String TAG = "ProviderSetupActivity";
final private static String ACTIVITY_STATE = "ACTIVITY STATE";
final private static String REASON_TO_FAIL = "REASON TO FAIL";
@@ -86,11 +91,13 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
showProgressBar();
} else if (PENDING_SHOW_FAILED_DIALOG == providerConfigState) {
showProgressBar();
+ hideConnectionDetails();
showDownloadFailedDialog();
} else if (SHOW_FAILED_DIALOG == providerConfigState) {
showProgressBar();
+ hideConnectionDetails();
} else if (SHOWING_PROVIDER_DETAILS == providerConfigState) {
- cancelSettingUpProvider();
+ cancelSettingUpProvider(false);
} else if (PENDING_SHOW_PROVIDER_DETAILS == providerConfigState) {
showProviderDetails();
}
@@ -142,7 +149,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
}
@Override
- public void handleProviderSetupFailed(Bundle resultData) {
+ public void handleError(Bundle resultData) {
reasonToFail = resultData.getString(ERRORS);
showDownloadFailedDialog();
}
@@ -156,9 +163,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
// -------- DownloadFailedDialogInterface ---v
@Override
public void cancelSettingUpProvider() {
- providerConfigState = PROVIDER_NOT_SET;
- provider = null;
- hideProgressBar();
+ cancelSettingUpProvider(true);
}
@Override
@@ -167,6 +172,16 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
ProviderAPICommand.execute(this, UPDATE_PROVIDER_DETAILS, provider);
}
+ public void cancelSettingUpProvider(boolean stopTor) {
+ if (stopTor && TorStatusObservable.getStatus() != OFF) {
+ Log.d(TAG, "SHUTDOWN - cancelSettingUpProvider stopTor:" + stopTor);
+ TorServiceCommand.stopTorServiceAsync(this);
+ }
+ providerConfigState = PROVIDER_NOT_SET;
+ provider = null;
+ hideProgressBar();
+ }
+
protected void restoreState(Bundle savedInstanceState) {
super.restoreState(savedInstanceState);
if (savedInstanceState == null) {
@@ -196,7 +211,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
/**
* Once selected a provider, this fragment offers the user to log in,
* use it anonymously (if possible)
- * or cancel his/her election pressing the back button.
+ * or cancel their selection pressing the back button.
*/
public void showProviderDetails() {
// show only if current activity is shown
@@ -218,6 +233,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity
public void showDownloadFailedDialog() {
try {
providerConfigState = SHOW_FAILED_DIALOG;
+ hideConnectionDetails();
FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(ProviderSetupFailedDialog.TAG);
DialogFragment newFragment;
try {
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java
index c0245845..16007a70 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java
@@ -37,7 +37,7 @@ public class SignupActivity extends ProviderCredentialsBaseActivity {
setProviderHeaderLogo(R.drawable.logo);
setProviderHeaderText(R.string.create_profile);
- setProgressbarText(R.string.signing_up);
+ setProgressbarTitle(R.string.signing_up);
setButtonText(R.string.signup_button);
passwordVerificationField.setVisibility(VISIBLE);