Skip to content

Commit 159454b

Browse files
only support versionCode
would love to support version name but it's not going to work out very well Signed-off-by: androidacy-user <opensource@androidacy.com>
1 parent e57829f commit 159454b

12 files changed

Lines changed: 197 additions & 104 deletions

File tree

app/build.gradle.kts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ android {
9898
// current timestamp of build
9999
buildConfigField("long", "BUILD_TIME", "$timestamp")
100100
// debug http requests. do not set this to true if you care about performance!!!!!
101-
buildConfigField("boolean", "DEBUG_HTTP", "false")
101+
if (System.getenv("CI") != null) {
102+
buildConfigField("boolean", "DEBUG_HTTP", "true")
103+
} else {
104+
buildConfigField("boolean", "DEBUG_HTTP", "false")
105+
}
102106
// Latest commit hash as BuildConfig.COMMIT_HASH
103107
buildConfigField("String", "COMMIT_HASH", "\"$gitCommitHash\"")
104108
// Get the current branch name as BuildConfig.BRANCH_NAME
@@ -161,7 +165,12 @@ android {
161165
// current timestamp of build
162166
buildConfigField("long", "BUILD_TIME", "$timestamp")
163167
// debug http requests. do not set this to true if you care about performance!!!!!
164-
buildConfigField("boolean", "DEBUG_HTTP", "false")
168+
// if env var CI is set to true, this will be true
169+
if (System.getenv("CI") != null) {
170+
buildConfigField("boolean", "DEBUG_HTTP", "true")
171+
} else {
172+
buildConfigField("boolean", "DEBUG_HTTP", "false")
173+
}
165174
// Latest commit hash as BuildConfig.COMMIT_HASH
166175
buildConfigField("String", "COMMIT_HASH", "\"$gitCommitHash\"")
167176
// Get the current branch name as BuildConfig.BRANCH_NAME
@@ -223,8 +232,11 @@ android {
223232
// current timestamp of build
224233
buildConfigField("long", "BUILD_TIME", "$timestamp")
225234
// debug http requests. do not set this to true if you care about performance!!!!!
226-
buildConfigField("boolean", "DEBUG_HTTP", "false")
227-
235+
if (System.getenv("CI") != null) {
236+
buildConfigField("boolean", "DEBUG_HTTP", "true")
237+
} else {
238+
buildConfigField("boolean", "DEBUG_HTTP", "false")
239+
}
228240
// Latest commit hash as BuildConfig.COMMIT_HASH
229241
buildConfigField("String", "COMMIT_HASH", "\"$gitCommitHash\"")
230242
// Get the current branch name as BuildConfig.BRANCH_NAME
@@ -469,6 +481,9 @@ dependencies {
469481

470482
// desugaring
471483
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
484+
485+
// yes
486+
implementation("com.github.fingerprintjs:fingerprint-android:2.0.0")
472487
}
473488

474489
android {

app/src/main/java/com/fox2code/mmm/MainActivity.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import com.fox2code.foxcompat.app.FoxActivity;
3636
import com.fox2code.foxcompat.view.FoxDisplay;
37+
import com.fox2code.mmm.androidacy.AndroidacyRepoData;
3738
import com.fox2code.mmm.background.BackgroundUpdateChecker;
3839
import com.fox2code.mmm.installer.InstallerInitializer;
3940
import com.fox2code.mmm.manager.LocalModuleInfo;
@@ -55,13 +56,15 @@
5556
import java.sql.Timestamp;
5657
import java.util.ArrayList;
5758
import java.util.List;
59+
import java.util.Objects;
5860

5961
import io.realm.Realm;
6062
import io.realm.RealmConfiguration;
6163
import timber.log.Timber;
6264

6365
public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener, SearchView.OnQueryTextListener, SearchView.OnCloseListener, OverScrollManager.OverScrollHelper {
6466
private static final int PRECISION = 10000;
67+
private static MainActivity INSTANCE;
6568
public static boolean doSetupNowRunning = true;
6669
public static boolean doSetupRestarting = false;
6770
public static List<LocalModuleInfo> localModuleInfoList = new ArrayList<>();
@@ -420,6 +423,7 @@ public void commonNext() {
420423
searchView.setEnabled(true);
421424
updateScreenInsets(getResources().getConfiguration());
422425
});
426+
maybeShowUpgrade();
423427
Timber.i("Finished app opening state!");
424428
}
425429
}, true);
@@ -702,4 +706,60 @@ public void onWindowFocusChanged(boolean hasFocus) {
702706
super.onWindowFocusChanged(hasFocus);
703707
this.updateScreenInsets();
704708
}
709+
710+
711+
712+
public void maybeShowUpgrade() {
713+
if (AndroidacyRepoData.getInstance() == null || AndroidacyRepoData.getInstance().memberLevel == null) {
714+
// wait for up to 10 seconds for AndroidacyRepoData to be initialized
715+
int i = 0;
716+
while (AndroidacyRepoData.getInstance() == null && i < 10) {
717+
try {
718+
//noinspection BusyWait
719+
Thread.sleep(1000);
720+
} catch (InterruptedException e) {
721+
Timber.e(e);
722+
}
723+
i++;
724+
}
725+
if (AndroidacyRepoData.getInstance().isEnabled() && AndroidacyRepoData.getInstance().memberLevel == null) {
726+
Timber.d("Member level is null, waiting for it to be initialized");
727+
i = 0;
728+
while (AndroidacyRepoData.getInstance().memberLevel == null && i < 20) {
729+
i++;
730+
try {
731+
//noinspection BusyWait
732+
Thread.sleep(500);
733+
} catch (InterruptedException e) {
734+
Timber.e(e);
735+
}
736+
}
737+
}
738+
// if it's still null, but it's enabled, throw an error
739+
if (AndroidacyRepoData.getInstance().isEnabled() && AndroidacyRepoData.getInstance().memberLevel == null) {
740+
throw new IllegalStateException("AndroidacyRepoData is enabled, but member level is null");
741+
}
742+
if (AndroidacyRepoData.getInstance() != null && AndroidacyRepoData.getInstance().isEnabled() && Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) {
743+
runtimeUtils.showUpgradeSnackbar(this, this);
744+
} else {
745+
if (!AndroidacyRepoData.getInstance().isEnabled()) {
746+
Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 1");
747+
} else if (!Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) {
748+
Timber.i("AndroidacyRepoData is not Guest, not showing upgrade snackbar 1. Level: %s", AndroidacyRepoData.getInstance().memberLevel);
749+
} else {
750+
Timber.i("Unknown error, not showing upgrade snackbar 1");
751+
}
752+
}
753+
} else if (AndroidacyRepoData.getInstance().isEnabled() && Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) {
754+
runtimeUtils.showUpgradeSnackbar(this, this);
755+
} else {
756+
if (!AndroidacyRepoData.getInstance().isEnabled()) {
757+
Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 2");
758+
} else if (!Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) {
759+
Timber.i("AndroidacyRepoData is not Guest, not showing upgrade snackbar 2. Level: %s", AndroidacyRepoData.getInstance().memberLevel);
760+
} else {
761+
Timber.i("Unknown error, not showing upgrade snackbar 2");
762+
}
763+
}
764+
}
705765
}

