Registration with voice verification.
This commit is contained in:
parent
6ca029f64a
commit
3634ba0b55
19 changed files with 805 additions and 316 deletions
|
@ -74,6 +74,13 @@
|
|||
|
||||
</activity>
|
||||
|
||||
<activity android:name=".RegistrationProblemsActivity"
|
||||
android:theme="@style/Theme.Sherlock.Light.Dialog"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".CountrySelectionActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".ImportExportActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
|
|
BIN
res/drawable-hdpi/check_dark.png
Normal file
BIN
res/drawable-hdpi/check_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-hdpi/telephone.png
Normal file
BIN
res/drawable-hdpi/telephone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
res/drawable-mdpi/check_dark.png
Normal file
BIN
res/drawable-mdpi/check_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-mdpi/telephone.png
Normal file
BIN
res/drawable-mdpi/telephone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-xhdpi/check_dark.png
Normal file
BIN
res/drawable-xhdpi/check_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
res/drawable-xhdpi/telephone.png
Normal file
BIN
res/drawable-xhdpi/telephone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
140
res/layout/registration_problems.xml
Normal file
140
res/layout/registration_problems.xml
Normal file
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="10dip"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<ScrollView android:layout_alignParentTop="true"
|
||||
android:layout_above="@+id/button_frame"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:paddingTop="5dip"
|
||||
android:paddingBottom="12dip">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:text="@string/registration_problems__some_possible_problems_include" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="•" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/registration_problems__sms_interceptors"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="@string/registration_problems__some_third_party_text_messaging_clients_such_as_handcent" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="•" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/registration_problems__incorrect_number"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="@string/registration_problems__please_checkt_to_make_sure_you_entered_your_number_correctly" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="•" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/registration_problems__google_voice"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="@string/registration_problems__textsecure_will_not_work_with_google_voice_numbers" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout android:id="@+id/button_frame"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="54dip"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
|
||||
<Button android:id="@+id/close_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="10dip"
|
||||
android:paddingRight="10dip"
|
||||
android:text="@android:string/ok"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
|
@ -34,7 +34,8 @@
|
|||
android:layout_alignParentLeft="true"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/alert" />
|
||||
android:src="@drawable/alert"
|
||||
android:contentDescription="Alert"/>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Constant"
|
||||
|
@ -44,130 +45,101 @@
|
|||
android:layout_toRightOf="@id/alert"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="SMS verification failed."
|
||||
android:text="@string/registration_progress_activity__sms_verification_failed"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16.0sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sms_failed_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/alert"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:text="TextSecure timed out while waiting for an SMS message to verify your phone number." />
|
||||
android:text="@string/registration_progress_activity__textsecure_timed_out_while_waiting_for_a_verification_sms_message" />
|
||||
</RelativeLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/verification_failure_edit_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10.0dip"
|
||||
android:gravity="center"
|
||||
android:text="Edit number"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:text="Some possible problems include:"/>
|
||||
<RelativeLayout android:id="@+id/voice_verification_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:background="@drawable/background_pane">
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<ImageView android:id="@+id/telephone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/telephone"
|
||||
android:contentDescription="Telephone"/>
|
||||
|
||||
<TableRow>
|
||||
<TextView style="@style/Registration.Constant"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@id/telephone"
|
||||
android:layout_toRightOf="@id/telephone"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="8dip"
|
||||
android:text="@string/registration_progress_activity__voice_verification"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
<TextView android:id="@+id/telephone_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/telephone"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:paddingBottom="10dip"
|
||||
android:text="@string/registration_progress_activity__textsecure_can_also_call_you_to_verify_your_number"/>
|
||||
|
||||
<LinearLayout android:id="@+id/code_container"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_below="@id/telephone_text">
|
||||
|
||||
<EditText android:id="@+id/telephone_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="6"
|
||||
android:inputType="number"
|
||||
android:enabled="false"/>
|
||||
|
||||
<Button android:id="@+id/verify_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="•" />
|
||||
android:text="@string/registration_progress_activity__verify"
|
||||
android:enabled="false"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="SMS Interceptors."
|
||||
android:textStyle="bold" />
|
||||
<Button android:id="@+id/call_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_below="@id/code_container"
|
||||
android:paddingLeft="5dip"
|
||||
android:paddingRight="5dip"
|
||||
android:layout_marginTop="10dip"
|
||||
android:text="@string/registration_progress_activity__call_me"/>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="Some third party text messaging clients, such as Handcent or GoSMS, behave poorly and intercept all incoming SMS messages. Check to see if you received a text message that starts with 'Your TextSecure verification code:', in which case you'll need to configure your third party text messaging app to let text messages through." />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="•" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Incorrect number."
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="Please check to make sure you entered your number correctly, and that it is formatted for correctly your region." />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="•" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Google Voice."
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="TextSecure will not work with Google Voice numbers." />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
<Button
|
||||
android:id="@+id/verification_failure_edit_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginBottom="10.0dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/registration_progress_activity__edit_number"
|
||||
android:textStyle="bold"
|
||||
android:layout_below="@id/call_button"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -194,7 +166,8 @@
|
|||
android:layout_alignParentLeft="true"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/alert" />
|
||||
android:src="@drawable/alert"
|
||||
android:contentDescription="Alert"/>
|
||||
|
||||
<TextView
|
||||
style="@style/Registration.Constant"
|
||||
|
@ -204,7 +177,7 @@
|
|||
android:layout_toRightOf="@id/connectivity_alert"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="Connectivity error."
|
||||
android:text="@string/registration_progress_activity__connectivity_error"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16.0sp" />
|
||||
|
||||
|
@ -215,7 +188,7 @@
|
|||
android:layout_below="@+id/connectivity_alert"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:text="RedPhone was unable to connect to the switch." />
|
||||
android:text="@string/registration_progress_activity__textsecure_was_unable_to_connect_to_the_push_service" />
|
||||
</RelativeLayout>
|
||||
|
||||
<Button
|
||||
|
@ -225,7 +198,7 @@
|
|||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10.0dip"
|
||||
android:gravity="center"
|
||||
android:text="Edit number"
|
||||
android:text="@string/registration_progress_activity__edit_number"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
@ -233,7 +206,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:text="Some possible problems include:" />
|
||||
android:text="@string/registration_progress_activity__some_possible_problems_include" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -257,7 +230,7 @@
|
|||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="No network connectivity."
|
||||
android:text="@string/registration_progress_activity__no_network_connectivity"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
@ -265,7 +238,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="Your device needs network connectivity in order to use this TextSecure feature. Check to ensure that it is connected to 3G or Wifi." />
|
||||
android:text="@string/registration_progress_activity__your_device_needs_network_connectivity" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
|
@ -287,7 +260,7 @@
|
|||
style="@style/Registration.Description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Restrictive firewall."
|
||||
android:text="@string/registration_progress_activity__restrictive_firewall"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
@ -295,7 +268,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dip"
|
||||
android:text="If you are connected via wifi, it's possible that there is a firewall blocking access to the TextSecure server. Try another network or mobile data." />
|
||||
android:text="@string/registration_progress_activity__if_you_are_connected_via_wifi_its_possible_that_there_is_a_firewall" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
@ -316,7 +289,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dip"
|
||||
android:paddingLeft="5dip"
|
||||
android:text="TextSecure will now automatically verify your number with a confirmation SMS message." />
|
||||
android:text="@string/registration_progress_activity__textsecure_will_now_automatically_verify_your_number_with_a_confirmation_sms_message" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -343,8 +316,9 @@
|
|||
android:gravity="center"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/check"
|
||||
android:visibility="invisible" />
|
||||
android:src="@drawable/check_dark"
|
||||
android:visibility="invisible"
|
||||
android:contentDescription="Check"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/connecting_progress"
|
||||
|
@ -366,7 +340,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="Registering with server..."
|
||||
android:text="@string/registration_progress_activity__connecting"
|
||||
android:textSize="16.0sp" />
|
||||
</TableRow>
|
||||
|
||||
|
@ -386,8 +360,9 @@
|
|||
android:gravity="center"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/check"
|
||||
android:visibility="invisible" />
|
||||
android:src="@drawable/check_dark"
|
||||
android:visibility="invisible"
|
||||
android:contentDescription="Check"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/verification_progress"
|
||||
|
@ -409,7 +384,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="Waiting for SMS verification..."
|
||||
android:text="@string/registration_progress_activity__waiting_for_sms_verification"
|
||||
android:textSize="16.0sp" />
|
||||
</TableRow>
|
||||
|
||||
|
@ -429,8 +404,9 @@
|
|||
android:gravity="center"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/check"
|
||||
android:visibility="invisible" />
|
||||
android:src="@drawable/check_dark"
|
||||
android:visibility="invisible"
|
||||
android:contentDescription="Check"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/gcm_registering_progress"
|
||||
|
@ -452,52 +428,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="Registering for push..."
|
||||
android:text="@string/registration_progress_activity__registering_with_server"
|
||||
android:textSize="16.0sp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/retrieve_directory_complete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:src="@drawable/check"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/retrieve_directory_progress"
|
||||
style="?android:attr/android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:visibility="invisible" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/retrieve_directory_text"
|
||||
style="@style/Registration.Constant"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="4.0dip"
|
||||
android:paddingRight="8.0dip"
|
||||
android:text="Retrieving directory..."
|
||||
android:textSize="16.0sp" />
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<TextView
|
||||
|
@ -505,7 +439,7 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dip"
|
||||
android:text="This could take a moment. Please be patient, we'll notify you when verification is complete." />
|
||||
android:text="@string/registration_progress_activity__this_couild_take_a_moment_please_be_patient" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/timer_progress_layout"
|
||||
|
@ -528,7 +462,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:text="Waiting for SMS verification..."
|
||||
android:text="@string/registration_progress_activity__waiting_for_sms_verification"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="12.0sp"
|
||||
android:textStyle="normal" />
|
||||
|
@ -551,7 +485,7 @@
|
|||
android:layout_weight="1.0"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:text="Edit number"
|
||||
android:text="@string/registration_progress_activity__edit_number"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
|
|
@ -186,6 +186,32 @@
|
|||
exchanges\' setting disabled.
|
||||
</string>
|
||||
|
||||
<!-- RegistrationProblemsActivity -->
|
||||
<string name="RegistrationProblemsActivity_possible_problems">Possible Problems</string>
|
||||
|
||||
<!-- RegistrationProgressActivity -->
|
||||
<string name="RegistrationProgressActivity_verifying_number">Verifying number</string>
|
||||
<string name="RegistrationProgressActivity_edit_s">Edit %s</string>
|
||||
<string name="RegistrationProgressActivity_registration_complete">Registration complete!</string>
|
||||
<string name="RegistrationProgressActivity_possible_problems">Possible problems.</string>
|
||||
<string name="RegistrationProgressActivity_you_must_enter_the_code_you_received_first">You must enter the code you received first...</string>
|
||||
<string name="RegistrationProgressActivity_connecting">Connecting</string>
|
||||
<string name="RegistrationProgressActivity_connecting_for_verification">Connecting for verification...</string>
|
||||
<string name="RegistrationProgressActivity_network_error">Network Error!</string>
|
||||
<string name="RegistrationProgressActivity_unable_to_connect">Unable to connect. Please check your network connection and try again.</string>
|
||||
<string name="RegistrationProgressActivity_verification_failed">Verification Failed!</string>
|
||||
<string name="RegistrationProgressActivity_the_verification_code_you_submitted_is_incorrect">The verification code you submitted is incorrect. Please try again.</string>
|
||||
<string name="RegistrationProgressActivity_too_many_attempts">Too many attempts</string>
|
||||
<string name="RegistrationProgressActivity_youve_submitted_an_incorrect_verification_code_too_many_times">You\'ve submitted an incorrect verification code too many times. Please wait a minute before trying again.</string>
|
||||
<string name="RegistrationProgressActivity_requesting_call">Requesting Call</string>
|
||||
<string name="RegistrationProgressActivity_requesting_incoming_call">Requesting incoming verification call...</string>
|
||||
<string name="RegistrationProgressActivity_server_error">Server Error</string>
|
||||
<string name="RegistrationProgressActivity_the_server_encountered_an_error">The server encountered an error. Please try again.</string>
|
||||
<string name="RegistrationProgressActivity_too_many_requests">Too Many Requests!</string>
|
||||
<string name="RegistrationProgressActivity_youve_already_requested_a_voice_call">You\'ve already recently requested a voice call. You can request another in 20 minutes.</string>
|
||||
<string name="RegistrationProgressActivity_verifying_voice_code">Verifying voice code...</string>
|
||||
|
||||
|
||||
<!-- VerifyIdentityActivity -->
|
||||
<string name="VerifyIdentityActivity_you_do_not_have_an_identity_key">You do not have an identity key.</string>
|
||||
<string name="VerifyIdentityActivity_recipient_has_no_identity_key">Recipient has no identity key.</string>
|
||||
|
@ -376,6 +402,48 @@
|
|||
<!-- receive_key_activity -->
|
||||
<string name="receive_key_activity__complete">Complete</string>
|
||||
|
||||
<!-- registration_progress_activity -->
|
||||
<string name="registration_progress_activity__voice_verification">Voice Verification</string>
|
||||
<string name="registration_progress_activity__textsecure_can_also_call_you_to_verify_your_number">
|
||||
TextSecure can also call you to verify your number. Tap \'Call Me\' and enter the six digit
|
||||
code that you hear below.
|
||||
</string>
|
||||
<string name="registration_progress_activity__verify">Verify</string>
|
||||
<string name="registration_progress_activity__call_me">Call Me</string>
|
||||
<string name="registration_progress_activity__edit_number">Edit number</string>
|
||||
<string name="registration_progress_activity__connectivity_error">Connectivity error.</string>
|
||||
<string name="registration_progress_activity__textsecure_was_unable_to_connect_to_the_push_service">
|
||||
TextSecure was unable to connect to the push service.
|
||||
</string>
|
||||
<string name="registration_progress_activity__some_possible_problems_include">Some possible
|
||||
problems include:
|
||||
</string>
|
||||
<string name="registration_progress_activity__no_network_connectivity">No network
|
||||
connectivity.
|
||||
</string>
|
||||
<string name="registration_progress_activity__your_device_needs_network_connectivity">Your
|
||||
device needs network connectivity in order to use this TextSecure feature. Check to ensure
|
||||
that it is connected to 3G or Wifi.
|
||||
</string>
|
||||
<string name="registration_progress_activity__restrictive_firewall">Restrictive firewall.
|
||||
</string>
|
||||
<string name="registration_progress_activity__if_you_are_connected_via_wifi_its_possible_that_there_is_a_firewall">
|
||||
If you are connected via wifi, it\'s possible that there is a firewall blocking access to
|
||||
the TextSecure server. Try another network or mobile data.
|
||||
</string>
|
||||
<string name="registration_progress_activity__textsecure_will_now_automatically_verify_your_number_with_a_confirmation_sms_message">
|
||||
TextSecure will now automatically verify your number with a confirmation SMS message.
|
||||
</string>
|
||||
<string name="registration_progress_activity__connecting">Connecting...</string>
|
||||
<string name="registration_progress_activity__waiting_for_sms_verification">Waiting for SMS
|
||||
verification...
|
||||
</string>
|
||||
<string name="registration_progress_activity__registering_with_server">Registering with server...</string>
|
||||
<string name="registration_progress_activity__this_couild_take_a_moment_please_be_patient">This
|
||||
could take a moment. Please be patient, we\'ll notify you when verification is complete.
|
||||
</string>
|
||||
|
||||
|
||||
<!-- recipients_panel -->
|
||||
<string name="recipients_panel__to">To</string>
|
||||
|
||||
|
@ -556,6 +624,31 @@
|
|||
|
||||
<!-- verify_keys -->
|
||||
<string name="verify_keys__menu_verified">Verified</string>
|
||||
<string name="registration_problems__some_possible_problems_include">Some possible problems
|
||||
include:
|
||||
</string>
|
||||
<string name="registration_problems__sms_interceptors">SMS Interceptors.</string>
|
||||
<string name="registration_problems__some_third_party_text_messaging_clients_such_as_handcent">
|
||||
Some third party text messaging clients, such as Handcent or GoSMS, behave poorly and
|
||||
intercept all incoming SMS messages. Check to see if you received a text message that starts
|
||||
with \'Your TextSecure verification code:\', in which case you\'ll need to configure your
|
||||
third party text messaging app to let text messages through.
|
||||
</string>
|
||||
<string name="registration_problems__incorrect_number">Incorrect number.</string>
|
||||
<string name="registration_problems__please_checkt_to_make_sure_you_entered_your_number_correctly">
|
||||
Please check to make sure you entered your number correctly, and that it is formatted for
|
||||
correctly your region.
|
||||
</string>
|
||||
<string name="registration_problems__google_voice">Google Voice.</string>
|
||||
<string name="registration_problems__textsecure_will_not_work_with_google_voice_numbers">
|
||||
TextSecure will not work with Google Voice numbers.
|
||||
</string>
|
||||
<string name="registration_progress_activity__textsecure_timed_out_while_waiting_for_a_verification_sms_message">
|
||||
TextSecure timed out while waiting for a verification SMS message.
|
||||
</string>
|
||||
<string name="registration_progress_activity__sms_verification_failed">SMS verification
|
||||
failed.
|
||||
</string>
|
||||
<!-- EOF -->
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue