From 16c7c4431344a0cc11ce08e885e62eeae0e791ee Mon Sep 17 00:00:00 2001 From: artdeell Date: Fri, 3 Nov 2023 17:08:56 +0300 Subject: [PATCH] Feat[mslogin]: handle WebView state saving --- .../fragments/MicrosoftLoginFragment.java | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java index 5c41d0f8b..316de8424 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java @@ -4,6 +4,7 @@ import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -13,6 +14,7 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import net.kdt.pojavlaunch.R; @@ -24,30 +26,57 @@ public class MicrosoftLoginFragment extends Fragment { public static final String TAG = "MICROSOFT_LOGIN_FRAGMENT"; private WebView mWebview; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mWebview = (WebView) inflater.inflate(R.layout.fragment_microsoft_login, container, false); - CookieManager.getInstance().removeAllCookies(this::onCookiesRemoved); + setWebViewSettings(); + if(savedInstanceState == null) startNewSession(); + else restoreWebViewState(savedInstanceState); return mWebview; } - @SuppressLint("SetJavaScriptEnabled") // required for Microsoft log-in - public void onCookiesRemoved(Boolean b) { + // WebView.restoreState() does not restore the WebSettings or the client, so set them there + // separately. Note that general state should not be altered here (aka no loading pages, no manipulating back/front lists), + // to avoid "undesirable side-effects" + @SuppressLint("SetJavaScriptEnabled") + private void setWebViewSettings() { WebSettings settings = mWebview.getSettings(); - settings.setJavaScriptEnabled(true); - mWebview.clearHistory(); - mWebview.clearCache(true); - mWebview.clearFormData(); - mWebview.clearHistory(); mWebview.setWebViewClient(new WebViewTrackClient()); + } - mWebview.loadUrl("https://login.live.com/oauth20_authorize.srf" + - "?client_id=00000000402b5328" + - "&response_type=code" + - "&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL" + - "&redirect_url=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf"); + private void startNewSession() { + CookieManager.getInstance().removeAllCookies((b)->{ + mWebview.clearHistory(); + mWebview.clearCache(true); + mWebview.clearFormData(); + mWebview.clearHistory(); + mWebview.loadUrl("https://login.live.com/oauth20_authorize.srf" + + "?client_id=00000000402b5328" + + "&response_type=code" + + "&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL" + + "&redirect_url=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf"); + }); + } + + private void restoreWebViewState(Bundle savedInstanceState) { + Log.i("MSAuthFragment","Restoring state..."); + if(mWebview.restoreState(savedInstanceState) == null) { + Log.w("MSAuthFragment", "Failed to restore state, starting afresh"); + // if, for some reason, we failed to restore our session, + // just start afresh + startNewSession(); + } + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + // Since the value cannot be null, just creaqte a "blank" client. This is done to not let Android + // kill us if something happens after onSaveInstanceState + mWebview.setWebViewClient(new WebViewClient()); + mWebview.saveState(outState); + super.onSaveInstanceState(outState); + // if something happens after this, well, too bad } /* Expose webview actions to others */