Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Phone number hint and retrieve SMS #3922

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ dependencies {
implementation "com.google.android.gms:play-services-maps:18.1.0"
implementation "com.google.android.gms:play-services-location:21.0.1"
implementation "com.google.android.gms:play-services-cronet:${googlePlayServicesVersion}"
implementation 'com.google.android.gms:play-services-auth:20.6.0'
implementation "com.google.android.gms:play-services-auth-api-phone:${googlePlayServicesVersion}"
implementation "com.google.zxing:core:${zxingVersion}"
implementation "com.github.tougee:sticky-headers-recyclerview:${stickyheadersrecyclerviewVersion}"
implementation "org.whispersystems:signal-protocol-android:${signalVersion}"
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,13 @@
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.SMSReceiver"
android:exported="true"
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>

<provider
android:name="androidx.startup.InitializationProvider"
Expand Down
39 changes: 39 additions & 0 deletions app/src/main/java/one/mixin/android/receiver/SMSReceiver.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package one.mixin.android.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Status
import one.mixin.android.extension.getParcelableCompat
import timber.log.Timber

class SMSReceiver : BroadcastReceiver() {
companion object {
var smsListener: SMSListener? = null
}

override fun onReceive(context: Context, intent: Intent?) {
if (SmsRetriever.SMS_RETRIEVED_ACTION != intent?.action) return
val extras = intent.extras ?: return
val status = extras.getParcelableCompat(SmsRetriever.EXTRA_STATUS, Status::class.java) ?: return

when (status.statusCode) {
CommonStatusCodes.SUCCESS -> {
val message = extras.getString(SmsRetriever.EXTRA_SMS_MESSAGE) ?: return
smsListener?.onSuccess(message)
}
CommonStatusCodes.TIMEOUT -> {
val msg = "SMSReceiver Waiting for SMS timed out (5 minutes)"
smsListener?.onError(msg)
Timber.d(msg)
}
}
}
}

interface SMSListener {
fun onSuccess(message: String)
fun onError(message: String)
}
42 changes: 42 additions & 0 deletions app/src/main/java/one/mixin/android/ui/landing/MobileFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.auth.api.identity.GetPhoneNumberHintIntentRequest
import com.google.android.gms.auth.api.identity.Identity
import com.google.i18n.phonenumbers.PhoneNumberUtil
import com.google.i18n.phonenumbers.Phonenumber
import com.mukesh.countrypicker.Country
Expand Down Expand Up @@ -95,6 +100,27 @@ class MobileFragment : BaseFragment(R.layout.fragment_mobile) {
}
}

@SuppressLint("SetTextI18n")
private val phoneNumberHintIntentResultLauncher: ActivityResultLauncher<IntentSenderRequest> = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
) { result ->
try {
val phoneNumberString = Identity.getSignInClient(requireActivity()).getPhoneNumberFromIntent(result.data)
val number = phoneUtil.parse(phoneNumberString, null)
if (!phoneUtil.isValidNumber(number)) {
return@registerForActivityResult
}
if (viewDestroyed()) return@registerForActivityResult

binding.apply {
countryCodeEt.setText("+${number.countryCode}")
mobileEt.setText(number.nationalNumber.toString())
}
} catch (e: Exception) {
Timber.d(e)
}
}

@SuppressLint("JavascriptInterface", "SetJavaScriptEnabled")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand Down Expand Up @@ -139,6 +165,8 @@ class MobileFragment : BaseFragment(R.layout.fragment_mobile) {
keyboard.setOnClickKeyboardListener(mKeyboardListener)
keyboard.animate().translationY(0f).start()
}

requestHint()
}

override fun onBackPressed(): Boolean {
Expand Down Expand Up @@ -169,6 +197,20 @@ class MobileFragment : BaseFragment(R.layout.fragment_mobile) {
.show()
}

private fun requestHint() {
val request: GetPhoneNumberHintIntentRequest = GetPhoneNumberHintIntentRequest.builder().build()
Identity.getSignInClient(requireActivity())
.getPhoneNumberHintIntent(request)
.addOnSuccessListener {
phoneNumberHintIntentResultLauncher.launch(
IntentSenderRequest.Builder(it.intentSender).build(),
)
}
.addOnFailureListener {
Timber.d(it)
}
}

private fun requestSend(captchaResponse: Pair<CaptchaView.CaptchaType, String>? = null) {
if (viewDestroyed()) return

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.uber.autodispose.autoDispose
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
Expand All @@ -36,6 +37,8 @@ import one.mixin.android.extension.defaultSharedPreferences
import one.mixin.android.extension.navTo
import one.mixin.android.extension.openUrl
import one.mixin.android.extension.putInt
import one.mixin.android.receiver.SMSListener
import one.mixin.android.receiver.SMSReceiver
import one.mixin.android.session.Session
import one.mixin.android.tip.exception.TipNetworkException
import one.mixin.android.ui.common.PinCodeFragment
Expand All @@ -53,6 +56,7 @@ import one.mixin.android.util.viewBinding
import one.mixin.android.vo.User
import one.mixin.android.widget.BottomSheet
import one.mixin.android.widget.CaptchaView
import timber.log.Timber

@AndroidEntryPoint
class VerificationFragment : PinCodeFragment(R.layout.fragment_verification) {
Expand Down Expand Up @@ -105,11 +109,13 @@ class VerificationFragment : PinCodeFragment(R.layout.fragment_verification) {
binding.verificationResendTv.setOnClickListener { sendVerification() }
binding.verificationNeedHelpTv.setOnClickListener { showBottom() }

startRetrieverSMS()
startCountDown()
}

override fun onDestroyView() {
super.onDestroyView()
SMSReceiver.smsListener = null
mCountDownTimer?.cancel()
}

Expand Down Expand Up @@ -139,6 +145,25 @@ class VerificationFragment : PinCodeFragment(R.layout.fragment_verification) {
viewModel.insertUser(u)
}

private fun startRetrieverSMS() {
SmsRetriever.getClient(requireContext())
.startSmsRetriever()
.addOnSuccessListener {
Timber.d("$TAG startRetrieverSMS success")
SMSReceiver.smsListener = object : SMSListener {
override fun onSuccess(message: String) {
Timber.d("$TAG receive SMS message: $message")
// TODO extract code and use
}

override fun onError(message: String) {}
}
}
.addOnFailureListener {
Timber.d("$TAG startRetrieverSMS failure ${it.stackTraceToString()}")
}
}

private fun isPhoneModification() = pin != null

@SuppressLint("InflateParams")
Expand Down