DO NOT MERGE: Migrate GoogleActivity to fragment

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-07-06 14:48:20 +05:30
parent da343e8530
commit cd5e49d1d2
8 changed files with 172 additions and 184 deletions

View File

@@ -90,8 +90,6 @@
<nav-graph android:value="@navigation/mobile_navigation" />
</activity>
<activity android:name=".view.ui.account.GoogleActivity" />
<service android:name=".data.service.NotificationService" />
<service android:name=".data.installer.InstallerService" />
<service android:name=".data.service.UpdateService" />

View File

@@ -201,7 +201,7 @@ class AccountFragment : Fragment(R.layout.fragment_account) {
binding.btnGoogle.addOnClickListener {
if (VM.liveData.value != AuthState.Fetching) {
binding.btnGoogle.updateProgress(true)
val intent = Intent(requireContext(), GoogleActivity::class.java)
val intent = Intent(requireContext(), GoogleFragment::class.java)
startForResult.launch(intent, requireContext().getEmptyActivityAnimation())
}
}

View File

@@ -1,142 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.ui.account
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.webkit.CookieManager
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import com.aurora.Constants
import com.aurora.store.R
import com.aurora.store.data.event.BusEvent
import com.aurora.store.databinding.ActivityGoogleBinding
import com.aurora.store.util.AC2DMTask
import com.aurora.store.util.AC2DMUtil
import com.aurora.store.util.Preferences
import com.aurora.store.view.ui.commons.BaseActivity
import nl.komponents.kovenant.task
import org.greenrobot.eventbus.EventBus
class GoogleActivity : BaseActivity() {
private lateinit var B: ActivityGoogleBinding
private val cookieManager = CookieManager.getInstance()
override fun onConnected() {
}
override fun onDisconnected() {
showNetworkConnectivitySheet()
}
override fun onReconnected() {
hideNetworkConnectivitySheet()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
B = ActivityGoogleBinding.inflate(layoutInflater)
setContentView(B.root)
setupWebView()
}
@SuppressLint("SetJavaScriptEnabled")
private fun setupWebView() {
cookieManager.removeAllCookies(null)
cookieManager.acceptThirdPartyCookies(B.webview)
cookieManager.setAcceptThirdPartyCookies(B.webview, true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
B.webview.settings.safeBrowsingEnabled = false
}
B.webview.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
val cookies = CookieManager.getInstance().getCookie(url)
val cookieMap = AC2DMUtil.parseCookieString(cookies)
if (cookieMap.isNotEmpty() && cookieMap[AUTH_TOKEN] != null) {
val oauthToken = cookieMap[AUTH_TOKEN]
B.webview.evaluateJavascript("(function() { return document.getElementById('profileIdentifier').innerHTML; })();") {
val email = it.replace("\"".toRegex(), "")
buildAuthData(email, oauthToken)
}
}
}
}
B.webview.apply {
settings.apply {
allowContentAccess = true
databaseEnabled = true
domStorageEnabled = true
javaScriptEnabled = true
cacheMode = WebSettings.LOAD_DEFAULT
}
loadUrl(EMBEDDED_SETUP_URL)
}
}
private fun buildAuthData(email: String, oauthToken: String?) {
task {
AC2DMTask().getAC2DMResponse(email, oauthToken)
} success {
if (it.isNotEmpty()) {
val aasToken = it["Token"]
if (aasToken != null) {
Preferences.putString(this, Constants.ACCOUNT_EMAIL_PLAIN, email)
Preferences.putString(this, Constants.ACCOUNT_AAS_PLAIN, aasToken)
EventBus.getDefault().post(BusEvent.GoogleAAS(true, email, aasToken))
} else {
Preferences.putString(this, Constants.ACCOUNT_EMAIL_PLAIN, "")
Preferences.putString(this, Constants.ACCOUNT_AAS_PLAIN, "")
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
}
} else {
Toast.makeText(this, getString(R.string.toast_aas_token_failed), Toast.LENGTH_LONG)
.show()
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
}
//Close Activity
setResult(RESULT_OK)
finishAfterTransition()
} fail {
Toast.makeText(this, getString(R.string.toast_aas_token_failed), Toast.LENGTH_LONG)
.show()
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
//Close Activity
setResult(RESULT_CANCELED)
finishAfterTransition()
}
}
companion object {
const val EMBEDDED_SETUP_URL =
"https://accounts.google.com/EmbeddedSetup/identifier?flowName=EmbeddedSetupAndroid"
const val AUTH_TOKEN = "oauth_token"
}
}

