Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java
Original file line number Diff line number Diff line change
Expand Up @@ -803,22 +803,24 @@ private void checkUpdate() {
JSONObject jroot = jarray.getJSONObject(0);
// JSONObject jroot = new JSONObject(json.toString());
if (jroot.has("tag_name") && jroot.has("html_url") && jroot.has("assets")) {
// Always link to the release page rather than a specific
// asset: the user picks the right download there, and
// the notification doesn't depend on asset ordering.
String url = jroot.getString("html_url");
JSONArray jassets = jroot.getJSONArray("assets");
if (jassets.length() > 0) {
JSONObject jasset = jassets.getJSONObject(0);
if (jasset.has("name")) {
long available = jroot.getLong("tag_name");
String name = jasset.getString("name");
Log.i(TAG, "Tag " + available + " name " + name + " url " + url);

long current = Util.getSelfVersionCode(ServiceSinkhole.this);
if (current < available) {
Log.i(TAG, "Update available from " + current + " to " + available);
showUpdateNotification(name, url);
} else
Log.i(TAG, "Up-to-date current version " + current);
}
long available = jroot.getLong("tag_name");
String name = (jroot.has("name") && !jroot.isNull("name") && jroot.getString("name").length() > 0)
? jroot.getString("name")
: getString(R.string.title_version, available);
Log.i(TAG, "Tag " + available + " name " + name + " url " + url);

long current = Util.getSelfVersionCode(ServiceSinkhole.this);
if (current < available) {
Log.i(TAG, "Update available from " + current + " to " + available);
showUpdateNotification(name, url);
} else
Log.i(TAG, "Up-to-date current version " + current);
}
}
} catch (JSONException ex) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ Your internet traffic is not being sent to a remote VPN server.</string>
<string name="msg_inactive">No active internet connection</string>
<string name="msg_queue">TrackerControl is busy</string>
<string name="msg_update">Update available, tap to download</string>
<string name="title_version">Version %1$d</string>
<string name="msg_usage">You can allow (greenish) or deny (reddish) Wi-Fi or mobile internet access by tapping on the icons next to an app</string>
<string name="msg_push">Incoming (push) messages are mostly handled by the system component Play services, which is allowed internet access by default</string>
<string name="msg_system">Managing all (system) apps can be enabled in the settings</string>
Expand Down
10 changes: 8 additions & 2 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,14 @@ The script writes the signed APK and verification metadata to
`output/release-2026071301/` and creates a draft GitHub release containing:

- `TrackerControl-githubRelease-latest.apk`
- `SHA256SUMS.txt`
- `BUILD-INFO.txt`
- `TrackerControl-githubRelease-latest.apk.sha256sums`
- `TrackerControl-githubRelease-latest.apk.build-info.txt`

The two metadata files are named with the APK filename as a prefix so they
always sort alphabetically after it. The GitHub API returns release assets
ordered by name, and the app's in-app update checker always downloads
`assets[0]`; without this ordering it can fetch `BUILD-INFO.txt` instead of
the APK (#681).

Install and test the APK from the draft, then publish the release in GitHub.

Expand Down
9 changes: 7 additions & 2 deletions scripts/build_and_sign.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,14 @@ readonly OUTPUT_DIR=${RELEASE_OUTPUT_DIR:-"$ROOT/output/release-$TAG"}
mkdir -p "$OUTPUT_DIR"
readonly ALIGNED_APK="$TEMP_DIR/TrackerControl-githubRelease-aligned.apk"
readonly TEMP_SIGNED_APK="$TEMP_DIR/TrackerControl-githubRelease-signed.apk"
# Asset names must sort alphabetically after the APK: the GitHub API
# returns release assets ordered by name, and the app's update checker
# (ServiceSinkhole#checkUpdate) always takes assets[0] as the download.
# Using the APK filename as a literal prefix guarantees it sorts first
# under any lexicographic comparison, regardless of case-folding rules.
readonly SIGNED_APK="$OUTPUT_DIR/TrackerControl-githubRelease-latest.apk"
readonly SIGNED_SUMS="$OUTPUT_DIR/SHA256SUMS.txt"
readonly OUTPUT_BUILD_INFO="$OUTPUT_DIR/BUILD-INFO.txt"
readonly SIGNED_SUMS="$OUTPUT_DIR/TrackerControl-githubRelease-latest.apk.sha256sums"
readonly OUTPUT_BUILD_INFO="$OUTPUT_DIR/TrackerControl-githubRelease-latest.apk.build-info.txt"
[[ ! -e $SIGNED_APK ]] || fail "signed output already exists: $SIGNED_APK"

printf 'Aligning and signing the APK...\n'
Expand Down