app/src/main/java/com/fox2code/mmm/UpdateActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public void downloadUpdate() throws JSONException {
224224
});
225225
}
226226
// convert to JSON
227-
JSONObject latestJSON = new JSONObject(Arrays.toString(lastestJSON));
227+
JSONObject latestJSON = new JSONObject(new String(lastestJSON));
228228
String changelog = latestJSON.getString("body");
229229
// set changelog text. changelog could be markdown, so we need to convert it to HTML
230230
MaterialTextView changelogTextView = findViewById(R.id.update_changelog);

app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,14 @@ public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathC
275275

276276
@Override
277277
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
278-
switch (consoleMessage.messageLevel()) {
279-
case TIP -> Timber.tag("JSLog").i(consoleMessage.message());
280-
case LOG -> Timber.tag("JSLog").d(consoleMessage.message());
281-
case WARNING -> Timber.tag("JSLog").w(consoleMessage.message());
282-
case ERROR -> Timber.tag("JSLog").e(consoleMessage.message());
283-
default -> Timber.tag("JSLog").v(consoleMessage.message());
278+
if (BuildConfig.DEBUG_HTTP) {
279+
switch (consoleMessage.messageLevel()) {
280+
case TIP -> Timber.tag("JSLog").i(consoleMessage.message());
281+
case LOG -> Timber.tag("JSLog").d(consoleMessage.message());
282+
case WARNING -> Timber.tag("JSLog").w(consoleMessage.message());
283+
case ERROR -> Timber.tag("JSLog").e(consoleMessage.message());
284+
default -> Timber.tag("JSLog").v(consoleMessage.message());
285+
}
284286
}
285287
return true;
286288
}

