mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 09:22:23 +00:00
Registration with voice verification.
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockActivity;
|
||||
|
||||
public class RegistrationProblemsActivity extends SherlockActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.registration_problems);
|
||||
setTitle(getString(R.string.RegistrationProblemsActivity_possible_problems));
|
||||
|
||||
((Button)findViewById(R.id.close_button)).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -7,12 +8,19 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
@@ -21,8 +29,13 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockActivity;
|
||||
import org.thoughtcrime.securesms.gcm.PushServiceSocket;
|
||||
import org.thoughtcrime.securesms.gcm.RateLimitException;
|
||||
import org.thoughtcrime.securesms.service.RegistrationService;
|
||||
import org.thoughtcrime.securesms.util.PhoneNumberFormatter;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.thoughtcrime.securesms.service.RegistrationService.RegistrationState;
|
||||
|
||||
@@ -46,32 +59,33 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
private ProgressBar connectingProgress;
|
||||
private ProgressBar verificationProgress;
|
||||
private ProgressBar gcmRegistrationProgress;
|
||||
private ProgressBar retrieveDirectoryProgress;
|
||||
|
||||
private ImageView connectingCheck;
|
||||
private ImageView verificationCheck;
|
||||
private ImageView gcmRegistrationCheck;
|
||||
private ImageView retrieveDirectoryCheck;
|
||||
|
||||
private TextView connectingText;
|
||||
private TextView verificationText;
|
||||
private TextView registrationTimerText;
|
||||
private TextView gcmRegistrationText;
|
||||
private TextView retrieveDirectoryText;
|
||||
|
||||
private Button editButton;
|
||||
private Button verificationFailureButton;
|
||||
private Button connectivityFailureButton;
|
||||
private Button callButton;
|
||||
private Button verifyButton;
|
||||
|
||||
private EditText codeEditText;
|
||||
|
||||
private volatile boolean visible;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
this.getSupportActionBar().setTitle("Verifying number");
|
||||
this.getSupportActionBar().setTitle(getString(R.string.RegistrationProgressActivity_verifying_number));
|
||||
setContentView(R.layout.registration_progress_activity);
|
||||
|
||||
initializeResources();
|
||||
initializeLinks();
|
||||
initializeServiceBinding();
|
||||
}
|
||||
|
||||
@@ -111,27 +125,45 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
this.connectingProgress = (ProgressBar) findViewById(R.id.connecting_progress);
|
||||
this.verificationProgress = (ProgressBar) findViewById(R.id.verification_progress);
|
||||
this.gcmRegistrationProgress = (ProgressBar) findViewById(R.id.gcm_registering_progress);
|
||||
this.retrieveDirectoryProgress = (ProgressBar) findViewById(R.id.retrieve_directory_progress);
|
||||
this.connectingCheck = (ImageView) findViewById(R.id.connecting_complete);
|
||||
this.verificationCheck = (ImageView) findViewById(R.id.verification_complete);
|
||||
this.gcmRegistrationCheck = (ImageView) findViewById(R.id.gcm_registering_complete);
|
||||
this.retrieveDirectoryCheck = (ImageView) findViewById(R.id.retrieve_directory_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);
|
||||
this.gcmRegistrationText = (TextView) findViewById(R.id.gcm_registering_text);
|
||||
this.retrieveDirectoryText = (TextView) findViewById(R.id.retrieve_directory_text);
|
||||
this.editButton = (Button) findViewById(R.id.edit_button);
|
||||
this.verificationFailureButton = (Button) findViewById(R.id.verification_failure_edit_button);
|
||||
this.connectivityFailureButton = (Button) findViewById(R.id.connectivity_failure_edit_button);
|
||||
this.callButton = (Button) findViewById(R.id.call_button);
|
||||
this.verifyButton = (Button) findViewById(R.id.verify_button);
|
||||
this.codeEditText = (EditText) findViewById(R.id.telephone_code);
|
||||
this.timeoutProgressLayout = (RelativeLayout) findViewById(R.id.timer_progress_layout);
|
||||
Button editButton = (Button) findViewById(R.id.edit_button);
|
||||
|
||||
|
||||
this.editButton.setOnClickListener(new EditButtonListener());
|
||||
editButton.setOnClickListener(new EditButtonListener());
|
||||
this.verificationFailureButton.setOnClickListener(new EditButtonListener());
|
||||
this.connectivityFailureButton.setOnClickListener(new EditButtonListener());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
private void handleActivityVisible() {
|
||||
IntentFilter filter = new IntentFilter(RegistrationService.REGISTRATION_EVENT);
|
||||
filter.setPriority(1000);
|
||||
@@ -166,12 +198,9 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
this.verificationCheck.setVisibility(View.INVISIBLE);
|
||||
this.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
||||
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryProgress.setVisibility(View.INVISIBLE);
|
||||
this.connectingText.setTextColor(FOCUSED_COLOR);
|
||||
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.retrieveDirectoryText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.timeoutProgressLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@@ -185,12 +214,9 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
this.verificationCheck.setVisibility(View.INVISIBLE);
|
||||
this.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
||||
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryProgress.setVisibility(View.INVISIBLE);
|
||||
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.verificationText.setTextColor(FOCUSED_COLOR);
|
||||
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.retrieveDirectoryText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.registrationProgress.setVisibility(View.VISIBLE);
|
||||
this.timeoutProgressLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
@@ -205,60 +231,48 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
this.verificationCheck.setVisibility(View.VISIBLE);
|
||||
this.gcmRegistrationProgress.setVisibility(View.VISIBLE);
|
||||
this.gcmRegistrationCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryProgress.setVisibility(View.INVISIBLE);
|
||||
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.gcmRegistrationText.setTextColor(FOCUSED_COLOR);
|
||||
this.retrieveDirectoryText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.registrationProgress.setVisibility(View.INVISIBLE);
|
||||
this.timeoutProgressLayout.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
private void handleStateRetrievingDirectory() {
|
||||
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.gcmRegistrationProgress.setVisibility(View.INVISIBLE);
|
||||
this.gcmRegistrationCheck.setVisibility(View.VISIBLE);
|
||||
this.retrieveDirectoryCheck.setVisibility(View.INVISIBLE);
|
||||
this.retrieveDirectoryProgress.setVisibility(View.VISIBLE);
|
||||
this.connectingText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.verificationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.gcmRegistrationText.setTextColor(UNFOCUSED_COLOR);
|
||||
this.retrieveDirectoryText.setTextColor(FOCUSED_COLOR);
|
||||
this.registrationProgress.setVisibility(View.INVISIBLE);
|
||||
this.timeoutProgressLayout.setVisibility(View.INVISIBLE);
|
||||
private void handleGcmTimeout(RegistrationState state) {
|
||||
handleConnectivityError(state);
|
||||
}
|
||||
|
||||
|
||||
private void handleGcmTimeout(String number) {
|
||||
handleConnectivityError(number);
|
||||
private void handleVerificationRequestedVoice(RegistrationState state) {
|
||||
handleVerificationTimeout(state);
|
||||
verifyButton.setOnClickListener(new VerifyClickListener(state.number, state.password));
|
||||
verifyButton.setEnabled(true);
|
||||
codeEditText.setEnabled(true);
|
||||
}
|
||||
|
||||
private void handleVerificationTimeout(String number) {
|
||||
private void handleVerificationTimeout(RegistrationState state) {
|
||||
this.callButton.setOnClickListener(new CallClickListener(state.number));
|
||||
this.verifyButton.setEnabled(false);
|
||||
this.codeEditText.setEnabled(false);
|
||||
this.registrationLayout.setVisibility(View.GONE);
|
||||
this.connectivityFailureLayout.setVisibility(View.GONE);
|
||||
this.verificationFailureLayout.setVisibility(View.VISIBLE);
|
||||
this.verificationFailureButton.setText(String.format("Edit %s",
|
||||
PhoneNumberFormatter.formatNumberInternational(number)));
|
||||
this.verificationFailureButton.setText(String.format(getString(R.string.RegistrationProgressActivity_edit_s),
|
||||
PhoneNumberFormatter.formatNumberInternational(state.number)));
|
||||
}
|
||||
|
||||
private void handleConnectivityError(String number) {
|
||||
private void handleConnectivityError(RegistrationState state) {
|
||||
this.registrationLayout.setVisibility(View.GONE);
|
||||
this.verificationFailureLayout.setVisibility(View.GONE);
|
||||
this.connectivityFailureLayout.setVisibility(View.VISIBLE);
|
||||
this.connectivityFailureButton.setText(String.format("Edit %s",
|
||||
PhoneNumberFormatter.formatNumberInternational(number)));
|
||||
this.connectivityFailureButton.setText(String.format(getString(R.string.RegistrationProgressActivity_edit_s),
|
||||
PhoneNumberFormatter.formatNumberInternational(state.number)));
|
||||
}
|
||||
|
||||
private void handleVerificationComplete() {
|
||||
if (visible) {
|
||||
Toast.makeText(this, "Registration complete", Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(this,
|
||||
R.string.RegistrationProgressActivity_registration_complete,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
shutdownService();
|
||||
@@ -316,7 +330,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
registrationService.setRegistrationStateHandler(registrationStateHandler);
|
||||
|
||||
RegistrationState state = registrationService.getRegistrationState();
|
||||
registrationStateHandler.obtainMessage(state.state, state.number).sendToTarget();
|
||||
registrationStateHandler.obtainMessage(state.state, state).sendToTarget();
|
||||
|
||||
handleTimerUpdate();
|
||||
}
|
||||
@@ -330,17 +344,19 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
private class RegistrationStateHandler extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
RegistrationState state = (RegistrationState)message.obj;
|
||||
|
||||
switch (message.what) {
|
||||
case RegistrationState.STATE_IDLE: handleStateIdle(); break;
|
||||
case RegistrationState.STATE_CONNECTING: handleStateConnecting(); break;
|
||||
case RegistrationState.STATE_VERIFYING: handleStateVerifying(); break;
|
||||
case RegistrationState.STATE_TIMER: handleTimerUpdate(); break;
|
||||
case RegistrationState.STATE_GCM_REGISTERING: handleStateGcmRegistering(); break;
|
||||
case RegistrationState.STATE_RETRIEVING_DIRECTORY: handleStateRetrievingDirectory(); break;
|
||||
case RegistrationState.STATE_TIMEOUT: handleVerificationTimeout((String)message.obj); break;
|
||||
case RegistrationState.STATE_COMPLETE: handleVerificationComplete(); break;
|
||||
case RegistrationState.STATE_GCM_TIMEOUT: handleGcmTimeout((String)message.obj); break;
|
||||
case RegistrationState.STATE_NETWORK_ERROR: handleConnectivityError((String)message.obj); break;
|
||||
case RegistrationState.STATE_IDLE: handleStateIdle(); break;
|
||||
case RegistrationState.STATE_CONNECTING: handleStateConnecting(); break;
|
||||
case RegistrationState.STATE_VERIFYING: handleStateVerifying(); break;
|
||||
case RegistrationState.STATE_TIMER: handleTimerUpdate(); break;
|
||||
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;
|
||||
case RegistrationState.STATE_VOICE_REQUESTED: handleVerificationRequestedVoice(state); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,4 +378,177 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
||||
abortBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
private class VerifyClickListener implements View.OnClickListener {
|
||||
|
||||
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 final String e164number;
|
||||
private final String password;
|
||||
private final Context context;
|
||||
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
public VerifyClickListener(String e164number, String password) {
|
||||
this.e164number = e164number;
|
||||
this.password = password;
|
||||
this.context = RegistrationProgressActivity.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final String code = codeEditText.getText().toString();
|
||||
|
||||
if (Util.isEmpty(code)) {
|
||||
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);
|
||||
startService(intent);
|
||||
break;
|
||||
case NETWORK_ERROR:
|
||||
Util.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_network_error),
|
||||
getString(R.string.RegistrationProgressActivity_unable_to_connect));
|
||||
break;
|
||||
case VERIFICATION_ERROR:
|
||||
Util.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_verification_failed),
|
||||
getString(R.string.RegistrationProgressActivity_the_verification_code_you_submitted_is_incorrect));
|
||||
break;
|
||||
case RATE_LIMIT_ERROR:
|
||||
Util.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_too_many_attempts),
|
||||
getString(R.string.RegistrationProgressActivity_youve_submitted_an_incorrect_verification_code_too_many_times));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(Void... params) {
|
||||
try {
|
||||
PushServiceSocket socket = new PushServiceSocket(context, e164number, password);
|
||||
socket.verifyAccount(code);
|
||||
return SUCCESS;
|
||||
} catch (IOException e) {
|
||||
Log.w("RegistrationProgressActivity", e);
|
||||
return NETWORK_ERROR;
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("RegistrationProgressActivity", e);
|
||||
return RATE_LIMIT_ERROR;
|
||||
}
|
||||
}
|
||||
}.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) {
|
||||
this.e164number = e164number;
|
||||
this.password = Util.getSecret(18);
|
||||
this.context = RegistrationProgressActivity.this;
|
||||
}
|
||||
|
||||
@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);
|
||||
startService(intent);
|
||||
|
||||
callButton.setEnabled(false);
|
||||
new Handler().postDelayed(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
callButton.setEnabled(true);
|
||||
}
|
||||
}, 15000);
|
||||
break;
|
||||
case NETWORK_ERROR:
|
||||
Util.showAlertDialog(context,
|
||||
getString(R.string.RegistrationProgressActivity_network_error),
|
||||
getString(R.string.RegistrationProgressActivity_unable_to_connect));
|
||||
break;
|
||||
case CREATE_ERROR:
|
||||
Util.showAlertDialog(context,
|
||||
getString(R.string.RegistrationProgressActivity_server_error),
|
||||
getString(R.string.RegistrationProgressActivity_the_server_encountered_an_error));
|
||||
break;
|
||||
case RATE_LIMIT_EXCEEDED:
|
||||
Util.showAlertDialog(context,
|
||||
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 {
|
||||
PushServiceSocket socket = new PushServiceSocket(context, e164number, password);
|
||||
socket.createAccount(true);
|
||||
|
||||
return SUCCESS;
|
||||
} catch (IOException e) {
|
||||
Log.w("RegistrationProgressActivity", e);
|
||||
return NETWORK_ERROR;
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("RegistrationProgressActivity", e);
|
||||
return RATE_LIMIT_EXCEEDED;
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
7
src/org/thoughtcrime/securesms/Release.java
Normal file
7
src/org/thoughtcrime/securesms/Release.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
public class Release {
|
||||
public static final String PUSH_SERVICE_URL = "https://gcm.textsecure.whispersystems.org";
|
||||
// public static final String PUSH_SERVICE_URL = "http://192.168.1.135:8080";
|
||||
public static final boolean ENFORCE_SSL = true;
|
||||
}
|
||||
@@ -65,15 +65,19 @@ public class RoutingActivity extends PassphraseRequiredSherlockActivity {
|
||||
}
|
||||
|
||||
private void routeApplicationState() {
|
||||
int state = getApplicationState();
|
||||
|
||||
switch (state) {
|
||||
case STATE_CREATE_PASSPHRASE: handleCreatePassphrase(); break;
|
||||
case STATE_PROMPT_PASSPHRASE: handlePromptPassphrase(); break;
|
||||
case STATE_IMPORT_DATABASE: handleImportDatabase(); break;
|
||||
case STATE_CONVERSATION_OR_LIST: handleDisplayConversationOrList(); break;
|
||||
case STATE_UPGRADE_DATABASE: handleUpgradeDatabase(); break;
|
||||
}
|
||||
Intent intent = new Intent(this, RegistrationActivity.class);
|
||||
startActivity(intent);
|
||||
return;
|
||||
//
|
||||
// int state = getApplicationState();
|
||||
//
|
||||
// switch (state) {
|
||||
// case STATE_CREATE_PASSPHRASE: handleCreatePassphrase(); break;
|
||||
// case STATE_PROMPT_PASSPHRASE: handlePromptPassphrase(); break;
|
||||
// case STATE_IMPORT_DATABASE: handleImportDatabase(); break;
|
||||
// case STATE_CONVERSATION_OR_LIST: handleDisplayConversationOrList(); break;
|
||||
// case STATE_UPGRADE_DATABASE: handleUpgradeDatabase(); break;
|
||||
// }
|
||||
}
|
||||
|
||||
private void handleCreatePassphrase() {
|
||||
|
||||
@@ -33,6 +33,8 @@ public class GcmIntentService extends GCMBaseIntentService {
|
||||
getGcmSocket(context).registerGcmId(registrationId);
|
||||
} catch (IOException e) {
|
||||
Log.w("GcmIntentService", e);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("GcmIntentService", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +45,8 @@ public class GcmIntentService extends GCMBaseIntentService {
|
||||
getGcmSocket(context).unregisterGcmId(registrationId);
|
||||
} catch (IOException ioe) {
|
||||
Log.w("GcmIntentService", ioe);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("GcmIntentService", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,10 +75,10 @@ public class GcmIntentService extends GCMBaseIntentService {
|
||||
Log.w("GcmIntentService", "GCM Error: " + s);
|
||||
}
|
||||
|
||||
private GcmSocket getGcmSocket(Context context) {
|
||||
private PushServiceSocket getGcmSocket(Context context) {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String localNumber = preferences.getString(ApplicationPreferencesActivity.LOCAL_NUMBER_PREF, null);
|
||||
String password = preferences.getString(ApplicationPreferencesActivity.GCM_PASSWORD_PREF, null);
|
||||
return new GcmSocket(context, localNumber, password);
|
||||
return new PushServiceSocket(context, localNumber, password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ public class OptimizingTransport {
|
||||
return;
|
||||
}
|
||||
|
||||
GcmSocket gcmSocket = new GcmSocket(context, localNumber, password);
|
||||
gcmSocket.sendMessage(PhoneNumberFormatter.formatNumber(context, recipient), messageText);
|
||||
PushServiceSocket pushServiceSocket = new PushServiceSocket(context, localNumber, password);
|
||||
pushServiceSocket.sendMessage(PhoneNumberFormatter.formatNumber(context, recipient), messageText);
|
||||
sentIntent.send(Activity.RESULT_OK);
|
||||
} catch (IOException ioe) {
|
||||
Log.w("OptimizingTransport", ioe);
|
||||
@@ -67,6 +67,10 @@ public class OptimizingTransport {
|
||||
sendSmsTextMessage(recipient, messageText, sentIntent, deliveredIntent);
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Log.w("OptimizingTransport", e);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("OptimzingTransport", e);
|
||||
Log.w("OptimzingTransport", "Rate Limit Exceeded, falling back to SMS...");
|
||||
sendSmsTextMessage(recipient, messageText, sentIntent, deliveredIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.thoughtcrimegson.Gson;
|
||||
import org.thoughtcrime.securesms.Release;
|
||||
import org.thoughtcrime.securesms.directory.DirectoryDescriptor;
|
||||
import org.thoughtcrime.securesms.directory.NumberFilter;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -19,6 +20,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyManagementException;
|
||||
@@ -28,46 +30,48 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class GcmSocket {
|
||||
public class PushServiceSocket {
|
||||
|
||||
private static final String CREATE_ACCOUNT_PATH = "/v1/accounts/%s";
|
||||
private static final String VERIFY_ACCOUNT_PATH = "/v1/accounts/%s";
|
||||
private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/%s";
|
||||
private static final String DIRECTORY_PATH = "/v1/directory/";
|
||||
private static final String MESSAGE_PATH = "/v1/messages/";
|
||||
private static final String CREATE_ACCOUNT_SMS_PATH = "/v1/accounts/sms/%s";
|
||||
private static final String CREATE_ACCOUNT_VOICE_PATH = "/v1/accounts/voice/%s";
|
||||
private static final String VERIFY_ACCOUNT_PATH = "/v1/accounts/code/%s";
|
||||
private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/";
|
||||
|
||||
private static final String DIRECTORY_PATH = "/v1/directory/";
|
||||
private static final String MESSAGE_PATH = "/v1/messages/";
|
||||
|
||||
private final String localNumber;
|
||||
private final String password;
|
||||
private final TrustManagerFactory trustManagerFactory;
|
||||
|
||||
public GcmSocket(Context context, String localNumber, String password) {
|
||||
public PushServiceSocket(Context context, String localNumber, String password) {
|
||||
this.localNumber = localNumber;
|
||||
this.password = password;
|
||||
this.trustManagerFactory = initializeTrustManagerFactory(context);
|
||||
}
|
||||
|
||||
public void createAccount() throws IOException {
|
||||
makeRequest(String.format(CREATE_ACCOUNT_PATH, localNumber), "POST", null);
|
||||
public void createAccount(boolean voice) throws IOException, RateLimitException {
|
||||
String path = voice ? CREATE_ACCOUNT_VOICE_PATH : CREATE_ACCOUNT_SMS_PATH;
|
||||
makeRequest(String.format(path, localNumber), "POST", null);
|
||||
}
|
||||
|
||||
public void verifyAccount(String verificationCode, String password)
|
||||
throws IOException
|
||||
public void verifyAccount(String verificationCode) throws IOException, RateLimitException {
|
||||
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode), "PUT", null);
|
||||
}
|
||||
|
||||
public void registerGcmId(String gcmRegistrationId) throws IOException, RateLimitException {
|
||||
GcmRegistrationId registration = new GcmRegistrationId(gcmRegistrationId);
|
||||
makeRequest(REGISTER_GCM_PATH, "PUT", new Gson().toJson(registration));
|
||||
}
|
||||
|
||||
public void unregisterGcmId(String gcmRegistrationId) throws IOException, RateLimitException {
|
||||
GcmRegistrationId registration = new GcmRegistrationId(gcmRegistrationId);
|
||||
makeRequest(REGISTER_GCM_PATH, "DELETE", new Gson().toJson(registration));
|
||||
}
|
||||
|
||||
public void sendMessage(String recipient, String messageText)
|
||||
throws IOException, RateLimitException
|
||||
{
|
||||
Verification verification = new Verification(verificationCode, password);
|
||||
makeRequest(String.format(VERIFY_ACCOUNT_PATH, localNumber), "PUT", new Gson().toJson(verification));
|
||||
}
|
||||
|
||||
public void registerGcmId(String gcmRegistrationId) throws IOException {
|
||||
GcmRegistrationId registration = new GcmRegistrationId(gcmRegistrationId);
|
||||
makeRequest(String.format(REGISTER_GCM_PATH, localNumber), "PUT", new Gson().toJson(registration));
|
||||
}
|
||||
|
||||
public void unregisterGcmId(String gcmRegistrationId) throws IOException {
|
||||
GcmRegistrationId registration = new GcmRegistrationId(gcmRegistrationId);
|
||||
makeRequest(String.format(REGISTER_GCM_PATH, localNumber), "DELETE", new Gson().toJson(registration));
|
||||
}
|
||||
|
||||
public void sendMessage(String recipient, String messageText) throws IOException {
|
||||
OutgoingGcmMessage message = new OutgoingGcmMessage(recipient, messageText);
|
||||
String responseText = makeRequest(MESSAGE_PATH, "POST", new Gson().toJson(message));
|
||||
GcmMessageResponse response = new Gson().fromJson(responseText, GcmMessageResponse.class);
|
||||
@@ -89,7 +93,9 @@ public class GcmSocket {
|
||||
directoryDescriptor.getVersion());
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.w("GcmSocket", ioe);
|
||||
Log.w("PushServiceSocket", ioe);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("PushServiceSocket", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,8 +111,8 @@ public class GcmSocket {
|
||||
|
||||
OutputStream output = new FileOutputStream(download);
|
||||
InputStream input = new GZIPInputStream(connection.getInputStream());
|
||||
int read = 0;
|
||||
byte[] buffer = new byte[4096];
|
||||
int read;
|
||||
|
||||
while ((read = input.read(buffer)) != -1) {
|
||||
output.write(buffer, 0, read);
|
||||
@@ -117,8 +123,10 @@ public class GcmSocket {
|
||||
return download;
|
||||
}
|
||||
|
||||
private String makeRequest(String urlFragment, String method, String body) throws IOException {
|
||||
HttpsURLConnection connection = getConnection(urlFragment, method);
|
||||
private String makeRequest(String urlFragment, String method, String body)
|
||||
throws IOException, RateLimitException
|
||||
{
|
||||
HttpURLConnection connection = getConnection(urlFragment, method);
|
||||
|
||||
if (body != null) {
|
||||
connection.setDoOutput(true);
|
||||
@@ -127,12 +135,16 @@ public class GcmSocket {
|
||||
connection.connect();
|
||||
|
||||
if (body != null) {
|
||||
Log.w("GcmSocket", method + " -- " + body);
|
||||
Log.w("PushServiceSocket", method + " -- " + body);
|
||||
OutputStream out = connection.getOutputStream();
|
||||
out.write(body.getBytes());
|
||||
out.close();
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() == 413) {
|
||||
throw new RateLimitException("Rate limit exceeded: " + connection.getResponseCode());
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() != 200) {
|
||||
throw new IOException("Bad response: " + connection.getResponseCode() + " " + connection.getResponseMessage());
|
||||
}
|
||||
@@ -140,19 +152,22 @@ public class GcmSocket {
|
||||
return Util.readFully(connection.getInputStream());
|
||||
}
|
||||
|
||||
private HttpsURLConnection getConnection(String urlFragment, String method) throws IOException {
|
||||
private HttpURLConnection getConnection(String urlFragment, String method) throws IOException {
|
||||
try {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, trustManagerFactory.getTrustManagers(), null);
|
||||
|
||||
URL url = new URL(String.format("https://gcm.textsecure.whispersystems.org%s", urlFragment));
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
connection.setSSLSocketFactory(context.getSocketFactory());
|
||||
URL url = new URL(String.format("%s%s", Release.PUSH_SERVICE_URL, urlFragment));
|
||||
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
|
||||
|
||||
if (Release.ENFORCE_SSL) {
|
||||
((HttpsURLConnection)connection).setSSLSocketFactory(context.getSocketFactory());
|
||||
}
|
||||
|
||||
connection.setRequestMethod(method);
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
|
||||
if (password != null) {
|
||||
System.out.println("Adding authorization header: " + getAuthorizationHeader());
|
||||
connection.setRequestProperty("Authorization", getAuthorizationHeader());
|
||||
}
|
||||
|
||||
@@ -198,20 +213,16 @@ public class GcmSocket {
|
||||
}
|
||||
|
||||
|
||||
private class Verification {
|
||||
|
||||
private String verificationCode;
|
||||
private String authenticationToken;
|
||||
|
||||
public Verification() {}
|
||||
|
||||
public Verification(String verificationCode,
|
||||
String authenticationToken)
|
||||
{
|
||||
this.verificationCode = verificationCode;
|
||||
this.authenticationToken = authenticationToken;
|
||||
}
|
||||
}
|
||||
// private class Verification {
|
||||
//
|
||||
// private String verificationCode;
|
||||
//
|
||||
// public Verification() {}
|
||||
//
|
||||
// public Verification(String verificationCode) {
|
||||
// this.verificationCode = verificationCode;
|
||||
// }
|
||||
// }
|
||||
|
||||
private class GcmRegistrationId {
|
||||
private String gcmRegistrationId;
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.thoughtcrime.securesms.gcm;
|
||||
|
||||
|
||||
public class RateLimitException extends Exception {
|
||||
public RateLimitException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,8 @@ import com.google.android.gcm.GCMRegistrar;
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.gcm.GcmIntentService;
|
||||
import org.thoughtcrime.securesms.gcm.GcmRegistrationTimeoutException;
|
||||
import org.thoughtcrime.securesms.gcm.GcmSocket;
|
||||
import org.thoughtcrime.securesms.gcm.PushServiceSocket;
|
||||
import org.thoughtcrime.securesms.gcm.RateLimitException;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -25,8 +26,9 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* The RegisterationService handles the actual process of registration. If it receives an
|
||||
* intent with a REGISTER_NUMBER_ACTION, it does the following through an executor:
|
||||
* The RegisterationService handles the process of PushService registration and verification.
|
||||
* If it receives an intent with a REGISTER_NUMBER_ACTION, it does the following through
|
||||
* an executor:
|
||||
*
|
||||
* 1) Generate secrets.
|
||||
* 2) Register the specified number and those secrets with the server.
|
||||
@@ -44,9 +46,12 @@ import java.util.concurrent.Executors;
|
||||
|
||||
public class RegistrationService extends Service {
|
||||
|
||||
public static final String REGISTER_NUMBER_ACTION = "org.thoughtcrime.securesms.RegistrationService.REGISTER_NUMBER";
|
||||
public static final String VOICE_REQUESTED_ACTION = "org.thoughtcrime.securesms.RegistrationService.VOICE_REQUESTED";
|
||||
public static final String VOICE_REGISTER_ACTION = "org.thoughtcrime.securesms.RegistrationService.VOICE_REGISTER";
|
||||
|
||||
public static final String NOTIFICATION_TITLE = "org.thoughtcrime.securesms.NOTIFICATION_TITLE";
|
||||
public static final String NOTIFICATION_TEXT = "org.thoughtcrime.securesms.NOTIFICATION_TEXT";
|
||||
public static final String REGISTER_NUMBER_ACTION = "org.thoughtcrime.securesms.RegistrationService.REGISTER_NUMBER";
|
||||
public static final String CHALLENGE_EVENT = "org.thoughtcrime.securesms.CHALLENGE_EVENT";
|
||||
public static final String REGISTRATION_EVENT = "org.thoughtcrime.securesms.REGISTRATION_EVENT";
|
||||
public static final String GCM_REGISTRATION_EVENT = "org.thoughtcrime.securesms.GCM_REGISTRATION_EVENT";
|
||||
@@ -70,11 +75,13 @@ public class RegistrationService extends Service {
|
||||
|
||||
@Override
|
||||
public int onStartCommand(final Intent intent, int flags, int startId) {
|
||||
if (intent != null && intent.getAction().equals(REGISTER_NUMBER_ACTION)) {
|
||||
if (intent != null) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleRegistrationIntent(intent);
|
||||
if (intent.getAction().equals(REGISTER_NUMBER_ACTION)) handleRegistrationIntent(intent);
|
||||
else if (intent.getAction().equals(VOICE_REQUESTED_ACTION)) handleVoiceRequestedIntent(intent);
|
||||
else if (intent.getAction().equals(VOICE_REGISTER_ACTION)) handleVoiceRegisterIntent(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -141,10 +148,58 @@ public class RegistrationService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleVoiceRequestedIntent(Intent intent) {
|
||||
setState(new RegistrationState(RegistrationState.STATE_VOICE_REQUESTED,
|
||||
intent.getStringExtra("e164number"),
|
||||
intent.getStringExtra("password")));
|
||||
}
|
||||
|
||||
private void handleVoiceRegisterIntent(Intent intent) {
|
||||
markAsVerifying(true);
|
||||
|
||||
String number = intent.getStringExtra("e164number");
|
||||
String password = intent.getStringExtra("password");
|
||||
|
||||
try {
|
||||
initializeGcmRegistrationListener();
|
||||
|
||||
PushServiceSocket socket = new PushServiceSocket(this, number, password);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
||||
GCMRegistrar.register(this, GcmIntentService.GCM_SENDER_ID);
|
||||
String gcmRegistrationId = waitForGcmRegistrationId();
|
||||
|
||||
socket.registerGcmId(gcmRegistrationId);
|
||||
socket.retrieveDirectory(this);
|
||||
|
||||
markAsVerified(number, password);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
|
||||
broadcastComplete(true);
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
Log.w("RegistrationService", uoe);
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_UNSUPPORTED, number));
|
||||
broadcastComplete(false);
|
||||
} catch (IOException e) {
|
||||
Log.w("RegistrationService", e);
|
||||
setState(new RegistrationState(RegistrationState.STATE_NETWORK_ERROR, number));
|
||||
broadcastComplete(false);
|
||||
} catch (GcmRegistrationTimeoutException e) {
|
||||
Log.w("RegistrationService", e);
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_TIMEOUT));
|
||||
broadcastComplete(false);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("RegistrationService", e);
|
||||
setState(new RegistrationState(RegistrationState.STATE_NETWORK_ERROR));
|
||||
broadcastComplete(false);
|
||||
} finally {
|
||||
shutdownGcmRegistrationListener();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRegistrationIntent(Intent intent) {
|
||||
markAsVerifying(true);
|
||||
|
||||
GcmSocket socket;
|
||||
String number = intent.getStringExtra("e164number");
|
||||
|
||||
try {
|
||||
@@ -153,19 +208,18 @@ public class RegistrationService extends Service {
|
||||
initializeGcmRegistrationListener();
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_CONNECTING, number));
|
||||
socket = new GcmSocket(this, number, password);
|
||||
socket.createAccount();
|
||||
PushServiceSocket socket = new PushServiceSocket(this, number, password);
|
||||
socket.createAccount(false);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_VERIFYING, number));
|
||||
String challenge = waitForChallenge();
|
||||
socket.verifyAccount(challenge, password);
|
||||
socket.verifyAccount(challenge);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
||||
GCMRegistrar.register(this, GcmIntentService.GCM_SENDER_ID);
|
||||
String gcmRegistrationId = waitForGcmRegistrationId();
|
||||
socket.registerGcmId(gcmRegistrationId);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_RETRIEVING_DIRECTORY, number));
|
||||
socket.registerGcmId(gcmRegistrationId);
|
||||
socket.retrieveDirectory(this);
|
||||
|
||||
markAsVerified(number, password);
|
||||
@@ -188,6 +242,10 @@ public class RegistrationService extends Service {
|
||||
Log.w("RegistrationService", e);
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_TIMEOUT));
|
||||
broadcastComplete(false);
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("RegistrationService", e);
|
||||
setState(new RegistrationState(RegistrationState.STATE_NETWORK_ERROR));
|
||||
broadcastComplete(false);
|
||||
} finally {
|
||||
shutdownChallengeListener();
|
||||
shutdownGcmRegistrationListener();
|
||||
@@ -260,7 +318,7 @@ public class RegistrationService extends Service {
|
||||
this.registrationState = state;
|
||||
|
||||
if (registrationStateHandler != null) {
|
||||
registrationStateHandler.obtainMessage(state.state, state.number).sendToTarget();
|
||||
registrationStateHandler.obtainMessage(state.state, state).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,30 +364,36 @@ public class RegistrationService extends Service {
|
||||
|
||||
public static class RegistrationState {
|
||||
|
||||
public static final int STATE_IDLE = 0;
|
||||
public static final int STATE_CONNECTING = 1;
|
||||
public static final int STATE_VERIFYING = 2;
|
||||
public static final int STATE_TIMER = 3;
|
||||
public static final int STATE_COMPLETE = 4;
|
||||
public static final int STATE_TIMEOUT = 5;
|
||||
public static final int STATE_NETWORK_ERROR = 6;
|
||||
public static final int STATE_IDLE = 0;
|
||||
public static final int STATE_CONNECTING = 1;
|
||||
public static final int STATE_VERIFYING = 2;
|
||||
public static final int STATE_TIMER = 3;
|
||||
public static final int STATE_COMPLETE = 4;
|
||||
public static final int STATE_TIMEOUT = 5;
|
||||
public static final int STATE_NETWORK_ERROR = 6;
|
||||
|
||||
public static final int STATE_GCM_UNSUPPORTED = 8;
|
||||
public static final int STATE_GCM_REGISTERING = 9;
|
||||
public static final int STATE_GCM_TIMEOUT = 10;
|
||||
public static final int STATE_GCM_UNSUPPORTED = 8;
|
||||
public static final int STATE_GCM_REGISTERING = 9;
|
||||
public static final int STATE_GCM_TIMEOUT = 10;
|
||||
|
||||
public static final int STATE_RETRIEVING_DIRECTORY = 11;
|
||||
public static final int STATE_VOICE_REQUESTED = 12;
|
||||
|
||||
public final int state;
|
||||
public final String number;
|
||||
public final String password;
|
||||
|
||||
public RegistrationState(int state) {
|
||||
this(state, null);
|
||||
}
|
||||
|
||||
public RegistrationState(int state, String number) {
|
||||
this.state = state;
|
||||
this.number = number;
|
||||
this(state, number, null);
|
||||
}
|
||||
|
||||
public RegistrationState(int state, String number, String password) {
|
||||
this.state = state;
|
||||
this.number = number;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user