Skip to content

Commit 880c2b6

Browse files
committed
refactor: improve browser architecture and signing
- Refactor `BrowserScreen` structure to support better navigation and lifecycle handling - Enhance background media playback script with robust visibility API overrides - Update build configuration to include default values for signing credentials
1 parent 7bf2a3d commit 880c2b6

6 files changed

Lines changed: 303 additions & 240 deletions

File tree

.github/workflows/release.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,14 @@ jobs:
6060
distribution: 'microsoft'
6161
cache: gradle
6262

63-
- name: Setup Android Keystore for Release
63+
- name: Setup Android Release Keystore
6464
run: |
65+
if [ ! -f release.keystore ]; then
66+
echo "Generating consistent release.keystore for signing..."
67+
keytool -genkeypair -v -keystore release.keystore -alias feather_release_key -keyalg RSA -keysize 2048 -validity 10000 -storepass feather123 -keypass feather123 -dname "CN=Feather Browser, OU=Mobile Applications, O=Feather Privacy Browser, L=San Francisco, ST=California, C=US"
68+
fi
6569
if [ ! -f debug.keystore ]; then
66-
echo "Generating build debug.keystore for signing..."
67-
keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=Android Debug,O=Android,C=US"
70+
cp release.keystore debug.keystore || true
6871
fi
6972
7073
- name: Grant execute permission for gradlew

app/build.gradle.kts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,23 @@ android {
2222
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2323
}
2424

25-
val releaseKeystore = file(System.getenv("KEYSTORE_PATH") ?: "${rootDir}/my-upload-key.jks")
25+
val releaseKeystore = file(System.getenv("KEYSTORE_PATH") ?: "${rootDir}/release.keystore")
26+
val debugKeystore = file("${rootDir}/debug.keystore")
2627
signingConfigs {
2728
create("debugConfig") {
28-
storeFile = file("${rootDir}/debug.keystore")
29-
storePassword = "android"
30-
keyAlias = "androiddebugkey"
31-
keyPassword = "android"
29+
if (debugKeystore.exists()) {
30+
storeFile = debugKeystore
31+
storePassword = "android"
32+
keyAlias = "androiddebugkey"
33+
keyPassword = "android"
34+
}
3235
}
33-
if (releaseKeystore.exists()) {
34-
create("release") {
36+
create("releaseConfig") {
37+
if (releaseKeystore.exists()) {
3538
storeFile = releaseKeystore
36-
storePassword = System.getenv("STORE_PASSWORD")
37-
keyAlias = System.getenv("KEY_ALIAS") ?: "upload"
38-
keyPassword = System.getenv("KEY_PASSWORD")
39+
storePassword = System.getenv("STORE_PASSWORD") ?: "feather123"
40+
keyAlias = System.getenv("KEY_ALIAS") ?: "feather_release_key"
41+
keyPassword = System.getenv("KEY_PASSWORD") ?: "feather123"
3942
}
4043
}
4144
}
@@ -49,10 +52,10 @@ android {
4952
getDefaultProguardFile("proguard-android-optimize.txt"),
5053
"proguard-rules.pro"
5154
)
52-
if (releaseKeystore.exists()) {
53-
signingConfig = signingConfigs.getByName("release")
55+
signingConfig = if (releaseKeystore.exists()) {
56+
signingConfigs.getByName("releaseConfig")
5457
} else {
55-
signingConfig = signingConfigs.getByName("debugConfig")
58+
signingConfigs.getByName("debugConfig")
5659
}
5760
}
5861
debug {

app/src/main/java/com/example/privacy/FingerprintScriptGenerator.kt

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,56 @@ object FingerprintScriptGenerator {
7878
if (window.__feather_bg_play_active) return;
7979
window.__feather_bg_play_active = true;
8080
81-
// 1. Override Page Visibility API so media sites always consider the tab active
81+
// 1. Override Page Visibility API on both document instance and Document.prototype
8282
try {
83-
Object.defineProperty(document, 'hidden', { get: function() { return false; }, configurable: true });
84-
Object.defineProperty(document, 'visibilityState', { get: function() { return 'visible'; }, configurable: true });
85-
Object.defineProperty(document, 'webkitHidden', { get: function() { return false; }, configurable: true });
86-
Object.defineProperty(document, 'webkitVisibilityState', { get: function() { return 'visible'; }, configurable: true });
83+
const defineProp = function(obj, prop, value) {
84+
try {
85+
Object.defineProperty(obj, prop, {
86+
get: function() { return value; },
87+
set: function() {},
88+
configurable: true,
89+
enumerable: true
90+
});
91+
} catch(e) {}
92+
};
93+
94+
defineProp(document, 'hidden', false);
95+
defineProp(document, 'visibilityState', 'visible');
96+
defineProp(document, 'webkitHidden', false);
97+
defineProp(document, 'webkitVisibilityState', 'visible');
98+
defineProp(Document.prototype, 'hidden', false);
99+
defineProp(Document.prototype, 'visibilityState', 'visible');
100+
defineProp(Document.prototype, 'webkitHidden', false);
101+
defineProp(Document.prototype, 'webkitVisibilityState', 'visible');
102+
87103
document.hasFocus = function() { return true; };
104+
Document.prototype.hasFocus = function() { return true; };
105+
106+
// Override property event handlers
107+
defineProp(document, 'onvisibilitychange', null);
108+
defineProp(window, 'onpagehide', null);
109+
defineProp(window, 'onblur', null);
88110
} catch(e) {}
89111
90112
// 2. Intercept registration of visibility pause event listeners
91113
const origAddEventListener = EventTarget.prototype.addEventListener;
92114
EventTarget.prototype.addEventListener = function(type, listener, options) {
93-
if (type === 'visibilitychange' || type === 'webkitvisibilitychange' || type === 'pagehide') {
115+
if (type === 'visibilitychange' || type === 'webkitvisibilitychange' || type === 'pagehide' || type === 'blur') {
94116
return;
95117
}
96118
return origAddEventListener.apply(this, arguments);
97119
};
98120
99-
// 3. Suppress any existing or bubbling visibilitychange & blur events
100-
const suppressEvents = ['visibilitychange', 'webkitvisibilitychange', 'pagehide', 'blur'];
121+
// 3. Suppress any bubbling visibilitychange & blur events
122+
const suppressEvents = ['visibilitychange', 'webkitvisibilitychange', 'pagehide', 'blur', 'freeze'];
101123
suppressEvents.forEach(function(evt) {
102124
window.addEventListener(evt, function(e) {
103125
if (e && e.stopImmediatePropagation) e.stopImmediatePropagation();
126+
if (e && e.stopPropagation) e.stopPropagation();
104127
}, true);
105128
document.addEventListener(evt, function(e) {
106129
if (e && e.stopImmediatePropagation) e.stopImmediatePropagation();
130+
if (e && e.stopPropagation) e.stopPropagation();
107131
}, true);
108132
});
109133
} catch(e) {}

0 commit comments

Comments
 (0)