View File

@@ -0,0 +1,136 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.ui.account
import android.os.Build
import android.os.Bundle
import android.view.View
import android.webkit.CookieManager
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.aurora.Constants
import com.aurora.store.R
import com.aurora.store.data.event.BusEvent
import com.aurora.store.databinding.FragmentGoogleBinding
import com.aurora.store.util.AC2DMTask
import com.aurora.store.util.AC2DMUtil
import com.aurora.store.util.Preferences
import com.aurora.store.viewmodel.auth.AuthViewModel
import nl.komponents.kovenant.task
import org.greenrobot.eventbus.EventBus
class GoogleFragment : Fragment(R.layout.fragment_google) {
private val viewModel: AuthViewModel by activityViewModels()
companion object {
const val EMBEDDED_SETUP_URL =
"https://accounts.google.com/EmbeddedSetup/identifier?flowName=EmbeddedSetupAndroid"
const val AUTH_TOKEN = "oauth_token"
private const val JS_SCRIPT =
"(function() { return document.getElementById('profileIdentifier').innerHTML; })();"
}
private var _binding: FragmentGoogleBinding? = null
private val binding: FragmentGoogleBinding
get() = _binding!!
private val cookieManager = CookieManager.getInstance()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentGoogleBinding.bind(view)
binding.webview.apply {
cookieManager.removeAllCookies(null)
cookieManager.acceptThirdPartyCookies(this)
cookieManager.setAcceptThirdPartyCookies(this, true)
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
val cookies = CookieManager.getInstance().getCookie(url)
val cookieMap = AC2DMUtil.parseCookieString(cookies)
if (cookieMap.isNotEmpty() && cookieMap[AUTH_TOKEN] != null) {
val oauthToken = cookieMap[AUTH_TOKEN]
evaluateJavascript(JS_SCRIPT) {
val email = it.replace("\"".toRegex(), "")
buildAuthData(email, oauthToken)
}
}
}
}
settings.apply {
allowContentAccess = true
databaseEnabled = true
domStorageEnabled = true
javaScriptEnabled = true
cacheMode = WebSettings.LOAD_DEFAULT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) safeBrowsingEnabled = false
}
loadUrl(EMBEDDED_SETUP_URL)
}
}
private fun buildAuthData(email: String, oauthToken: String?) {
task {
AC2DMTask().getAC2DMResponse(email, oauthToken)
} success {
if (it.isNotEmpty()) {
val aasToken = it["Token"]
if (aasToken != null) {
Preferences.putString(requireContext(), Constants.ACCOUNT_EMAIL_PLAIN, email)
Preferences.putString(requireContext(), Constants.ACCOUNT_AAS_PLAIN, aasToken)
EventBus.getDefault().post(BusEvent.GoogleAAS(true, email, aasToken))
viewModel.buildGoogleAuthData(email, aasToken)
} else {
Preferences.putString(requireContext(), Constants.ACCOUNT_EMAIL_PLAIN, "")
Preferences.putString(requireContext(), Constants.ACCOUNT_AAS_PLAIN, "")
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
}
} else {
Toast.makeText(
requireContext(),
getString(R.string.toast_aas_token_failed),
Toast.LENGTH_LONG
).show()
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
}
findNavController().navigate(
GoogleFragmentDirections.actionGoogleFragmentToSplashFragment()
)
} fail {
Toast.makeText(
requireContext(),
getString(R.string.toast_aas_token_failed),
Toast.LENGTH_LONG
).show()
EventBus.getDefault().post(BusEvent.GoogleAAS(false))
findNavController().navigate(
GoogleFragmentDirections.actionGoogleFragmentToSplashFragment()
)
}
}
}

View File

