From dcf5f1fecb9add7e640a6bb780cb0c752e5c025e Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 20 Aug 2023 14:01:09 +0200 Subject: [PATCH] Add basic Google account settings This uses WebView instead of the native solution, meaning some options are not available. Hopefully can still be useful to recover access to accounts that are signed in microG when Google decides that it can't verify your identity through other means. --- .../src/main/AndroidManifest.xml | 32 ++- ...ava => LegacyAccountSettingsActivity.java} | 2 +- .../microg/tools/AccountPickerActivity.java | 21 +- .../gms/accountsettings/ui/LoaderActivity.kt | 162 +++++++++++++++ .../gms/accountsettings/ui/MainActivity.kt | 184 ++++++++++++++++++ .../gms/accountsettings/ui/WebViewHelper.kt | 129 ++++++++++++ .../gms/accountsettings/ui/extensions.kt | 23 +++ .../ui/GoogleHelpRedirectActivity.kt | 2 +- .../src/main/res/xml/preferences_auth.xml | 7 + 9 files changed, 541 insertions(+), 21 deletions(-) rename play-services-core/src/main/java/org/microg/gms/ui/{AccountSettingsActivity.java => LegacyAccountSettingsActivity.java} (97%) create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 163447e121..ea90952b37 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -362,7 +362,8 @@ android:name="org.microg.tools.AccountPickerActivity" android:excludeFromRecents="true" android:exported="true" - android:process=":ui"> + android:process=":ui" + android:theme="@style/Theme.AppCompat.DayNight.Dialog.Alert.NoActionBar"> @@ -545,16 +546,41 @@ android:taskAffinity="org.microg.gms.settings" /> + android:taskAffinity="org.microg.gms.settings"> + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java similarity index 97% rename from play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java rename to play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java index e1e1dd5a6b..02f211fc5b 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java @@ -36,7 +36,7 @@ import static android.os.Build.VERSION.SDK_INT; import static org.microg.gms.auth.AuthManager.PREF_AUTH_VISIBLE; -public class AccountSettingsActivity extends AbstractSettingsActivity { +public class LegacyAccountSettingsActivity extends AbstractSettingsActivity { @Override protected Fragment getFragment() { diff --git a/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java b/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java index 09fa611a64..1a603a9502 100644 --- a/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java +++ b/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java @@ -16,18 +16,15 @@ package org.microg.tools; -import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.util.Log; +import androidx.appcompat.app.AppCompatActivity; /** * This is just an activity that forwards to the systems native account picker */ -public class AccountPickerActivity extends Activity { - private static final int REQUEST_CODE = AccountPickerActivity.class.hashCode(); - +public class AccountPickerActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -37,16 +34,8 @@ protected void onCreate(Bundle savedInstanceState) { ComponentName.unflattenFromString("android/.accounts.ChooseTypeAndAccountActivity"); intent.setClassName(componentName.getPackageName(), componentName.getClassName()); intent.putExtras(extras); - startActivityForResult(intent, REQUEST_CODE); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_CODE) { - setResult(resultCode, data); - finish(); - } else { - super.onActivityResult(requestCode, resultCode, data); - } + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(intent); + finish(); } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt new file mode 100644 index 0000000000..fd6f8c8165 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.accountsettings.ui + +import android.accounts.AccountManager +import android.app.Activity +import android.content.Intent +import android.content.Intent.* +import android.net.Uri +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import org.microg.gms.auth.AuthConstants.DEFAULT_ACCOUNT_TYPE +import org.microg.gms.common.PackageUtils +import org.microg.tools.AccountPickerActivity + +private const val TAG = "AccountSettingsLoader" + +private val ALLOWED_FALLBACK_PREFIXES = setOf("https://myaccount.google.com/", "https://takeout.google.com/") +private val BROWSABLE_SCREEN_IDS = setOf(1, 200, 400, 502, 527, 10003, 10050, 12700, 12701) +private val ACCOUNT_CHOOSER_URI = Uri.parse("https://accounts.google.com/AccountChooser") + +private const val QUERY_PARAM_CONTINUE = "continue" +private const val QUERY_PARAM_LANG = "hl" +private const val QUERY_PARAM_EMAIL = "Email" + +private const val EXTRA_ALLOWABLE_ACCOUNT_TYPES = "allowableAccountTypes" + +private const val REQUEST_ACCOUNT_PICKER = 1 + +class LoaderActivity : AppCompatActivity() { + private var canAskForAccount = false + + private fun launchFallback() { + val fallbackUrl = intent?.getStringExtra(EXTRA_FALLBACK_URL) + + if (fallbackUrl == null) { + Log.d(TAG, "No fallback") + finishResult(RESULT_CANCELED) + } else if (fallbackUrl in ALLOWED_FALLBACK_PREFIXES) { + // TODO: Error screen? + Log.d(TAG, "Illegal fallback url") + finishResult(RESULT_CANCELED) + } else { + val fallbackAuth = intent?.getBooleanExtra(EXTRA_FALLBACK_AUTH, false) ?: false + val uri = if (fallbackAuth) { + val builder = ACCOUNT_CHOOSER_URI.buildUpon().appendQueryParameter(QUERY_PARAM_CONTINUE, fallbackUrl) + val accountName = intent?.getStringExtra(EXTRA_ACCOUNT_NAME) + if (!accountName.isNullOrBlank()) { + builder.appendQueryParameter(QUERY_PARAM_EMAIL, accountName) + } + val lang = Uri.parse(fallbackUrl).getQueryParameter(QUERY_PARAM_LANG) + if (lang != null) { + builder.appendQueryParameter(QUERY_PARAM_LANG, lang) + } + builder.build() + } else { + Uri.parse(fallbackUrl) + } + Log.d(TAG, "Opening fallback $fallbackUrl") + val intent = Intent(ACTION_VIEW, uri).apply { addCategory(CATEGORY_BROWSABLE) } + startActivity(intent) + finishResult(RESULT_OK) + } + } + + private fun launchMain() { + val requestedAccountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME) + val ignoreAccount = intent?.getBooleanExtra(EXTRA_IGNORE_ACCOUNT, false) ?: false + val accounts = AccountManager.get(this).getAccountsByType(DEFAULT_ACCOUNT_TYPE) + val account = if (requestedAccountName != null) { + val account = accounts.find { it.name == requestedAccountName } + if (account == null) { + // TODO: Error screen? + Log.d(TAG, "Account not found: $requestedAccountName") + return finishResult(RESULT_CANCELED) + } + account + } else if (accounts.isEmpty()) { + if (intent?.getStringExtra(EXTRA_FALLBACK_URL) != null) { + return launchFallback() + } else { + // TODO: Error screen? + Log.d(TAG, "No account configured") + return finishResult(RESULT_CANCELED) + } + } else if (accounts.size > 1) { + if (canAskForAccount) { + val intent = Intent(this, AccountPickerActivity::class.java) + intent.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES, arrayOf(DEFAULT_ACCOUNT_TYPE)) + startActivityForResult(intent, REQUEST_ACCOUNT_PICKER) + canAskForAccount = false + return + } else { + return finishResult(RESULT_CANCELED) + } + } else { + accounts.first() + } + + val intent = Intent(this, MainActivity::class.java).apply { + action = intent.action + if (intent.hasExtra(EXTRA_THEME_CHOICE)) putExtra(EXTRA_THEME_CHOICE, intent.getIntExtra(EXTRA_THEME_CHOICE, 0)) + putExtra(EXTRA_ACCOUNT_NAME, account.name) + if (ignoreAccount) putExtra(EXTRA_IGNORE_ACCOUNT, true) + putExtra(EXTRA_SCREEN_ID, intent.getIntExtra(EXTRA_SCREEN_ID, 1)) + for (it in intent.extras?.keySet().orEmpty()) { + if (it.startsWith(EXTRA_SCREEN_OPTIONS_PREFIX)) putExtra(it, intent.getStringExtra(it)) + } + putExtra(EXTRA_CALLING_PACKAGE_NAME, callingActivity?.packageName) + if (intent.action != ACTION_BROWSE_SETTINGS) { + addFlags(FLAG_ACTIVITY_FORWARD_RESULT) + } + } + + startActivity(intent) + + if (!isFinishing && !isChangingConfigurations) { + finishResult(RESULT_OK) + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (requestCode == REQUEST_ACCOUNT_PICKER) { + if (resultCode == RESULT_OK && data?.hasExtra(AccountManager.KEY_ACCOUNT_NAME) == true) { + intent.putExtra(EXTRA_ACCOUNT_NAME, data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)) + launchMain() + } else { + finishResult(resultCode) + } + } else { + super.onActivityResult(requestCode, resultCode, data) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + canAskForAccount = true + val extras = intent?.extras?.also { it.keySet() } + Log.d(TAG, "Invoked with ${intent.action} and extras $extras") + + super.onCreate(savedInstanceState) + + val isMainAllowed = if (intent == null || intent.action != ACTION_BROWSE_SETTINGS) + PackageUtils.isGooglePackage(this, callingActivity?.packageName) + else + extras?.getInt(EXTRA_SCREEN_ID, -1) in BROWSABLE_SCREEN_IDS + + if (!isMainAllowed) { + launchFallback() + } else if (!isFinishing && !isChangingConfigurations){ + launchMain() + } + } + + private fun finishResult(resultCode: Int) { + setResult(resultCode) + finish() + } +} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt new file mode 100644 index 0000000000..17bd6b9c03 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt @@ -0,0 +1,184 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.accountsettings.ui + +import android.accounts.Account +import android.accounts.AccountManager +import android.os.Bundle +import android.util.Log +import android.view.View +import android.webkit.WebView +import android.widget.FrameLayout +import android.widget.ProgressBar +import android.widget.RelativeLayout +import android.widget.RelativeLayout.LayoutParams.MATCH_PARENT +import android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.updateLayoutParams +import org.microg.gms.auth.AuthConstants +import org.microg.gms.common.Constants + +private const val TAG = "AccountSettings" + +// TODO: There likely is some API to figure those out... +private val SCREEN_ID_TO_URL = hashMapOf( + 1 to "https://myaccount.google.com", + 200 to "https://myaccount.google.com/privacycheckup", + 203 to "https://myaccount.google.com/email", + 204 to "https://myaccount.google.com/phone", + 205 to "https://myaccount.google.com/birthday", + 206 to "https://myaccount.google.com/gender", + 210 to "https://myaccount.google.com/locationsharing", + 214 to "https://myaccount.google.com/dashboard", + 215 to "https://takeout.google.com", + 216 to "https://myaccount.google.com/inactive", + 219 to "https://myactivity.google.com/myactivity", + 220 to "https://www.google.com/maps/timeline", + 224 to "https://myactivity.google.com/activitycontrols?settings=search", + 227 to "https://myactivity.google.com/activitycontrols?settings=location", + 231 to "https://myactivity.google.com/activitycontrols?settings=youtube", + 235 to "https://myactivity.google.com/activitycontrols/youtube", + 238 to "https://www.google.com/setting/search/privateresults/", + 241 to "https://myaccount.google.com/communication-preferences", + 300 to "https://myaccount.google.com/language", + 301 to "https://drive.google.com/settings/storage", + 302 to "https://myaccount.google.com/deleteservices", + 303 to "https://myaccount.google.com/deleteaccount", + 307 to "https://payments.google.com/payments/home", + 308 to "https://myaccount.google.com/subscriptions", + 309 to "https://myaccount.google.com/purchases", + 310 to "https://myaccount.google.com/reservations", + 312 to "https://myaccount.google.com/accessibility", + 313 to "https://myaccount.google.com/inputtools", + 400 to "https://myaccount.google.com/security-checkup/", + 401 to "https://myaccount.google.com/signinoptions/password", + 403 to "https://myaccount.google.com/signinoptions/two-step-verification", + 406 to "https://myaccount.google.com/signinoptions/rescuephone", + 407 to "https://myaccount.google.com/recovery/email", + 409 to "https://myaccount.google.com/notifications", + 410 to "https://myaccount.google.com/device-activity", + 417 to "https://myaccount.google.com/find-your-phone", + 425 to "https://myaccount.google.com/account-enhanced-safe-browsing", + 426 to "https://myaccount.google.com/two-step-verification/authenticator", + 427 to "https://myaccount.google.com/two-step-verification/backup-codes", + 429 to "https://myaccount.google.com/two-step-verification/security-keys", + 430 to "https://myaccount.google.com/two-step-verification/prompt", + 431 to "https://myaccount.google.com/connections", + 432 to "https://myaccount.google.com/two-step-verification/phone-numbers", + 433 to "https://myaccount.google.com/signinoptions/passkeys", + 437 to "https://myaccount.google.com/signinoptions/passwordoptional", + 500 to "https://policies.google.com/privacy", + 503 to "https://policies.google.com/terms", + 519 to "https://myaccount.google.com/yourdata/maps", + 520 to "https://myaccount.google.com/yourdata/search", + 530 to "https://fit.google.com/privacy/settings", + 547 to "https://myactivity.google.com/product/search", + 562 to "https://myaccount.google.com/yourdata/youtube", + 10003 to "https://myaccount.google.com/personal-info", + 10004 to "https://myaccount.google.com/data-and-privacy", + 10005 to "https://myaccount.google.com/people-and-sharing", + 10006 to "https://myaccount.google.com/security", + 10007 to "https://myaccount.google.com/payments-and-subscriptions", + 10015 to "https://support.google.com/accounts", + 10050 to "https://myaccount.google.com/profile", + 10090 to "https://myaccount.google.com/profile/name", + 10704 to "https://www.google.com/account/about", + 10706 to "https://myaccount.google.com/profile/profiles-summary", + 10728 to "https://myaccount.google.com/data-and-privacy/how-data-improves-experience", + 10729 to "https://myaccount.google.com/data-and-privacy/data-visibility", + 10759 to "https://myaccount.google.com/address/home", + 10760 to "https://myaccount.google.com/address/work", +) + +private val ALLOWED_WEB_PREFIXES = setOf( + "https://accounts.google.com/", + "https://myaccount.google.com/", + "https://one.google.com/", + "https://myactivity.google.com/", + "https://timeline.google.com/", + "https://takeout.google.com/", + "https://www.google.com/maps/timeline", + "https://www.google.com/setting/", + "https://drive.google.com/settings/", + "https://drive.google.com/accounts/", + "https://drive.google.com/u/1/settings/", + "https://payments.google.com/", + "https://policies.google.com/", + "https://fit.google.com/privacy/settings", +) + +private val ACTION_TO_SCREEN_ID = hashMapOf( + ACTION_MY_ACCOUNT to 1, + ACTION_ACCOUNT_PREFERENCES_SETTINGS to 1, + ACTION_SECURITY_SETTINGS to 10006, + ACTION_PRIVACY_SETTINGS to 10004, +) + +class MainActivity : AppCompatActivity() { + private lateinit var webView: WebView + + private fun getSelectedAccountName(): String? = null + + override fun onCreate(savedInstanceState: Bundle?) { + val extras = intent?.extras?.also { it.keySet() } + Log.d(TAG, "Invoked with ${intent.action} and extras $extras") + super.onCreate(savedInstanceState) + + val screenId = intent?.getIntExtra(EXTRA_SCREEN_ID, -1).takeIf { it != -1 } ?: ACTION_TO_SCREEN_ID[intent.action] ?: 1 + val screenOptions = intent.extras?.keySet().orEmpty() + .filter { it.startsWith(EXTRA_SCREEN_OPTIONS_PREFIX) } + .map { it.substring(EXTRA_SCREEN_OPTIONS_PREFIX.length) to intent.getStringExtra(it) } + .toMap() + + val callingPackage = intent?.getStringExtra(EXTRA_CALLING_PACKAGE_NAME) ?: callingActivity?.packageName ?: Constants.GMS_PACKAGE_NAME + + val ignoreAccount = intent?.getBooleanExtra(EXTRA_IGNORE_ACCOUNT, false) ?: false + val accountName = if (ignoreAccount) null else { + val accounts = AccountManager.get(this).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE) + val accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME) ?: intent.getParcelableExtra("account")?.name ?: getSelectedAccountName() + accounts.find { it.name.equals(accountName) }?.name + } + + if (accountName == null) { + Log.w(TAG, "No account, going without!") + } + + if (screenId in SCREEN_ID_TO_URL) { + val layout = RelativeLayout(this) + layout.addView(ProgressBar(this).apply { + layoutParams = RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { + addRule(RelativeLayout.CENTER_HORIZONTAL) + addRule(RelativeLayout.CENTER_VERTICAL) + } + isIndeterminate = true + }) + webView = WebView(this).apply { + layoutParams = RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) + visibility = View.INVISIBLE + } + layout.addView(webView) + setContentView(layout) + WebViewHelper(this, webView, ALLOWED_WEB_PREFIXES).openWebView(SCREEN_ID_TO_URL[screenId], accountName) + setResult(RESULT_OK) + } else { + Log.w(TAG, "Unknown screen id, can't open corresponding web page") + setResult(RESULT_CANCELED) + finish() + } + } + + override fun onDestroy() { + super.onDestroy() + } + + override fun onBackPressed() { + if (this::webView.isInitialized && webView.canGoBack()) { + webView.goBack() + } else { + super.onBackPressed() + } + } +} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt new file mode 100644 index 0000000000..201af5d172 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.accountsettings.ui + +import android.content.Intent +import android.content.Intent.URI_INTENT_SCHEME +import android.net.Uri +import android.util.Log +import android.view.View +import android.webkit.WebResourceRequest +import android.webkit.WebSettings +import android.webkit.WebView +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import androidx.webkit.WebResourceErrorCompat +import androidx.webkit.WebViewClientCompat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.microg.gms.auth.AuthManager +import org.microg.gms.common.Constants.GMS_PACKAGE_NAME +import org.microg.gms.common.PackageUtils +import java.net.URLEncoder +import java.util.* + +private const val TAG = "AccountSettingsWebView" + +class WebViewHelper(private val activity: AppCompatActivity, private val webView: WebView, private val allowedPrefixes: Set = emptySet()) { + fun openWebView(url: String?, accountName: String?) { + prepareWebViewSettings(webView.settings) + webView.webViewClient = object : WebViewClientCompat() { + override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceErrorCompat) { + Log.w(TAG, "Error loading: $error") + } + + override fun onPageFinished(view: WebView?, url: String?) { + super.onPageFinished(view, url) + webView.visibility = View.VISIBLE + } + + override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { + Log.d(TAG, "Navigating to $url") + if (url.startsWith("intent:")) { + try { + val intent = Intent.parseUri(url, URI_INTENT_SCHEME) + if (intent.`package` == GMS_PACKAGE_NAME || PackageUtils.isGooglePackage(activity, intent.`package`)) { + // Only allow to start Google packages + activity.startActivity(intent) + } else { + Log.w(TAG, "Ignoring request to start non-Google app") + } + } catch (e: Exception) { + Log.w(TAG, "Error invoking intent", e) + } + return false + } + if (allowedPrefixes.isNotEmpty() && allowedPrefixes.none { url.startsWith(it) }) { + try { + activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { addCategory(Intent.CATEGORY_BROWSABLE) }) + } catch (e: Exception) { + Log.w(TAG, "Error forwarding to browser", e) + } + return true + } + return false + } + } + + val urlWithLanguage: String? = addLanguageParam(url) + if (accountName != null) { + activity.lifecycleScope.launch { + withContext(Dispatchers.IO) { + openWebWithAccount(accountName, urlWithLanguage) + } + } + } else { + loadWebViewUrl(urlWithLanguage) + } + } + + private fun loadWebViewUrl(url: String?) { + if (url != null) { + webView.loadUrl(url) + } else { + activity.finish() + } + } + + private fun addLanguageParam(url: String?): String? { + val language = Locale.getDefault().language + return if (language.isNotEmpty()) { + Uri.parse(url).buildUpon().appendQueryParameter("hl", language).toString() + } else { + url + } + } + + private fun openWebWithAccount(accountName: String, url: String?) { + try { + val service = "weblogin:continue=" + URLEncoder.encode(url, "utf-8") + val authManager = AuthManager(activity, accountName, GMS_PACKAGE_NAME, service) + val authUrl = authManager.requestAuth(false)?.auth + if (authUrl?.contains("WILL_NOT_SIGN_IN") == true) { + throw RuntimeException("Would not sign in") + } + Log.d(TAG, "Opening $authUrl") + webView.post { + loadWebViewUrl(authUrl) + } + } catch (e: Exception) { + Log.w(TAG, "Failed to get weblogin auth.", e) + activity.finish() + } + } + + private fun prepareWebViewSettings(settings: WebSettings) { + settings.javaScriptEnabled = true + settings.setSupportMultipleWindows(false) + settings.allowFileAccess = false + settings.databaseEnabled = false + settings.setNeedInitialFocus(false) + settings.useWideViewPort = false + settings.setSupportZoom(false) + settings.javaScriptCanOpenWindowsAutomatically = false + } +} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt new file mode 100644 index 0000000000..5ca88fe76c --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.accountsettings.ui + +const val ACTION_BROWSE_SETTINGS = "com.google.android.gms.accountsettings.action.BROWSE_SETTINGS" +const val ACTION_MY_ACCOUNT = "com.google.android.gms.accountsettings.MY_ACCOUNT" +const val ACTION_ACCOUNT_PREFERENCES_SETTINGS = "com.google.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS" +const val ACTION_PRIVACY_SETTINGS = "com.google.android.gms.accountsettings.PRIVACY_SETTINGS" +const val ACTION_SECURITY_SETTINGS = "com.google.android.gms.accountsettings.SECURITY_SETTINGS" + +const val EXTRA_CALLING_PACKAGE_NAME = "extra.callingPackageName" +const val EXTRA_IGNORE_ACCOUNT = "extra.ignoreAccount" +const val EXTRA_ACCOUNT_NAME = "extra.accountName" +const val EXTRA_SCREEN_ID = "extra.screenId" +const val EXTRA_SCREEN_OPTIONS_PREFIX = "extra.screen." +const val EXTRA_FALLBACK_URL = "extra.fallbackUrl" +const val EXTRA_FALLBACK_AUTH = "extra.fallbackAuth" +const val EXTRA_THEME_CHOICE = "extra.themeChoice" + +const val OPTION_SCREEN_FLAVOR = "screenFlavor" \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/googlehelp/ui/GoogleHelpRedirectActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/googlehelp/ui/GoogleHelpRedirectActivity.kt index 10528c6d3b..1c2d5a970a 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/googlehelp/ui/GoogleHelpRedirectActivity.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/googlehelp/ui/GoogleHelpRedirectActivity.kt @@ -16,7 +16,7 @@ private const val TAG = "GoogleHelpRedirect" class GoogleHelpRedirectActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val callingPackage = callingPackage ?: return finish() + val callingPackage = callingActivity?.packageName ?: return finish() val intent = intent ?: return finish() val googleHelp = intent.getParcelableExtra(EXTRA_GOOGLE_HELP) ?: return finish() Log.d(TAG, "Using GoogleHelp: $googleHelp") diff --git a/play-services-core/src/main/res/xml/preferences_auth.xml b/play-services-core/src/main/res/xml/preferences_auth.xml index d4c0871c44..e2b5a39075 100644 --- a/play-services-core/src/main/res/xml/preferences_auth.xml +++ b/play-services-core/src/main/res/xml/preferences_auth.xml @@ -36,4 +36,11 @@ android:action="com.google.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS" android:targetPackage="com.google.android.gms" /> + + +