2013-03-26 04:26:03 +00:00
|
|
|
package org.thoughtcrime.securesms;
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
import android.app.ProgressDialog;
|
2013-03-26 04:26:03 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.ComponentName;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.IntentFilter;
|
|
|
|
import android.content.ServiceConnection;
|
|
|
|
import android.graphics.Color;
|
2013-07-08 23:29:28 +00:00
|
|
|
import android.os.AsyncTask;
|
2013-03-26 04:26:03 +00:00
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.IBinder;
|
|
|
|
import android.os.Message;
|
2014-06-29 03:40:57 +00:00
|
|
|
import android.support.v7.app.ActionBarActivity;
|
2013-07-08 23:29:28 +00:00
|
|
|
import android.text.SpannableString;
|
|
|
|
import android.text.Spanned;
|
2014-11-12 19:15:05 +00:00
|
|
|
import android.text.TextUtils;
|
2013-07-08 23:29:28 +00:00
|
|
|
import android.text.method.LinkMovementMethod;
|
|
|
|
import android.text.style.ClickableSpan;
|
|
|
|
import android.util.Log;
|
2013-03-26 04:26:03 +00:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.Button;
|
2013-07-08 23:29:28 +00:00
|
|
|
import android.widget.EditText;
|
2013-03-26 04:26:03 +00:00
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.ProgressBar;
|
|
|
|
import android.widget.RelativeLayout;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
2013-11-20 08:45:51 +00:00
|
|
|
|
2014-11-10 04:35:08 +00:00
|
|
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|
|
|
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
2013-08-15 15:25:30 +00:00
|
|
|
import org.thoughtcrime.securesms.service.RegistrationService;
|
2014-03-01 00:32:00 +00:00
|
|
|
import org.thoughtcrime.securesms.util.Dialogs;
|
2014-02-18 20:48:20 +00:00
|
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
2014-11-12 19:15:05 +00:00
|
|
|
import org.thoughtcrime.securesms.util.Util;
|
2014-11-10 04:35:08 +00:00
|
|
|
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
2014-11-12 19:35:54 +00:00
|
|
|
import org.whispersystems.textsecure.api.push.exceptions.ExpectationFailedException;
|
|
|
|
import org.whispersystems.textsecure.api.push.exceptions.RateLimitException;
|
2014-11-12 19:15:05 +00:00
|
|
|
import org.whispersystems.textsecure.api.util.PhoneNumberFormatter;
|
2013-07-08 23:29:28 +00:00
|
|
|
|
|
|
|
import java.io.IOException;
|
2013-03-26 04:26:03 +00:00
|
|
|
|
|
|
|
import static org.thoughtcrime.securesms.service.RegistrationService.RegistrationState;
|
|
|
|
|
2014-06-29 03:40:57 +00:00
|
|
|
public class RegistrationProgressActivity extends ActionBarActivity {
|
2013-03-26 04:26:03 +00:00
|
|
|
|
|
|
|
private static final int FOCUSED_COLOR = Color.parseColor("#ff333333");
|
|
|
|
private static final int UNFOCUSED_COLOR = Color.parseColor("#ff808080");
|
|
|
|
|
|
|
|
private ServiceConnection serviceConnection = new RegistrationServiceConnection();
|
|
|
|
private Handler registrationStateHandler = new RegistrationStateHandler();
|
|
|
|
private RegistrationReceiver registrationReceiver = new RegistrationReceiver();
|
|
|
|
|
|
|
|
private RegistrationService registrationService;
|
|
|
|
|
|
|
|
private LinearLayout registrationLayout;
|
|
|
|
private LinearLayout verificationFailureLayout;
|
|
|
|
private LinearLayout connectivityFailureLayout;
|
|
|
|
private RelativeLayout timeoutProgressLayout;
|
|
|
|
|
|
|
|
private ProgressBar registrationProgress;
|
|
|
|
private ProgressBar connectingProgress;
|
|
|
|
private ProgressBar verificationProgress;
|
2013-08-15 15:25:30 +00:00
|
|
|
private ProgressBar generatingKeysProgress;
|
2013-03-26 04:26:03 +00:00
|
|
|
private ProgressBar gcmRegistrationProgress;
|
|
|
|
|
2013-08-15 15:25:30 +00:00
|
|
|
|
2013-03-26 04:26:03 +00:00
|
|
|
private ImageView connectingCheck;
|
|
|
|
private ImageView verificationCheck;
|
2013-08-15 15:25:30 +00:00
|
|
|
private ImageView generatingKeysCheck;
|
2013-03-26 04:26:03 +00:00
|
|
|
private ImageView gcmRegistrationCheck;
|
|
|
|
|
|
|
|
private TextView connectingText;
|
|
|
|
private TextView verificationText;
|
|
|
|
private TextView registrationTimerText;
|
2013-08-15 15:25:30 +00:00
|
|
|
private TextView generatingKeysText;
|
2013-03-26 04:26:03 +00:00
|
|
|
private TextView gcmRegistrationText;
|
|
|
|
|
|
|
|
private Button verificationFailureButton;
|
|
|
|
private Button connectivityFailureButton;
|
2013-07-08 23:29:28 +00:00
|
|
|
private Button callButton;
|
|
|
|
private Button verifyButton;
|
|
|
|
|
|
|
|
private EditText codeEditText;
|
2013-03-26 04:26:03 +00:00
|
|
|
|
2013-08-15 15:25:30 +00:00
|
|
|
private MasterSecret masterSecret;
|
2013-03-26 04:26:03 +00:00
|
|
|
private volatile boolean visible;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate(Bundle bundle) {
|
|
|
|
super.onCreate(bundle);
|
2014-04-08 20:14:40 +00:00
|
|
|
getSupportActionBar().setTitle(getString(R.string.RegistrationProgressActivity_verifying_number));
|
2013-03-26 04:26:03 +00:00
|
|
|
setContentView(R.layout.registration_progress_activity);
|
|
|
|
|
|
|
|
initializeResources();
|
2013-07-08 23:29:28 +00:00
|
|
|
initializeLinks();
|
2013-03-26 04:26:03 +00:00
|
|
|
initializeServiceBinding();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
shutdownServiceBinding();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
handleActivityVisible();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
handleActivityNotVisible();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initializeServiceBinding() {
|
|
|
|
Intent intent = new Intent(this, RegistrationService.class);
|
|
|
|
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initializeResources() {
|
2013-08-15 15:25:30 +00:00
|
|
|
this.masterSecret = getIntent().getParcelableExtra("master_secret");
|
2013-03-26 04:26:03 +00:00
|
|
|
this.registrationLayout = (LinearLayout)findViewById(R.id.registering_layout);
|
|
|
|
this.verificationFailureLayout = (LinearLayout)findViewById(R.id.verification_failure_layout);
|
|
|
|
this.connectivityFailureLayout = (LinearLayout)findViewById(R.id.connectivity_failure_layout);
|
|
|
|
this.registrationProgress = (ProgressBar) findViewById(R.id.registration_progress);
|
|
|
|
this.connectingProgress = (ProgressBar) findViewById(R.id.connecting_progress);
|
|
|
|
this.verificationProgress = (ProgressBar) findViewById(R.id.verification_progress);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysProgress = (ProgressBar) findViewById(R.id.generating_keys_progress);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationProgress = (ProgressBar) findViewById(R.id.gcm_registering_progress);
|
|
|
|
this.connectingCheck = (ImageView) findViewById(R.id.connecting_complete);
|
|
|
|
this.verificationCheck = (ImageView) findViewById(R.id.verification_complete);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysCheck = (ImageView) findViewById(R.id.generating_keys_complete);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationCheck = (ImageView) findViewById(R.id.gcm_registering_complete);
|
|
|
|
this.connectingText = (TextView) findViewById(R.id.connecting_text);
|
|
|
|
this.verificationText = (TextView) findViewById(R.id.verification_text);
|
|
|
|
this.registrationTimerText = (TextView) findViewById(R.id.registration_timer);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysText = (TextView) findViewById(R.id.generating_keys_text);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationText = (TextView) findViewById(R.id.gcm_registering_text);
|
|
|
|
this.verificationFailureButton = (Button) findViewById(R.id.verification_failure_edit_button);
|
|
|
|
this.connectivityFailureButton = (Button) findViewById(R.id.connectivity_failure_edit_button);
|
2013-07-08 23:29:28 +00:00
|
|
|
this.callButton = (Button) findViewById(R.id.call_button);
|
|
|
|
this.verifyButton = (Button) findViewById(R.id.verify_button);
|
|
|
|
this.codeEditText = (EditText) findViewById(R.id.telephone_code);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.timeoutProgressLayout = (RelativeLayout) findViewById(R.id.timer_progress_layout);
|
2013-07-08 23:29:28 +00:00
|
|
|
Button editButton = (Button) findViewById(R.id.edit_button);
|
2013-03-26 04:26:03 +00:00
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
editButton.setOnClickListener(new EditButtonListener());
|
2013-03-26 04:26:03 +00:00
|
|
|
this.verificationFailureButton.setOnClickListener(new EditButtonListener());
|
|
|
|
this.connectivityFailureButton.setOnClickListener(new EditButtonListener());
|
|
|
|
}
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
private void initializeLinks() {
|
|
|
|
TextView failureText = (TextView) findViewById(R.id.sms_failed_text);
|
|
|
|
String pretext = getString(R.string.registration_progress_activity__textsecure_timed_out_while_waiting_for_a_verification_sms_message);
|
|
|
|
String link = getString(R.string.RegistrationProblemsActivity_possible_problems);
|
|
|
|
SpannableString spannableString = new SpannableString(pretext + " " + link);
|
|
|
|
|
|
|
|
spannableString.setSpan(new ClickableSpan() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View widget) {
|
|
|
|
Intent intent = new Intent(RegistrationProgressActivity.this,
|
|
|
|
RegistrationProblemsActivity.class);
|
|
|
|
startActivity(intent);
|
|
|
|
}
|
|
|
|
}, pretext.length() + 1, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
|
|
|
failureText.setText(spannableString);
|
|
|
|
failureText.setMovementMethod(LinkMovementMethod.getInstance());
|
|
|
|
}
|
|
|
|
|
2013-03-26 04:26:03 +00:00
|
|
|
private void handleActivityVisible() {
|
|
|
|
IntentFilter filter = new IntentFilter(RegistrationService.REGISTRATION_EVENT);
|
|
|
|
filter.setPriority(1000);
|
|
|
|
registerReceiver(registrationReceiver, filter);
|
|
|
|
visible = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleActivityNotVisible() {
|
|
|
|
unregisterReceiver(registrationReceiver);
|
|
|
|
visible = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleStateIdle() {
|
|
|
|
if (hasNumberDirective()) {
|
|
|
|
Intent intent = new Intent(this, RegistrationService.class);
|
|
|
|
intent.setAction(RegistrationService.REGISTER_NUMBER_ACTION);
|
|
|
|
intent.putExtra("e164number", getNumberDirective());
|
2013-08-15 15:25:30 +00:00
|
|
|
intent.putExtra("master_secret", masterSecret);
|
2013-03-26 04:26:03 +00:00
|
|
|
startService(intent);
|
|
|
|
} else {
|
2013-08-22 00:25:19 +00:00
|
|
|
Intent intent = new Intent(this, RegistrationActivity.class);
|
|
|
|
intent.putExtra("master_secret", masterSecret);
|
|
|
|
startActivity(intent);
|
2013-03-26 04:26:03 +00:00
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleStateConnecting() {
|
|
|
|
this.registrationLayout.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectingProgress.setVisibility(View.VISIBLE);
|
|
|
|
this.connectingCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.verificationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.verificationCheck.setVisibility(View.INVISIBLE);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.generatingKeysCheck.setVisibility(View.INVISIBLE);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingText.setTextColor(FOCUSED_COLOR);
|
|
|
|
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysText.setTextColor(UNFOCUSED_COLOR);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.timeoutProgressLayout.setVisibility(View.VISIBLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleStateVerifying() {
|
|
|
|
this.registrationLayout.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectingProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingCheck.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationProgress.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationCheck.setVisibility(View.INVISIBLE);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.generatingKeysCheck.setVisibility(View.INVISIBLE);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.verificationText.setTextColor(FOCUSED_COLOR);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysText.setTextColor(UNFOCUSED_COLOR);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.registrationProgress.setVisibility(View.VISIBLE);
|
|
|
|
this.timeoutProgressLayout.setVisibility(View.VISIBLE);
|
|
|
|
}
|
|
|
|
|
2013-08-15 15:25:30 +00:00
|
|
|
private void handleStateGeneratingKeys() {
|
|
|
|
this.registrationLayout.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectingProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingCheck.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.verificationCheck.setVisibility(View.VISIBLE);
|
|
|
|
this.generatingKeysProgress.setVisibility(View.VISIBLE);
|
|
|
|
this.generatingKeysCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.generatingKeysText.setTextColor(FOCUSED_COLOR);
|
|
|
|
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.registrationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.timeoutProgressLayout.setVisibility(View.INVISIBLE);
|
|
|
|
}
|
|
|
|
|
2013-03-26 04:26:03 +00:00
|
|
|
private void handleStateGcmRegistering() {
|
|
|
|
this.registrationLayout.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectingProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingCheck.setVisibility(View.VISIBLE);
|
|
|
|
this.verificationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.verificationCheck.setVisibility(View.VISIBLE);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.generatingKeysCheck.setVisibility(View.VISIBLE);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationProgress.setVisibility(View.VISIBLE);
|
|
|
|
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
|
|
|
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
|
|
|
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
2013-08-15 15:25:30 +00:00
|
|
|
this.generatingKeysText.setTextColor(UNFOCUSED_COLOR);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.gcmRegistrationText.setTextColor(FOCUSED_COLOR);
|
|
|
|
this.registrationProgress.setVisibility(View.INVISIBLE);
|
|
|
|
this.timeoutProgressLayout.setVisibility(View.INVISIBLE);
|
|
|
|
}
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
private void handleGcmTimeout(RegistrationState state) {
|
|
|
|
handleConnectivityError(state);
|
2013-04-01 02:16:06 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
private void handleVerificationRequestedVoice(RegistrationState state) {
|
|
|
|
handleVerificationTimeout(state);
|
|
|
|
verifyButton.setOnClickListener(new VerifyClickListener(state.number, state.password));
|
|
|
|
verifyButton.setEnabled(true);
|
|
|
|
codeEditText.setEnabled(true);
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
private void handleVerificationTimeout(RegistrationState state) {
|
|
|
|
this.callButton.setOnClickListener(new CallClickListener(state.number));
|
|
|
|
this.verifyButton.setEnabled(false);
|
|
|
|
this.codeEditText.setEnabled(false);
|
2013-03-26 04:26:03 +00:00
|
|
|
this.registrationLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.VISIBLE);
|
2013-07-08 23:29:28 +00:00
|
|
|
this.verificationFailureButton.setText(String.format(getString(R.string.RegistrationProgressActivity_edit_s),
|
|
|
|
PhoneNumberFormatter.formatNumberInternational(state.number)));
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
private void handleConnectivityError(RegistrationState state) {
|
2013-03-26 04:26:03 +00:00
|
|
|
this.registrationLayout.setVisibility(View.GONE);
|
|
|
|
this.verificationFailureLayout.setVisibility(View.GONE);
|
|
|
|
this.connectivityFailureLayout.setVisibility(View.VISIBLE);
|
2013-07-08 23:29:28 +00:00
|
|
|
this.connectivityFailureButton.setText(String.format(getString(R.string.RegistrationProgressActivity_edit_s),
|
|
|
|
PhoneNumberFormatter.formatNumberInternational(state.number)));
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|
|
|
|
|
2014-02-26 00:59:56 +00:00
|
|
|
private void handleMultiRegistrationError(RegistrationState state) {
|
|
|
|
handleVerificationTimeout(state);
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(this, getString(R.string.RegistrationProgressActivity_registration_conflict),
|
2014-02-26 00:59:56 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_this_number_is_already_registered_on_a_different));
|
|
|
|
}
|
|
|
|
|
2013-03-26 04:26:03 +00:00
|
|
|
private void handleVerificationComplete() {
|
|
|
|
if (visible) {
|
2013-07-08 23:29:28 +00:00
|
|
|
Toast.makeText(this,
|
|
|
|
R.string.RegistrationProgressActivity_registration_complete,
|
|
|
|
Toast.LENGTH_LONG).show();
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shutdownService();
|
|
|
|
startActivity(new Intent(this, RoutingActivity.class));
|
|
|
|
finish();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleTimerUpdate() {
|
|
|
|
if (registrationService == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int totalSecondsRemaining = registrationService.getSecondsRemaining();
|
|
|
|
int minutesRemaining = totalSecondsRemaining / 60;
|
|
|
|
int secondsRemaining = totalSecondsRemaining - (minutesRemaining * 60);
|
|
|
|
double percentageComplete = (double)((60 * 2) - totalSecondsRemaining) / (double)(60 * 2);
|
|
|
|
int progress = (int)Math.round(((double)registrationProgress.getMax()) * percentageComplete);
|
|
|
|
|
|
|
|
this.registrationProgress.setProgress(progress);
|
|
|
|
this.registrationTimerText.setText(String.format("%02d:%02d", minutesRemaining, secondsRemaining));
|
|
|
|
|
|
|
|
registrationStateHandler.sendEmptyMessageDelayed(RegistrationState.STATE_TIMER, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean hasNumberDirective() {
|
|
|
|
return getIntent().getStringExtra("e164number") != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getNumberDirective() {
|
|
|
|
return getIntent().getStringExtra("e164number");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void shutdownServiceBinding() {
|
|
|
|
if (serviceConnection != null) {
|
|
|
|
unbindService(serviceConnection);
|
|
|
|
serviceConnection = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void shutdownService() {
|
|
|
|
if (registrationService != null) {
|
|
|
|
registrationService.shutdown();
|
|
|
|
registrationService = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
shutdownServiceBinding();
|
|
|
|
|
|
|
|
Intent serviceIntent = new Intent(RegistrationProgressActivity.this, RegistrationService.class);
|
|
|
|
stopService(serviceIntent);
|
|
|
|
}
|
|
|
|
|
|
|
|
private class RegistrationServiceConnection implements ServiceConnection {
|
|
|
|
@Override
|
|
|
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
|
|
|
registrationService = ((RegistrationService.RegistrationServiceBinder)service).getService();
|
|
|
|
registrationService.setRegistrationStateHandler(registrationStateHandler);
|
|
|
|
|
|
|
|
RegistrationState state = registrationService.getRegistrationState();
|
2013-07-08 23:29:28 +00:00
|
|
|
registrationStateHandler.obtainMessage(state.state, state).sendToTarget();
|
2013-03-26 04:26:03 +00:00
|
|
|
|
|
|
|
handleTimerUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onServiceDisconnected(ComponentName name) {
|
|
|
|
registrationService.setRegistrationStateHandler(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class RegistrationStateHandler extends Handler {
|
|
|
|
@Override
|
|
|
|
public void handleMessage(Message message) {
|
2013-07-08 23:29:28 +00:00
|
|
|
RegistrationState state = (RegistrationState)message.obj;
|
|
|
|
|
2013-03-26 04:26:03 +00:00
|
|
|
switch (message.what) {
|
2013-07-08 23:29:28 +00:00
|
|
|
case RegistrationState.STATE_IDLE: handleStateIdle(); break;
|
|
|
|
case RegistrationState.STATE_CONNECTING: handleStateConnecting(); break;
|
|
|
|
case RegistrationState.STATE_VERIFYING: handleStateVerifying(); break;
|
|
|
|
case RegistrationState.STATE_TIMER: handleTimerUpdate(); break;
|
2013-08-15 15:25:30 +00:00
|
|
|
case RegistrationState.STATE_GENERATING_KEYS: handleStateGeneratingKeys(); break;
|
2013-07-08 23:29:28 +00:00
|
|
|
case RegistrationState.STATE_GCM_REGISTERING: handleStateGcmRegistering(); break;
|
|
|
|
case RegistrationState.STATE_TIMEOUT: handleVerificationTimeout(state); break;
|
|
|
|
case RegistrationState.STATE_COMPLETE: handleVerificationComplete(); break;
|
|
|
|
case RegistrationState.STATE_GCM_TIMEOUT: handleGcmTimeout(state); break;
|
|
|
|
case RegistrationState.STATE_NETWORK_ERROR: handleConnectivityError(state); break;
|
2014-02-26 00:59:56 +00:00
|
|
|
case RegistrationState.STATE_MULTI_REGISTERED: handleMultiRegistrationError(state); break;
|
2013-07-08 23:29:28 +00:00
|
|
|
case RegistrationState.STATE_VOICE_REQUESTED: handleVerificationRequestedVoice(state); break;
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class EditButtonListener implements View.OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
shutdownService();
|
|
|
|
|
|
|
|
Intent activityIntent = new Intent(RegistrationProgressActivity.this, RegistrationActivity.class);
|
2013-08-22 00:25:19 +00:00
|
|
|
activityIntent.putExtra("master_secret", masterSecret);
|
2013-03-26 04:26:03 +00:00
|
|
|
startActivity(activityIntent);
|
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class RegistrationReceiver extends BroadcastReceiver {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
abortBroadcast();
|
|
|
|
}
|
|
|
|
}
|
2013-07-08 23:29:28 +00:00
|
|
|
|
|
|
|
private class VerifyClickListener implements View.OnClickListener {
|
|
|
|
|
2014-02-26 00:59:56 +00:00
|
|
|
private static final int SUCCESS = 0;
|
|
|
|
private static final int NETWORK_ERROR = 1;
|
|
|
|
private static final int RATE_LIMIT_ERROR = 2;
|
|
|
|
private static final int VERIFICATION_ERROR = 3;
|
|
|
|
private static final int MULTI_REGISTRATION_ERROR = 4;
|
2013-07-08 23:29:28 +00:00
|
|
|
|
|
|
|
private final String e164number;
|
|
|
|
private final String password;
|
2013-08-28 22:35:30 +00:00
|
|
|
private final String signalingKey;
|
2013-07-08 23:29:28 +00:00
|
|
|
private final Context context;
|
|
|
|
|
|
|
|
private ProgressDialog progressDialog;
|
|
|
|
|
|
|
|
public VerifyClickListener(String e164number, String password) {
|
2013-08-28 22:35:30 +00:00
|
|
|
this.e164number = e164number;
|
|
|
|
this.password = password;
|
|
|
|
this.signalingKey = Util.getSecret(52);
|
|
|
|
this.context = RegistrationProgressActivity.this;
|
2013-07-08 23:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
final String code = codeEditText.getText().toString();
|
|
|
|
|
2014-11-12 19:15:05 +00:00
|
|
|
if (TextUtils.isEmpty(code)) {
|
2013-07-08 23:29:28 +00:00
|
|
|
Toast.makeText(context,
|
|
|
|
getString(R.string.RegistrationProgressActivity_you_must_enter_the_code_you_received_first),
|
|
|
|
Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
new AsyncTask<Void, Void, Integer>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPreExecute() {
|
|
|
|
progressDialog = ProgressDialog.show(context,
|
|
|
|
getString(R.string.RegistrationProgressActivity_connecting),
|
|
|
|
getString(R.string.RegistrationProgressActivity_connecting_for_verification),
|
|
|
|
true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Integer result) {
|
|
|
|
if (progressDialog != null) progressDialog.dismiss();
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case SUCCESS:
|
|
|
|
Intent intent = new Intent(context, RegistrationService.class);
|
|
|
|
intent.setAction(RegistrationService.VOICE_REGISTER_ACTION);
|
|
|
|
intent.putExtra("e164number", e164number);
|
|
|
|
intent.putExtra("password", password);
|
2013-08-28 22:35:30 +00:00
|
|
|
intent.putExtra("signaling_key", signalingKey);
|
2013-08-15 15:25:30 +00:00
|
|
|
intent.putExtra("master_secret", masterSecret);
|
2013-07-08 23:29:28 +00:00
|
|
|
startService(intent);
|
|
|
|
break;
|
|
|
|
case NETWORK_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_network_error),
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_unable_to_connect));
|
|
|
|
break;
|
|
|
|
case VERIFICATION_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_verification_failed),
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_the_verification_code_you_submitted_is_incorrect));
|
|
|
|
break;
|
|
|
|
case RATE_LIMIT_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_too_many_attempts),
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_youve_submitted_an_incorrect_verification_code_too_many_times));
|
|
|
|
break;
|
2014-02-26 00:59:56 +00:00
|
|
|
case MULTI_REGISTRATION_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_registration_conflict),
|
2014-02-26 00:59:56 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_this_number_is_already_registered_on_a_different));
|
|
|
|
break;
|
2013-07-08 23:29:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Integer doInBackground(Void... params) {
|
|
|
|
try {
|
2014-11-12 20:10:56 +00:00
|
|
|
TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context, e164number, password);
|
2014-02-18 20:48:20 +00:00
|
|
|
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
2014-11-10 04:35:08 +00:00
|
|
|
|
|
|
|
accountManager.verifyAccount(code, signalingKey, true, registrationId);
|
|
|
|
|
2013-07-08 23:29:28 +00:00
|
|
|
return SUCCESS;
|
2014-02-26 00:59:56 +00:00
|
|
|
} catch (ExpectationFailedException e) {
|
|
|
|
Log.w("RegistrationProgressActivity", e);
|
|
|
|
return MULTI_REGISTRATION_ERROR;
|
2013-07-08 23:29:28 +00:00
|
|
|
} catch (RateLimitException e) {
|
|
|
|
Log.w("RegistrationProgressActivity", e);
|
|
|
|
return RATE_LIMIT_ERROR;
|
2013-07-19 00:42:45 +00:00
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w("RegistrationProgressActivity", e);
|
|
|
|
return NETWORK_ERROR;
|
2013-07-08 23:29:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class CallClickListener implements View.OnClickListener {
|
|
|
|
|
|
|
|
private static final int SUCCESS = 0;
|
|
|
|
private static final int NETWORK_ERROR = 1;
|
|
|
|
private static final int RATE_LIMIT_EXCEEDED = 2;
|
|
|
|
private static final int CREATE_ERROR = 3;
|
|
|
|
|
|
|
|
private final String e164number;
|
|
|
|
private final String password;
|
|
|
|
private final Context context;
|
|
|
|
|
|
|
|
public CallClickListener(String e164number) {
|
2013-08-28 22:35:30 +00:00
|
|
|
this.e164number = e164number;
|
|
|
|
this.password = Util.getSecret(18);
|
|
|
|
this.context = RegistrationProgressActivity.this;
|
2013-07-08 23:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
new AsyncTask<Void, Void, Integer>() {
|
|
|
|
private ProgressDialog progressDialog;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPreExecute() {
|
|
|
|
progressDialog = ProgressDialog.show(context,
|
|
|
|
getString(R.string.RegistrationProgressActivity_requesting_call),
|
|
|
|
getString(R.string.RegistrationProgressActivity_requesting_incoming_call),
|
|
|
|
true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Integer result) {
|
|
|
|
if (progressDialog != null) progressDialog.dismiss();
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case SUCCESS:
|
|
|
|
Intent intent = new Intent(context, RegistrationService.class);
|
|
|
|
intent.setAction(RegistrationService.VOICE_REQUESTED_ACTION);
|
|
|
|
intent.putExtra("e164number", e164number);
|
|
|
|
intent.putExtra("password", password);
|
2013-08-15 15:25:30 +00:00
|
|
|
intent.putExtra("master_secret", masterSecret);
|
2013-07-08 23:29:28 +00:00
|
|
|
startService(intent);
|
|
|
|
|
|
|
|
callButton.setEnabled(false);
|
|
|
|
new Handler().postDelayed(new Runnable(){
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
callButton.setEnabled(true);
|
|
|
|
}
|
|
|
|
}, 15000);
|
|
|
|
break;
|
|
|
|
case NETWORK_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context,
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_network_error),
|
|
|
|
getString(R.string.RegistrationProgressActivity_unable_to_connect));
|
|
|
|
break;
|
|
|
|
case CREATE_ERROR:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context,
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_server_error),
|
|
|
|
getString(R.string.RegistrationProgressActivity_the_server_encountered_an_error));
|
|
|
|
break;
|
|
|
|
case RATE_LIMIT_EXCEEDED:
|
2014-03-01 00:32:00 +00:00
|
|
|
Dialogs.showAlertDialog(context,
|
2013-07-08 23:29:28 +00:00
|
|
|
getString(R.string.RegistrationProgressActivity_too_many_requests),
|
|
|
|
getString(R.string.RegistrationProgressActivity_youve_already_requested_a_voice_call));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Integer doInBackground(Void... params) {
|
|
|
|
try {
|
2014-11-12 20:10:56 +00:00
|
|
|
TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context, e164number, password);
|
2014-11-10 04:35:08 +00:00
|
|
|
accountManager.requestVoiceVerificationCode();
|
2013-07-08 23:29:28 +00:00
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
} catch (RateLimitException e) {
|
|
|
|
Log.w("RegistrationProgressActivity", e);
|
|
|
|
return RATE_LIMIT_EXCEEDED;
|
2013-07-19 00:42:45 +00:00
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w("RegistrationProgressActivity", e);
|
|
|
|
return NETWORK_ERROR;
|
2013-07-08 23:29:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2013-03-26 04:26:03 +00:00
|
|
|
}
|