Use preset groups for allowing internet requests

This commit is contained in:
Arjan Schrijver
2025-12-25 14:45:08 +01:00
committed by Arjan Schrijver
parent fc23dcaaaf
commit d2cd47231a
9 changed files with 101 additions and 31 deletions
@@ -51,12 +51,12 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.webview.GBChromeClient;
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient;
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton;
import nodomain.freeyourgadget.gadgetbridge.webview.GBChromeClient;
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient;
public class ExternalPebbleJSActivity extends AbstractGBActivity {
@@ -144,7 +144,7 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
}
private void startBackgroundWebViewAndFinish() {
WebViewSingleton.ensureCreated(this);
WebViewSingleton.ensureCreated(this, GBWebClient.REQUEST_TYPE_PEBBLE_BACKGROUND_JS);
finish();
}
@@ -179,7 +179,7 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
setContentView(R.layout.activity_legacy_external_pebble_js);
myWebView = (WebView) findViewById(R.id.configureWebview);
myWebView.clearCache(true);
myWebView.setWebViewClient(new GBWebClient());
myWebView.setWebViewClient(new GBWebClient(GBWebClient.REQUEST_TYPE_PEBBLE_APP_CONFIG));
myWebView.setWebChromeClient(new GBChromeClient());
WebSettings webSettings = myWebView.getSettings();
//noinspection SetJavaScriptEnabled
@@ -481,7 +481,8 @@ public abstract class AbstractAppManagerFragment extends Fragment {
appListFabNew.show();
}
if (appStoreActivity != null && mGBDevice.getDeviceCoordinator() instanceof PebbleCoordinator) {
boolean appStoreAllowed = GBApplication.getPrefs().getBoolean("pref_key_internethelper_allow_pebble_appstore", false);
if (appStoreAllowed && appStoreActivity != null && mGBDevice.getDeviceCoordinator() instanceof PebbleCoordinator) {
if (InternetHelperSingleton.INSTANCE.ensureInternetHelperBound()) {
appListFabStore.setOnClickListener(v -> {
Intent startIntent = new Intent(getContext(), appStoreActivity);
@@ -665,8 +666,9 @@ public abstract class AbstractAppManagerFragment extends Fragment {
startActivity(startIntent);
return true;
} else if (itemId == R.id.appmanager_app_openinstore) {
boolean appStoreAllowed = GBApplication.getPrefs().getBoolean("pref_key_internethelper_allow_pebble_appstore", false);
final String url = "https://apps.rebble.io/en_US/search/" + ((selectedApp.getType() == GBDeviceApp.Type.WATCHFACE) ? "watchfaces" : "watchapps") + "/1/?native=true&query=" + Uri.encode(selectedApp.getUUID().toString());
if (InternetHelperSingleton.INSTANCE.ensureInternetHelperBound()) {
if (appStoreAllowed && InternetHelperSingleton.INSTANCE.ensureInternetHelperBound()) {
final Intent startIntent = new Intent(getContext().getApplicationContext(), RebbleAppStoreActivity.class);
startIntent.putExtra(DeviceService.EXTRA_URI, url);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, mGBDevice);
@@ -35,10 +35,10 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService
import nodomain.freeyourgadget.gadgetbridge.webview.GBChromeClient
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient
import nodomain.freeyourgadget.gadgetbridge.util.GB
import nodomain.freeyourgadget.gadgetbridge.util.InternetHelperSingleton
import nodomain.freeyourgadget.gadgetbridge.webview.GBChromeClient
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient
import nodomain.freeyourgadget.internethelper.aidl.http.HttpGetRequest
import nodomain.freeyourgadget.internethelper.aidl.http.HttpHeaders
import nodomain.freeyourgadget.internethelper.aidl.http.HttpResponse
@@ -172,7 +172,7 @@ class RebbleAppStoreActivity : AbstractGBActivity() {
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
webView!!.webViewClient = object : GBWebClient() {
webView!!.webViewClient = object : GBWebClient(GBWebClient.REQUEST_TYPE_PEBBLE_APP_STORE) {
override fun shouldOverrideUrlLoading(
wv: WebView,
request: WebResourceRequest
@@ -54,8 +54,8 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs.BangleJSDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.webview.GBWebClient;
public class AppsManagementActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(AppsManagementActivity.class);
@@ -210,7 +210,7 @@ public class AppsManagementActivity extends AbstractGBActivity {
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(mGBDevice.getAddress()));
final String url = devicePrefs.getString(PREF_BANGLEJS_WEBVIEW_URL, "https://banglejs.com/apps/android.html").trim();
webView.setWebViewClient(new GBWebClient(){
webView.setWebViewClient(new GBWebClient(GBWebClient.REQUEST_TYPE_BANGLE_APP_LOADER){
@Override
public void onPageFinished(WebView view, String weburl){
//webView.loadUrl("javascript:showToast('WebView in Espruino')");
@@ -205,9 +205,6 @@ public class PebbleCoordinator extends AbstractBLClassicDeviceCoordinator {
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
final List<Integer> generic = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.GENERIC);
generic.add(R.xml.devicesettings_device_internet_access);
final List<Integer> notifications = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS);
notifications.add(R.xml.devicesettings_autoremove_notifications);
notifications.add(R.xml.devicesettings_pebble_calls_notifications);
@@ -49,7 +49,7 @@ public class WebViewSingleton {
private WebViewSingleton() {
}
public static synchronized void ensureCreated(Context context) {
public static synchronized void ensureCreated(Context context, int requestType) {
if (instance.webView == null) {
instance.contextWrapper = new MutableContextWrapper(context);
instance.mainLooper = context.getMainLooper();
@@ -58,7 +58,7 @@ public class WebViewSingleton {
instance.webView.setWillNotDraw(true);
instance.webView.clearCache(true);
instance.webView.resumeTimers();
instance.webView.setWebViewClient(new GBWebClient());
instance.webView.setWebViewClient(new GBWebClient(requestType));
instance.webView.setWebChromeClient(new GBChromeClient());
WebSettings webSettings = instance.webView.getSettings();
//noinspection SetJavaScriptEnabled
@@ -102,7 +102,7 @@ public class WebViewSingleton {
}
public void runJavascriptInterface(@NonNull Context context, @NonNull GBDevice device, @NonNull UUID uuid) {
ensureCreated(context);
ensureCreated(context, GBWebClient.REQUEST_TYPE_PEBBLE_BACKGROUND_JS);
InternetHelperSingleton.INSTANCE.ensureInternetHelperBound();
if (uuid.equals(currentRunningUUID)) {
LOG.debug("WEBVIEW uuid not changed keeping the old context");
@@ -18,7 +18,6 @@
package nodomain.freeyourgadget.gadgetbridge.webview;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.RemoteException;
import android.webkit.WebResourceRequest;
@@ -50,15 +49,28 @@ import nodomain.freeyourgadget.gadgetbridge.entities.URLFilterEntry;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather;
import nodomain.freeyourgadget.gadgetbridge.model.weather.WeatherMapper;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.InternetHelperSingleton;
public class GBWebClient extends WebViewClient {
private static final Logger LOG = LoggerFactory.getLogger(GBWebClient.class);
public static int REQUEST_TYPE_OTHER = 0;
public static int REQUEST_TYPE_PEBBLE_APP_STORE = 1;
public static int REQUEST_TYPE_PEBBLE_APP_CONFIG = 2;
public static int REQUEST_TYPE_PEBBLE_BACKGROUND_JS = 3;
public static int REQUEST_TYPE_BANGLE_APP_LOADER = 4;
private int requestType;
private String[] LocallySupportedDomains = new String[]{
"openweathermap.org", //for weather :)
"rawgit.com", //for trekvolle
};
private static final Logger LOG = LoggerFactory.getLogger(GBWebClient.class);
public GBWebClient(int type) {
super();
requestType = type;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
@@ -81,8 +93,10 @@ public class GBWebClient extends WebViewClient {
}
private WebResourceResponse mimicReply(Uri requestedUri) {
GBPrefs prefs = GBApplication.getPrefs();
boolean locallySupported = StringUtils.indexOfAny(requestedUri.getHost(), LocallySupportedDomains) != -1;
boolean urlIsAllowed = locallySupported;
boolean matchFound = false;
List<URLFilterEntry> urlFilterEntries = DBHelper.getURLFilterEntries();
// Handle local schemes locally
@@ -90,8 +104,23 @@ public class GBWebClient extends WebViewClient {
return null;
}
// Handle predefined groups
if (requestType == REQUEST_TYPE_PEBBLE_APP_STORE) {
matchFound = true;
urlIsAllowed = prefs.getBoolean("pref_key_internethelper_allow_pebble_appstore", false);
} else if (requestType == REQUEST_TYPE_PEBBLE_APP_CONFIG) {
matchFound = true;
urlIsAllowed = prefs.getBoolean("pref_key_internethelper_allow_pebble_configs", false);
} else if (requestType == REQUEST_TYPE_PEBBLE_BACKGROUND_JS) {
matchFound = true;
urlIsAllowed = prefs.getBoolean("pref_key_internethelper_allow_pebble_background_js", false);
} else if (requestType == REQUEST_TYPE_BANGLE_APP_LOADER) {
matchFound = true;
urlIsAllowed = prefs.getBoolean("pref_key_internethelper_allow_bangle_app_loader", false);
}
// Search for matches
boolean matchFound = false;
if (!matchFound) {
for (URLFilterEntry entry : urlFilterEntries) {
if (requestedUri.toString().contains(entry.getUrl())) {
matchFound = true;
@@ -99,11 +128,11 @@ public class GBWebClient extends WebViewClient {
LOG.info("URL matched with URLFilterEntry: {}, allowed={}", entry.getUrl(), entry.getAllowed());
}
}
}
// Handle OpenWeatherMap locally
boolean forceLocal = false;
SharedPreferences sharedPreferences = GBApplication.getPrefs().getPreferences();
if (locallySupported && sharedPreferences.getBoolean("pref_key_internethelper_force_local", true)) {
if (locallySupported && prefs.getBoolean("pref_key_internethelper_force_local", true)) {
matchFound = true;
urlIsAllowed = true;
forceLocal = true;
@@ -112,7 +141,7 @@ public class GBWebClient extends WebViewClient {
// Add to database if missing
if (requestedUri.getHost() != null && !matchFound) {
LOG.info("URL not matched with URLFilterEntry, storing new entry");
String defaultAction = sharedPreferences.getString("pref_key_internethelper_new_url_action", "deny");
String defaultAction = prefs.getString("pref_key_internethelper_new_url_action", "deny");
urlIsAllowed = defaultAction.equals("allow");
URLFilterEntry filterEntry = new URLFilterEntry();
filterEntry.setUrl(requestedUri.toString().replaceAll("\\?.*", ""));
@@ -141,7 +170,7 @@ public class GBWebClient extends WebViewClient {
}
}
} else {
LOG.debug("WEBVIEW request not intercepted:{}", requestedUri);
LOG.debug("WEBVIEW request not intercepted: {}", requestedUri);
}
return null;
}
+10 -1
View File
@@ -4468,7 +4468,16 @@
<string name="internet_helper_pref_new_url_action_summary">Set the default action to take when a URL is requested that isn\'t already in the list below.</string>
<string name="internet_helper_pref_intercept_supported_title">Intercept supported requests</string>
<string name="internet_helper_pref_intercept_supported_summary">Some internet requests can be intercepted and responded to locally without sending anything to the internet.</string>
<string name="internet_helper_pref_known_urls_title">Known URLs</string>
<string name="internet_helper_pref_allowed_connections">Allowed connections</string>
<string name="internet_helper_pref_pebble_app_store_title">Pebble app store</string>
<string name="internet_helper_pref_pebble_app_store_summary">Access the Pebble app store for app installations and updates</string>
<string name="internet_helper_pref_pebble_background_js_title">Requests from Pebble apps</string>
<string name="internet_helper_pref_pebble_background_js_summary">Allow Pebble watch apps and watchfaces to access the internet</string>
<string name="internet_helper_pref_pebble_app_config_title">Pebble app configuration pages</string>
<string name="internet_helper_pref_pebble_app_config_summary">Allow access to webpages that are needed for configuring apps and watchfaces</string>
<string name="internet_helper_pref_bangle_app_loader_title">Bangle app loader</string>
<string name="internet_helper_pref_bangle_app_loader_summary">Access the Bangle app loader website</string>
<string name="internet_helper_pref_other_urls_title">Other URLs</string>
<string name="internet_helper_url_list_instruction_summary">Use the list below to configure which (parts of) URLs are allowed or denied to be forwarded to the internethelper add-on app. The validation is using a simple text comparison, so a part of a URL can be entered too.</string>
<string name="rebble_appstore_download_failed_wrong_content_type">Download failed, wrong content-type: %1$s</string>
<string name="rebble_appstore_download_failed">Download failed: %1$s</string>
@@ -26,9 +26,42 @@
android:summary="@string/internet_helper_pref_intercept_supported_summary"
app:iconSpaceReserved="false" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_key_internethelper_allowed_connections"
android:title="@string/internet_helper_pref_allowed_connections"
app:iconSpaceReserved="false">
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="pref_key_internethelper_allow_pebble_appstore"
android:layout="@layout/preference_checkbox"
android:title="@string/internet_helper_pref_pebble_app_store_title"
android:summary="@string/internet_helper_pref_pebble_app_store_summary"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="pref_key_internethelper_allow_pebble_background_js"
android:layout="@layout/preference_checkbox"
android:title="@string/internet_helper_pref_pebble_background_js_title"
android:summary="@string/internet_helper_pref_pebble_background_js_summary"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="pref_key_internethelper_allow_pebble_configs"
android:layout="@layout/preference_checkbox"
android:title="@string/internet_helper_pref_pebble_app_config_title"
android:summary="@string/internet_helper_pref_pebble_app_config_summary"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="pref_key_internethelper_allow_bangle_app_loader"
android:layout="@layout/preference_checkbox"
android:title="@string/internet_helper_pref_bangle_app_loader_title"
android:summary="@string/internet_helper_pref_bangle_app_loader_summary"
app:iconSpaceReserved="false" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_key_internethelper_url_list"
android:title="@string/internet_helper_pref_known_urls_title"
android:title="@string/internet_helper_pref_other_urls_title"
app:iconSpaceReserved="false">
<Preference
android:key="pref_key_internethelper_info"