package nodomain.freeyourgadget.gadgetbridge.womp; import android.Manifest; import android.annotation.SuppressLint; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import nodomain.freeyourgadget.gadgetbridge.R; public class WompWebActivity extends AppCompatActivity implements WompJsBridge.Host { public static final String EXTRA_PAGE = "page"; private static final int REQ_SCAN = 7101; private static final int REQ_PERM = 7102; private WebView webView; private String pendingScanCb; private long lastBackPressedAt; public static Intent open(android.content.Context ctx, String page) { Intent i = new Intent(ctx, WompWebActivity.class); i.putExtra(EXTRA_PAGE, page); return i; } @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(@Nullable Bundle savedInstanceState) { setTheme(R.style.GadgetbridgeTheme_NoActionBar); super.onCreate(savedInstanceState); setContentView(R.layout.activity_womp_web); webView = findViewById(R.id.womp_webview); WebSettings s = webView.getSettings(); s.setJavaScriptEnabled(true); s.setDomStorageEnabled(true); s.setAllowFileAccess(true); s.setAllowContentAccess(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { s.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { if (url != null && (url.endsWith("home.html") || url.endsWith("login.html"))) { view.clearHistory(); } } }); webView.setWebChromeClient(new WebChromeClient()); webView.addJavascriptInterface(new WompJsBridge(this, this), "Womp"); String page = getIntent().getStringExtra(EXTRA_PAGE); if (page == null || page.length() == 0) { page = WompSession.isLoggedIn(this) ? "home.html" : "login.html"; } webView.loadUrl("file:///android_asset/womp/" + page); ensureRuntimePermissions(); } private void ensureRuntimePermissions() { java.util.ArrayList need = new java.util.ArrayList<>(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { need.add(Manifest.permission.CAMERA); } if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { need.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { need.add(Manifest.permission.POST_NOTIFICATIONS); } if (!need.isEmpty()) { ActivityCompat.requestPermissions(this, need.toArray(new String[0]), REQ_PERM); } } @Override public void scan(String callbackId) { pendingScanCb = callbackId; startActivityForResult(new Intent(this, WompScanActivity.class), REQ_SCAN); } @Override public void closePage() { finish(); } @Override public void onLoggedIn() { WompKeepAliveService.start(this); if (webView != null) { webView.loadUrl("file:///android_asset/womp/home.html"); } } @Override public void onLogout() { if (webView != null) { webView.loadUrl("file:///android_asset/womp/login.html"); } } @Override public void evalJs(String script) { if (webView != null) { webView.evaluateJavascript(script, null); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQ_SCAN && pendingScanCb != null) { String code = resultCode == RESULT_OK && data != null ? data.getStringExtra(WompScanActivity.EXTRA_CODE) : ""; String script = "window.__wompCb && window.__wompCb(" + org.json.JSONObject.quote(pendingScanCb) + ",true," + org.json.JSONObject.quote(code == null ? "" : code) + ")"; evalJs(script); pendingScanCb = null; } } @Override public void onBackPressed() { if (webView != null && webView.canGoBack()) { webView.goBack(); return; } if (!isTaskRoot()) { super.onBackPressed(); return; } long now = System.currentTimeMillis(); if (now - lastBackPressedAt < 2000) { finishAffinity(); return; } lastBackPressedAt = now; Toast.makeText(this, R.string.womp_press_again_to_exit, Toast.LENGTH_SHORT).show(); } }