@@ -19,15 +19,11 @@
package com.aurora.store.view.ui.splash
import android.app.Activity.RESULT_CANCELED
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.aurora.extensions.getEmptyActivityAnimation
import com.aurora.extensions.hide
import com.aurora.extensions.load
import com.aurora.extensions.show
@@ -35,7 +31,6 @@ import com.aurora.store.R
import com.aurora.store.data.AuthState
import com.aurora.store.data.event.BusEvent
import com.aurora.store.databinding.FragmentSplashBinding
import com.aurora.store.view.ui.account.GoogleActivity
import com.aurora.store.viewmodel.auth.AuthViewModel
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import org.greenrobot.eventbus.EventBus
@@ -47,21 +42,11 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
private val binding: FragmentSplashBinding
get() = _binding!!
private lateinit var VM: AuthViewModel
private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_CANCELED) {
resetActions()
} else {
binding.btnGoogle.updateProgress(true)
}
}
private val viewModel: AuthViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentSplashBinding.bind(view)
VM = ViewModelProvider(this)[AuthViewModel::class.java]
binding.imgIcon.load(R.drawable.ic_logo) {
transform(RoundedCorners(32))
@@ -75,7 +60,7 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
//Initial status
updateStatus(getString(R.string.session_init))
VM.liveData.observe(viewLifecycleOwner) {
viewModel.liveData.observe(viewLifecycleOwner) {
when (it) {
AuthState.Fetching -> {
updateStatus(getString(R.string.requesting_new_session))
@@ -114,11 +99,9 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
}
}
}
}
override fun onResume() {
if (::VM.isInitialized) VM.observe()
super.onResume()
// Check authentication status
viewModel.observe()
}
override fun onDestroyView() {
@@ -133,7 +116,7 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
is BusEvent.GoogleAAS -> {
if (event.success) {
updateStatus(getString(R.string.session_verifying_google))
VM.buildGoogleAuthData(event.email, event.aasToken)
viewModel.buildGoogleAuthData(event.email, event.aasToken)
} else {
updateStatus(getString(R.string.session_login_failed_google))
}
@@ -163,24 +146,23 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
private fun attachActions() {
binding.btnAnonymous.addOnClickListener {
if (VM.liveData.value != AuthState.Fetching) {
if (viewModel.liveData.value != AuthState.Fetching) {
binding.btnAnonymous.updateProgress(true)
VM.buildAnonymousAuthData()
viewModel.buildAnonymousAuthData()
}
}
binding.btnAnonymousInsecure.addOnClickListener {
if (VM.liveData.value != AuthState.Fetching) {
if (viewModel.liveData.value != AuthState.Fetching) {
binding.btnAnonymousInsecure.updateProgress(true)
VM.buildInSecureAnonymousAuthData()
viewModel.buildInSecureAnonymousAuthData()
}
}
binding.btnGoogle.addOnClickListener {
if (VM.liveData.value != AuthState.Fetching) {
if (viewModel.liveData.value != AuthState.Fetching) {
binding.btnGoogle.updateProgress(true)
val intent = Intent(requireContext(), GoogleActivity::class.java)
startForResult.launch(intent, activity?.getEmptyActivityAnimation())
findNavController().navigate(R.id.googleFragment)
}
}
}

View File

@@ -59,17 +59,19 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application
}
override fun observe() {
val signedIn = Preferences.getBoolean(getApplication(), Constants.ACCOUNT_SIGNED_IN)
if (signedIn) {
liveData.postValue(AuthState.Available)
buildSavedAuthData()
} else {
liveData.postValue(AuthState.Unavailable)
if (liveData.value != AuthState.Fetching) {
val signedIn = Preferences.getBoolean(getApplication(), Constants.ACCOUNT_SIGNED_IN)
if (signedIn) {
liveData.postValue(AuthState.Available)
buildSavedAuthData()
} else {
liveData.postValue(AuthState.Unavailable)
}
}
}
fun buildGoogleAuthData(email: String, aasToken: String) {
updateStatus("Requesting new session")
liveData.postValue(AuthState.Fetching)
task {
var properties = NativeDeviceInfoProvider(getApplication()).getNativeDeviceProperties()

View File

@@ -18,8 +18,10 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
tools:context=".view.ui.account.GoogleFragment">
<WebView
android:id="@+id/webview"

View File

@@ -233,11 +233,21 @@
<fragment
android:id="@+id/splashFragment"
android:name="com.aurora.store.view.ui.splash.SplashFragment"
android:label="fragment_splash"
tools:layout="@layout/fragment_splash" >
<action
android:id="@+id/action_splashFragment_to_navigation_apps"
app:destination="@id/navigation_apps"
app:launchSingleTop="true"
app:popUpTo="@id/mobile_navigation"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/googleFragment"
android:name="com.aurora.store.view.ui.account.GoogleFragment"
tools:layout="@layout/fragment_google" >
<action
android:id="@+id/action_googleFragment_to_splashFragment"
app:destination="@id/splashFragment"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
</fragment>