app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.fox2code.mmm.androidacy;
22

33
import android.annotation.SuppressLint;
4+
import android.app.Activity;
5+
import android.content.Context;
46
import android.content.Intent;
57
import android.content.SharedPreferences;
68
import android.net.Uri;
@@ -10,18 +12,23 @@
1012

1113
import androidx.annotation.NonNull;
1214

15+
import com.fingerprintjs.android.fingerprint.Fingerprinter;
16+
import com.fingerprintjs.android.fingerprint.FingerprinterFactory;
17+
import com.fox2code.foxcompat.app.FoxActivity;
18+
import com.fox2code.foxcompat.app.internal.FoxCompat;
1319
import com.fox2code.mmm.BuildConfig;
20+
import com.fox2code.mmm.MainActivity;
1421
import com.fox2code.mmm.MainApplication;
1522
import com.fox2code.mmm.R;
1623
import com.fox2code.mmm.manager.ModuleInfo;
1724
import com.fox2code.mmm.repo.RepoData;
1825
import com.fox2code.mmm.repo.RepoManager;
1926
import com.fox2code.mmm.repo.RepoModule;
27+
import com.fox2code.mmm.utils.RuntimeUtils;
2028
import com.fox2code.mmm.utils.io.PropUtils;
2129
import com.fox2code.mmm.utils.io.net.Http;
2230
import com.fox2code.mmm.utils.io.net.HttpException;
2331
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
24-
import com.topjohnwu.superuser.Shell;
2532

2633
import org.json.JSONArray;
2734
import org.json.JSONException;
@@ -31,13 +38,13 @@
3138
import java.io.IOException;
3239
import java.net.HttpURLConnection;
3340
import java.net.URL;
34-
import java.security.MessageDigest;
35-
import java.security.NoSuchAlgorithmException;
3641
import java.util.ArrayList;
3742
import java.util.Arrays;
3843
import java.util.Iterator;
3944
import java.util.List;
4045
import java.util.Objects;
46+
import java.util.UUID;
47+
import java.util.concurrent.atomic.AtomicReference;
4148

