Add basic Google account settings dcf5f1fecb

This commit is contained in:
inotia00 2023-12-24 04:55:14 +09:00 • committed by Cuynu
commit bb405b5b58
8 changed files with 549 additions and 18 deletions

View file

@ -256,7 +256,8 @@
android:name="org.microg.tools.AccountPickerActivity"
android:excludeFromRecents="true"
android:exported="true"
android:process=":ui">
android:process=":ui"
android:theme="@style/Theme.LoginBlue.Base">
<intent-filter>
<action android:name="com.google.android.gms.common.account.CHOOSE_ACCOUNT" />
@ -385,20 +386,49 @@
android:taskAffinity="org.microg.gms.settings" />
<activity
android:name="org.microg.gms.ui.AccountSettingsActivity"
android:name="org.microg.gms.ui.LegacyAccountSettingsActivity"
android:process=":ui"
<<<<<<< HEAD
android:taskAffinity="org.microg.gms.settings"
android:exported="true">
=======
android:taskAffinity="org.microg.gms.settings" />
<activity
android:name="org.microg.gms.accountsettings.ui.MainActivity"
android:process=":ui"
android:exported="false"
android:taskAffinity="org.microg.gms.settings"
android:theme="@style/Theme.LoginBlue.Base">
>>>>>>> 902d5e3d (Add basic Google account settings https://github.com/microg/GmsCore/commit/dcf5f1fecb9add7e640a6bb780cb0c752e5c025e)
<intent-filter>
<action android:name="com.google.android.gms.accountsettings.MY_ACCOUNT" />
<action android:name="com.google.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS" />
<action android:name="com.google.android.gms.accountsettings.PRIVACY_SETTINGS" />
<action android:name="com.google.android.gms.accountsettings.SECURITY_SETTINGS" />
<action android:name="com.google.android.gms.accountsettings.action.VIEW_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="org.microg.gms.accountsettings.ui.LoaderActivity"
android:process=":ui"
android:exported="true"
android:excludeFromRecents="true"
android:theme="@style/Theme.LoginBlue.Base">
<intent-filter>
<action android:name="com.google.android.gms.accountsettings.action.VIEW_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.accountsettings.action.BROWSE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<!-- Other -->
<service android:name="org.microg.gms.auth.SignInService"

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2013-2017 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.ui;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import com.mgoogle.android.gms.R;
import org.microg.gms.auth.AuthConstants;
import org.microg.tools.ui.AbstractSettingsActivity;
import org.microg.tools.ui.ResourceSettingsFragment;
import static android.accounts.AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE;
import static android.accounts.AccountManager.VISIBILITY_NOT_VISIBLE;
import static android.accounts.AccountManager.VISIBILITY_VISIBLE;
import static android.os.Build.VERSION.SDK_INT;
import static org.microg.gms.auth.AuthManager.PREF_AUTH_VISIBLE;
public class LegacyAccountSettingsActivity extends AbstractSettingsActivity {
@Override
protected Fragment getFragment() {
return new AccountSettingsFragment();
}
public static class AccountSettingsFragment extends ResourceSettingsFragment {
public AccountSettingsFragment() {
preferencesResource = R.xml.preferences_account;
}
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
Preference pref = findPreference(PREF_AUTH_VISIBLE);
if (pref != null) {
if (SDK_INT < 26) {
pref.setVisible(false);
} else {
pref.setOnPreferenceChangeListener((preference, newValue) -> {
if (newValue instanceof Boolean) {
AccountManager am = AccountManager.get(getContext());
for (Account account : am.getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE)) {
am.setAccountVisibility(account, PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, (Boolean) newValue ? VISIBILITY_VISIBLE : VISIBILITY_NOT_VISIBLE);
}
}
return true;
});
}
}
}
}
}

View file

@ -16,16 +16,15 @@
package org.microg.tools;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
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) {
@ -36,16 +35,8 @@ public class AccountPickerActivity extends Activity {
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();
}
}

View file

@ -0,0 +1,165 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.accountsettings.ui
import android.accounts.AccountManager
import android.content.Intent
import android.content.Intent.ACTION_VIEW
import android.content.Intent.CATEGORY_BROWSABLE
import android.content.Intent.FLAG_ACTIVITY_FORWARD_RESULT
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
@Suppress("DEPRECATION")
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)
}
}
@Deprecated("Deprecated in Java")
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()
}
}

View file

@ -0,0 +1,185 @@
/*
* 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.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 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",
"https://maps.google.com/maps/timeline"
)
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,
)
@Suppress("DEPRECATION")
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>("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()
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (this::webView.isInitialized && webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}
}

View file

@ -0,0 +1,130 @@
/*
* 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<String> = emptySet<String>()) {
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
}
@Deprecated("Deprecated in Java")
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
}
}

View file

@ -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"

View file

@ -36,4 +36,11 @@
android:action="@string/var_pref_auth_action_preferences_settings"
android:targetPackage="@string/var_pref_start_gms_package" />
</PreferenceScreen>
<PreferenceScreen
android:key="legacy"
android:title="Legacy settings">
<intent
android:targetClass="org.microg.gms.ui.LegacyAccountSettingsActivity"
android:targetPackage="@string/var_pref_start_gms_package" />
</PreferenceScreen>
</PreferenceScreen>