-
-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use cached file from config app in fetching content filtering file
- Loading branch information
1 parent
cc0e78d
commit 813f476
Showing
6 changed files
with
659 additions
and
0 deletions.
There are no files selected for viewing
191 changes: 191 additions & 0 deletions
191
patches/0186-Include-a-java-port-of-atomic-file-and-scoped-file-d.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: fgei <[email protected]> | ||
Date: Mon, 15 Jul 2024 15:29:50 +0000 | ||
Subject: [PATCH] Include a java port of atomic file and scoped file descriptor | ||
utility classes from Apps app | ||
|
||
--- | ||
vanadium/ext/utils/BUILD.gn | 14 +++ | ||
.../app/vanadium/ext/utils/AtomicFile2.java | 101 ++++++++++++++++++ | ||
.../ext/utils/ScopedFileDescriptor.java | 42 ++++++++ | ||
3 files changed, 157 insertions(+) | ||
create mode 100644 vanadium/ext/utils/BUILD.gn | ||
create mode 100644 vanadium/ext/utils/java/src/app/vanadium/ext/utils/AtomicFile2.java | ||
create mode 100644 vanadium/ext/utils/java/src/app/vanadium/ext/utils/ScopedFileDescriptor.java | ||
|
||
diff --git a/vanadium/ext/utils/BUILD.gn b/vanadium/ext/utils/BUILD.gn | ||
new file mode 100644 | ||
index 0000000000000..bc05f3660d5b3 | ||
--- /dev/null | ||
+++ b/vanadium/ext/utils/BUILD.gn | ||
@@ -0,0 +1,14 @@ | ||
+# Copyright 2023 GrapheneOS | ||
+# Use of this source code is governed by a GPL-2.0 style license that can be | ||
+# found in the LICENSE file. | ||
+ | ||
+import("//build/config/android/rules.gni") | ||
+ | ||
+android_library("file_utils_java") { | ||
+ sources = [ | ||
+ "java/src/app/vanadium/ext/utils/AtomicFile2.java", | ||
+ "java/src/app/vanadium/ext/utils/ScopedFileDescriptor.java", | ||
+ ] | ||
+ deps = [ | ||
+ ] | ||
+} | ||
\ No newline at end of file | ||
diff --git a/vanadium/ext/utils/java/src/app/vanadium/ext/utils/AtomicFile2.java b/vanadium/ext/utils/java/src/app/vanadium/ext/utils/AtomicFile2.java | ||
new file mode 100644 | ||
index 0000000000000..e684ba75ee4db | ||
--- /dev/null | ||
+++ b/vanadium/ext/utils/java/src/app/vanadium/ext/utils/AtomicFile2.java | ||
@@ -0,0 +1,101 @@ | ||
+package app.vanadium.ext.utils; | ||
+ | ||
+import android.content.Context; | ||
+import android.os.Build; | ||
+import android.system.ErrnoException; | ||
+import android.system.Os; | ||
+import android.system.OsConstants; | ||
+import android.util.Log; | ||
+ | ||
+ | ||
+import java.io.ByteArrayOutputStream; | ||
+import java.io.File; | ||
+import java.io.FileInputStream; | ||
+import java.io.IOException; | ||
+import java.io.InterruptedIOException; | ||
+import java.nio.file.Files; | ||
+ | ||
+// Class authored by muhomorr in Apps app repository, see | ||
+// https://github.com/GrapheneOS/Apps/commit/43e9d5218374e712f96154b269e554b2debd652d#diff-d95bcaf27889d24a999547d34ab4a980c248cd9f048aebf27524cdc103e58b47 | ||
+// and the copied documentation below: | ||
+// android.util.AtomicFile has several issues: | ||
+// - ignores errors from fsync(), rename(), close() | ||
+// - doesn't do fsync of the containing directory | ||
+// - doesn't enforce having at most one writer at a time | ||
+// - checks for a legacy file name that was used by its older implementation | ||
+public final class AtomicFile2 { | ||
+ | ||
+ public static final String TAG = "cr_AtomicFile2"; | ||
+ | ||
+ public final String name; | ||
+ public final String dirPath; | ||
+ private final File file; | ||
+ public final String filePath; | ||
+ private final String tmpFilePath; | ||
+ | ||
+ // Context.getFilesDir() is the only reliable place to write files: files from cache dir may | ||
+ // disappear mid-write, before rename of tmpPath. Writes to files on shared storage go through | ||
+ // the FUSE daemon, which lowers reliability and performance | ||
+ public AtomicFile2(Context ctx, String name) { | ||
+ File filesDir = ctx.getFilesDir(); | ||
+ this.name = name; | ||
+ this.dirPath = filesDir.getPath(); | ||
+ this.file = new File(filesDir, name); | ||
+ this.filePath = this.file.getPath(); | ||
+ this.tmpFilePath = this.filePath + ".tmp"; | ||
+ } | ||
+ | ||
+ public byte[] read() throws IOException { | ||
+ if (!file.exists()) { | ||
+ return null; | ||
+ } | ||
+ | ||
+ try { | ||
+ return Files.readAllBytes(file.toPath()); | ||
+ } catch (IOException e) { | ||
+ Log.e(TAG, "", e); | ||
+ return null; | ||
+ } | ||
+ } | ||
+ | ||
+ public boolean delete() { | ||
+ synchronized (file) { | ||
+ return file.delete(); | ||
+ } | ||
+ } | ||
+ | ||
+ public void write(byte[] bytes) throws ErrnoException, InterruptedIOException { | ||
+ synchronized (file) { | ||
+ writeInner(bytes); | ||
+ } | ||
+ } | ||
+ | ||
+ private void writeInner(byte[] bytes) throws ErrnoException, InterruptedIOException { | ||
+ int flags = OsConstants.O_RDWR | OsConstants.O_CREAT | | ||
+ // in case there's a leftover file from previous failed write | ||
+ OsConstants.O_TRUNC; | ||
+ int mode = OsConstants.S_IRUSR | OsConstants.S_IWUSR; // 0600 | ||
+ | ||
+ try (ScopedFileDescriptor sfd = | ||
+ new ScopedFileDescriptor(Os.open(tmpFilePath, flags, mode))) { | ||
+ int written = 0; | ||
+ int len = bytes.length; | ||
+ while (written != len) { | ||
+ int chunkLen = len - written; | ||
+ int writeRes = Os.write(sfd.v, bytes, written, chunkLen); | ||
+ if (writeRes < 0 || writeRes > chunkLen) { | ||
+ throw new IllegalStateException("unexpected write result and chunk to write"); | ||
+ } | ||
+ written += writeRes; | ||
+ } | ||
+ | ||
+ Os.fsync(sfd.v); | ||
+ } | ||
+ | ||
+ Os.rename(tmpFilePath, filePath); | ||
+ | ||
+ try (var fd = new ScopedFileDescriptor(Os.open(dirPath, OsConstants.O_RDONLY, 0))) { | ||
+ Os.fsync(fd.v); | ||
+ } | ||
+ } | ||
+} | ||
diff --git a/vanadium/ext/utils/java/src/app/vanadium/ext/utils/ScopedFileDescriptor.java b/vanadium/ext/utils/java/src/app/vanadium/ext/utils/ScopedFileDescriptor.java | ||
new file mode 100644 | ||
index 0000000000000..7934567ff189e | ||
--- /dev/null | ||
+++ b/vanadium/ext/utils/java/src/app/vanadium/ext/utils/ScopedFileDescriptor.java | ||
@@ -0,0 +1,42 @@ | ||
+package app.vanadium.ext.utils; | ||
+ | ||
+import android.content.Context; | ||
+import android.os.ParcelFileDescriptor; | ||
+import android.system.ErrnoException; | ||
+import android.system.Os; | ||
+import android.system.OsConstants; | ||
+import android.util.Log; | ||
+ | ||
+import java.io.File; | ||
+import java.io.FileDescriptor; | ||
+import java.io.IOException; | ||
+ | ||
+// Class authored by muhomorr in Apps app repository, see | ||
+// https://github.com/GrapheneOS/Apps/commit/43e9d5218374e712f96154b269e554b2debd652d#diff-d95bcaf27889d24a999547d34ab4a980c248cd9f048aebf27524cdc103e58b47 | ||
+// and the copied documentation below: | ||
+public final class ScopedFileDescriptor implements AutoCloseable { | ||
+ | ||
+ public static final String TAG = "cr_ScopedFileDescriptor"; | ||
+ | ||
+ public final FileDescriptor v; | ||
+ | ||
+ public ScopedFileDescriptor(FileDescriptor v) { | ||
+ this.v = v; | ||
+ } | ||
+ | ||
+ // Needed for accessing the int value of fd. | ||
+ // Strangely, access to int value of FileDescriptor is restricted behind hidden and discouraged | ||
+ // FileDescriptor.getInt$(), but is part of public API of ParcelFileDescriptor | ||
+ public ParcelFileDescriptor dupToFd() throws IOException { | ||
+ return ParcelFileDescriptor.dup(v); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void close() { | ||
+ try { | ||
+ Os.close(v); | ||
+ } catch (ErrnoException e) { | ||
+ Log.d(TAG, "", e); | ||
+ } | ||
+ } | ||
+} |
130 changes: 130 additions & 0 deletions
130
patches/0187-Add-support-for-upstream-file-based-parsing-of-unind.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: fgei <[email protected]> | ||
Date: Mon, 15 Jul 2024 15:40:55 +0000 | ||
Subject: [PATCH] Add support for upstream file-based parsing of unindexed | ||
content filtering component | ||
|
||
--- | ||
vanadium/android_config/proto/BUILD.gn | 2 + | ||
.../SubresourceFilterComponentUtils.java | 78 +++++++++++++++++++ | ||
.../vanadium/config/VanadiumConfParser.java | 3 + | ||
3 files changed, 83 insertions(+) | ||
create mode 100644 vanadium/android_config/proto/java/src/app/vanadium/config/SubresourceFilterComponentUtils.java | ||
|
||
diff --git a/vanadium/android_config/proto/BUILD.gn b/vanadium/android_config/proto/BUILD.gn | ||
index 5f04b2dca6267..497fd12a4671c 100644 | ||
--- a/vanadium/android_config/proto/BUILD.gn | ||
+++ b/vanadium/android_config/proto/BUILD.gn | ||
@@ -54,12 +54,14 @@ action("config_generation") { | ||
|
||
android_library("browser_config_parser_java") { | ||
sources = [ | ||
+ "java/src/app/vanadium/config/SubresourceFilterComponentUtils.java", | ||
"java/src/app/vanadium/config/VanadiumConfConditionals.java", | ||
"java/src/app/vanadium/config/VanadiumConfParser.java", | ||
] | ||
deps = [ | ||
":config_proto_java", | ||
"//vanadium/android_config:configinfo_java", | ||
+ "//vanadium/ext/utils:file_utils_java", | ||
] | ||
} | ||
|
||
diff --git a/vanadium/android_config/proto/java/src/app/vanadium/config/SubresourceFilterComponentUtils.java b/vanadium/android_config/proto/java/src/app/vanadium/config/SubresourceFilterComponentUtils.java | ||
new file mode 100644 | ||
index 0000000000000..a42d38734d266 | ||
--- /dev/null | ||
+++ b/vanadium/android_config/proto/java/src/app/vanadium/config/SubresourceFilterComponentUtils.java | ||
@@ -0,0 +1,78 @@ | ||
+package app.vanadium.config; | ||
+ | ||
+import android.content.Context; | ||
+import android.system.ErrnoException; | ||
+import android.util.Log; | ||
+ | ||
+import java.io.InterruptedIOException; | ||
+import java.util.Objects; | ||
+ | ||
+import app.vanadium.config.proto.VanadiumConfigProto; | ||
+import app.vanadium.ext.utils.AtomicFile2; | ||
+ | ||
+public final class SubresourceFilterComponentUtils { | ||
+ | ||
+ private static final String UNINDEXED_RULESET_FILE_NAME = "unindexed_subresource_filter"; | ||
+ private static final String TAG = "cr_SubresourceFilterComponentUtils"; | ||
+ | ||
+ private static SubresourceFilterComponentUtils instance; | ||
+ private static volatile boolean initialized = false; | ||
+ | ||
+ private final AtomicFile2 atomicFileForParsing; | ||
+ | ||
+ SubresourceFilterComponentUtils(Context appCtx) { | ||
+ this.atomicFileForParsing = new AtomicFile2(appCtx, UNINDEXED_RULESET_FILE_NAME); | ||
+ } | ||
+ | ||
+ static SubresourceFilterComponentUtils initialize(Context appCtx) { | ||
+ if (initialized) { | ||
+ return instance; | ||
+ } | ||
+ | ||
+ instance = new SubresourceFilterComponentUtils(appCtx); | ||
+ initialized = true; | ||
+ return instance; | ||
+ } | ||
+ | ||
+ private static SubresourceFilterComponentUtils getInstance() { | ||
+ if (!initialized || instance == null) { | ||
+ Log.w(TAG, "not yet initialized", new Throwable()); | ||
+ return null; | ||
+ } | ||
+ | ||
+ return instance; | ||
+ } | ||
+ | ||
+ public static void writeCurrentContents() { | ||
+ SubresourceFilterComponentUtils instance = getInstance(); | ||
+ if (instance == null) { | ||
+ return; | ||
+ } | ||
+ | ||
+ try { | ||
+ instance.atomicFileForParsing.write( | ||
+ VanadiumConfParser.getByteArrayForComponent( | ||
+ VanadiumConfigProto.Component.ComponentType.SUBRESOURCE_FILTER_TOOLS)); | ||
+ } catch (ErrnoException | InterruptedIOException e) { | ||
+ Log.e(TAG, "", e); | ||
+ } | ||
+ } | ||
+ | ||
+ public static boolean deleteComponentFileForParsing() { | ||
+ SubresourceFilterComponentUtils instance = getInstance(); | ||
+ if (instance == null) { | ||
+ return false; | ||
+ } | ||
+ | ||
+ return instance.atomicFileForParsing.delete(); | ||
+ } | ||
+ | ||
+ public static String getFilePathForParsing() { | ||
+ SubresourceFilterComponentUtils instance = getInstance(); | ||
+ if (instance == null) { | ||
+ return null; | ||
+ } | ||
+ | ||
+ return instance.atomicFileForParsing.filePath; | ||
+ } | ||
+} | ||
diff --git a/vanadium/android_config/proto/java/src/app/vanadium/config/VanadiumConfParser.java b/vanadium/android_config/proto/java/src/app/vanadium/config/VanadiumConfParser.java | ||
index bdb3bf71cebcc..76fcd33f74909 100644 | ||
--- a/vanadium/android_config/proto/java/src/app/vanadium/config/VanadiumConfParser.java | ||
+++ b/vanadium/android_config/proto/java/src/app/vanadium/config/VanadiumConfParser.java | ||
@@ -329,6 +329,9 @@ public final class VanadiumConfParser { | ||
private static void parseInBackground(Context ctx, SpecType specType) { | ||
futureParsedConfigs = executor.submit(() -> { | ||
parsedConfigs = parse(ctx, specType); | ||
+ if (parsedConfigs != null) { | ||
+ SubresourceFilterComponentUtils.initialize(ctx); | ||
+ } | ||
return parsedConfigs; | ||
}); | ||
} |
Oops, something went wrong.