mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 18:10:29 +00:00
Remove extension WebView data during uninstall
This commit is contained in:
1 parent
c47b735fc4
commit
d642ae5018
25 files changed
+609
-19
No files matched your search
@@ -29,7 +29,7 @@ android {
|
||||
compileSdk 34
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
minSdkVersion 21
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
@@ -49,7 +49,7 @@ android {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'androidx.webkit:webkit:1.12.0'
|
||||
implementation 'androidx.webkit:webkit:1.13.0'
|
||||
implementation 'androidx.browser:browser:1.8.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
+83
@@ -1,6 +1,12 @@
|
||||
package com.pichillilorenzo.flutter_inappwebview_android;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.webkit.Profile;
|
||||
import androidx.webkit.WebStorageCompat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import androidx.webkit.ProfileStore;
|
||||
import androidx.webkit.ProxyConfig;
|
||||
import androidx.webkit.ProxyController;
|
||||
@@ -10,6 +16,76 @@ import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
// Internal host bridge: profile creation and proxy completion precede navigation.
|
||||
final class GopeedProfiles {
|
||||
private static SharedPreferences preferences;
|
||||
private static final Set<String> cleared = new HashSet<>();
|
||||
private static final String DELETIONS = "pendingDeletions";
|
||||
|
||||
static void initialize(Context context) {
|
||||
if (preferences != null) return;
|
||||
preferences = context.getSharedPreferences("gopeed_webview_profiles", Context.MODE_PRIVATE);
|
||||
if (!WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE)) return;
|
||||
for (String id : deletions()) {
|
||||
try {
|
||||
// Do this before getProfile/getOrCreateProfile load any profile.
|
||||
ProfileStore.getInstance().deleteProfile(id);
|
||||
setPending(id, false);
|
||||
} catch (RuntimeException ignored) {
|
||||
// Keep the durable entry and reject use until removal succeeds.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> deletions() {
|
||||
return new HashSet<>(preferences.getStringSet(DELETIONS, new HashSet<>()));
|
||||
}
|
||||
|
||||
private static void setPending(String id, boolean pending) {
|
||||
Set<String> ids = deletions();
|
||||
if (pending) ids.add(id); else ids.remove(id);
|
||||
if (!preferences.edit().putStringSet(DELETIONS, ids).commit())
|
||||
throw new IllegalStateException("Unable to persist WebView profile removal");
|
||||
}
|
||||
|
||||
static void remove(MethodCall call, MethodChannel.Result result) {
|
||||
if (!WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE)) {
|
||||
result.error("UNAVAILABLE", "Android WebView profile removal is unavailable", null);
|
||||
return;
|
||||
}
|
||||
String id = call.argument("gopeedProfileId");
|
||||
try {
|
||||
java.util.UUID.fromString(id);
|
||||
setPending(id, true);
|
||||
try {
|
||||
ProfileStore.getInstance().deleteProfile(id);
|
||||
setPending(id, false);
|
||||
cleared.remove(id);
|
||||
result.success(true);
|
||||
return;
|
||||
} catch (IllegalStateException loadedProfile) {
|
||||
// Android forbids deleting a profile loaded in this process, even
|
||||
// after every WebView has been destroyed. Clear all its data now;
|
||||
// remove the empty profile at the next process start.
|
||||
}
|
||||
if (!WebViewFeature.isFeatureSupported(WebViewFeature.DELETE_BROWSING_DATA)) {
|
||||
result.error("PROFILE_REMOVE_FAILED", "Restart Gopeed to finish removing WebView profile data", null);
|
||||
return;
|
||||
}
|
||||
Profile profile = ProfileStore.getInstance().getProfile(id);
|
||||
if (profile == null) {
|
||||
setPending(id, false);
|
||||
result.success(true);
|
||||
return;
|
||||
}
|
||||
profile.getGeolocationPermissions().clearAll();
|
||||
WebStorageCompat.deleteBrowsingData(profile.getWebStorage(), () -> {
|
||||
cleared.add(id);
|
||||
result.success(true);
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
result.error("PROFILE_REMOVE_FAILED", "Unable to remove WebView profile data", null);
|
||||
}
|
||||
}
|
||||
|
||||
private static String appliedProxy;
|
||||
private static String pendingProxy;
|
||||
private static final java.util.List<MethodChannel.Result> pending = new java.util.ArrayList<>();
|
||||
@@ -26,6 +102,13 @@ final class GopeedProfiles {
|
||||
Uri uri = Uri.parse(proxy);
|
||||
if (!"http".equals(uri.getScheme()) || !"127.0.0.1".equals(uri.getHost()) || uri.getPort() <= 0)
|
||||
throw new IllegalArgumentException("Invalid host proxy configuration");
|
||||
if (deletions().contains(id)) {
|
||||
if (!cleared.contains(id)) throw new IllegalStateException("Profile removal requires restart");
|
||||
// Reinstallation may reuse the now-empty profile. Do not delete its
|
||||
// new data on the next start.
|
||||
setPending(id, false);
|
||||
cleared.remove(id);
|
||||
}
|
||||
ProfileStore.getInstance().getOrCreateProfile(id);
|
||||
if (proxy.equals(appliedProxy)) { result.success(true); return; }
|
||||
if (pendingProxy != null) {
|
||||
|
||||
+1
@@ -87,6 +87,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
||||
|
||||
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
|
||||
this.applicationContext = applicationContext;
|
||||
GopeedProfiles.initialize(applicationContext);
|
||||
this.activity = activity;
|
||||
this.messenger = messenger;
|
||||
this.flutterView = flutterView;
|
||||
|
||||
+4
@@ -49,6 +49,10 @@ public class MyCookieManager extends ChannelDelegateImpl {
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
if (call.method.equals("gopeed.removeProfile")) {
|
||||
GopeedProfiles.remove(call, result);
|
||||
return;
|
||||
}
|
||||
if (call.method.equals("gopeed.prepareProfile")) {
|
||||
GopeedProfiles.prepare(call, result);
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user