4249
import okhttp3.HttpUrl;
4350
import timber.log.Timber;
@@ -94,59 +101,36 @@ public static String generateDeviceId() {
94101
}
95102
// Try to get the device ID from the shared preferences
96103
SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("androidacy");
97-
String deviceIdPref = sharedPreferences.getString("device_id", null);
104+
String deviceIdPref = sharedPreferences.getString("device_id_v2", null);
98105
if (deviceIdPref != null) {
99106
ANDROIDACY_DEVICE_ID = deviceIdPref;
100107
return deviceIdPref;
101108
} else {
102-
// Really not that scary - just hashes some device info. We can't even get the info
103-
// we originally hashed, so it's not like we can use it to track you.
104-
String deviceId = null;
105-
// Get ro.serialno if it exists
106-
// First, we need to get an su shell
107-
Shell.Result result = Shell.cmd("getprop ro.serialno").exec();
108-
// Check if the command was successful
109-
if (result.isSuccess()) {
110-
// Get the output
111-
String output = result.getOut().get(0);
112-
// Check if the output is valid
113-
if (output != null && !output.isEmpty()) {
114-
deviceId = output;
109+
Fingerprinter fp = FingerprinterFactory.create(MainApplication.getINSTANCE().getApplicationContext());
110+
fp.getFingerprint(Fingerprinter.Version.V_5, fingerprint-> {
111+
ANDROIDACY_DEVICE_ID = fingerprint;
112+
// use fingerprint
113+
// Save the device ID to the shared preferences
114+
SharedPreferences.Editor editor = sharedPreferences.edit();
115+
editor.putString("device_id_v2", ANDROIDACY_DEVICE_ID);
116+
editor.apply();
117+
return null;
118+
});
119+
// wait for up to 5 seconds for the fingerprint to be generated (ANDROIDACY_DEVICE_ID to be set)
120+
long startTime = System.currentTimeMillis();
121+
while (ANDROIDACY_DEVICE_ID == null && System.currentTimeMillis() - startTime < 5000) {
122+
try {
123+
//noinspection BusyWait
124+
Thread.sleep(100);
125+
} catch (InterruptedException ignored) {
126+
Thread.currentThread().interrupt();
115127
}
116128
}
117-
// Now, get device model, manufacturer, and Android version originally from
118-
String deviceModel = android.os.Build.MODEL;
119-
String deviceManufacturer = android.os.Build.MANUFACTURER;
120-
String androidVersion = android.os.Build.VERSION.RELEASE;
121-
// Append it all together
122-
deviceId += deviceModel + deviceManufacturer + androidVersion;
123-
// Hash it
124-
MessageDigest digest;
125-
try {
126-
digest = MessageDigest.getInstance("SHA-256");
127-
} catch (NoSuchAlgorithmException ignored) {
128-
// This should never happen so we can just return the original device ID
129-
ANDROIDACY_DEVICE_ID = deviceId;
130-
return deviceId;
131-
}
132-
byte[] hash = digest.digest(deviceId.getBytes());
133-
// Convert it to a hex string
134-
StringBuilder hexString = new StringBuilder();
135-
for (byte b : hash) {
136-
String hex = Integer.toHexString(0xff & b);
137-
if (hex.length() == 1) {
138-
hexString.append('0');
139-
}
140-
hexString.append(hex);
129+
if (ANDROIDACY_DEVICE_ID == null) {
130+
// fingerprint generation failed, use a random UUID
131+
ANDROIDACY_DEVICE_ID = UUID.randomUUID().toString();
141132
}
142-
// Save it to shared preferences
143-
SharedPreferences.Editor editor = sharedPreferences.edit();
144-
editor.putString("device_id", hexString.toString());
145-
editor.apply();
146-
// Set ANDROIDACY_DEVICE_ID
147-
ANDROIDACY_DEVICE_ID = hexString.toString();
148-
// Return it
149-
return hexString.toString();
133+
return ANDROIDACY_DEVICE_ID;
150134
}
151135
}
152136

@@ -155,8 +139,9 @@ public boolean isValidToken(String token) throws IOException {
155139
try {
156140
byte[] resp = Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token + "&device_id=" + deviceId + "&client_id=" + BuildConfig.ANDROIDACY_CLIENT_ID, false);
157141
// response is JSON
158-
JSONObject jsonObject = new JSONObject(Arrays.toString(resp));
142+
JSONObject jsonObject = new JSONObject(new String(resp));
159143
memberLevel = jsonObject.getString("role");
144+
Timber.d("Member level: %s", memberLevel);
160145
JSONArray memberPermissions = jsonObject.getJSONArray("permissions");
161146
// set role and permissions on userInfo property
162147
userInfo = new String[][]{{"role", memberLevel}, {"permissions", String.valueOf(memberPermissions)}};
@@ -252,7 +237,7 @@ protected boolean prepare() {
252237
try {
253238
Timber.i("Requesting new token...");
254239
// POST json request to https://production-api.androidacy.com/auth/register
255-
token = Arrays.toString(Http.doHttpPost("https://" + this.host + "/auth/register?client_id=" + BuildConfig.ANDROIDACY_CLIENT_ID, "{\"device_id\":\"" + deviceId + "\"}", false));
240+
token = new String(Http.doHttpPost("https://" + this.host + "/auth/register?client_id=" + BuildConfig.ANDROIDACY_CLIENT_ID, "{\"device_id\":\"" + deviceId + "\"}", false));
256241
// Parse token
257242
try {
258243
JSONObject jsonObject = new JSONObject(token);
@@ -261,6 +246,7 @@ protected boolean prepare() {
261246
//noinspection SuspiciousRegexArgument
262247
Timber.d("Token: %s", token.substring(0, token.length() - 4).replaceAll(".", "*") + token.substring(token.length() - 4));
263248
memberLevel = jsonObject.getString("role");
249+
Timber.d("Member level: %s", memberLevel);
264250
} catch (JSONException e) {
265251
Timber.e(e, "Failed to parse token");
266252
// Show a toast

app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,6 @@ public static String getMarkdownFromAPI(String url) {
133133
if (md == null) {
134134
return null;
135135
}
136-
return Arrays.toString(md);
136+
return new String(md);
137137
}
138138
}

app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,34 +153,28 @@ static void doCheck(Context context) {
153153
}
154154
RepoModule repoModule = repoModules.get(localModuleInfo.id);
155155
localModuleInfo.checkModuleUpdate();
156-
String remoteVersion = localModuleInfo.updateVersion;
157156
String remoteVersionCode = String.valueOf(localModuleInfo.updateVersionCode);
158157
if (repoModule != null) {
159-
remoteVersion = repoModule.moduleInfo.version;
160158
remoteVersionCode = String.valueOf(repoModule.moduleInfo.versionCode);
161159
}
162-
// now, coerce everything into an int
163160
int localVersionCode = Integer.parseInt(String.valueOf(localModuleInfo.versionCode));
164161
int remoteVersionCodeInt = Integer.parseInt(remoteVersionCode);
165-
// we also have to match the version name
166-
int localVersion = Integer.parseInt(localModuleInfo.version);
167-
int remoteVersionInt = Integer.parseInt(remoteVersion);
168-
int wantsVersion = Integer.parseInt(version.split(":")[1]);
162+
int wantsVersion = Integer.parseInt(version.split(":")[1].replaceAll("[^0-9]", ""));
169163
// now find out if user wants up to and including this version, or this version and newer
170164
// if it starts with ^, it's this version and newer, if it ends with $, it's this version and older
171165
if (version.startsWith("^")) {
172166
// this version and newer
173-
if (wantsVersion > localVersion || wantsVersion > remoteVersionInt || wantsVersion > remoteVersionCodeInt || wantsVersion < localVersionCode) {
167+
if (wantsVersion <= remoteVersionCodeInt || wantsVersion <= localVersionCode) {
174168
// if it is, we skip it
175169
continue;
176170
}
177171
} else if (version.endsWith("$")) {
178172
// this version and older
179-
if (wantsVersion < localVersion || wantsVersion < remoteVersionInt || wantsVersion < remoteVersionCodeInt || wantsVersion > localVersionCode) {
173+
if (wantsVersion >= remoteVersionCodeInt || wantsVersion >= localVersionCode) {
180174
// if it is, we skip it
181175
continue;
182176
}
183-
} else if (wantsVersion == localVersion || wantsVersion == remoteVersionInt || wantsVersion == remoteVersionCodeInt || wantsVersion == localVersionCode) {
177+
} else if (wantsVersion == remoteVersionCodeInt || wantsVersion == localVersionCode) {
184178
// if it is, we skip it
185179
continue;
186180
}

0 commit comments

Comments
 (0)