Skip to content

Commit 0cff405

Browse files
committed
Add basic, anonymous analytics with option to disable in Help menu
1 parent bff5eb7 commit 0cff405

File tree

8 files changed

+152
-3
lines changed

8 files changed

+152
-3
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2021 airsquared
3+
*
4+
* This file is part of blobsaver.
5+
*
6+
* blobsaver is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, version 3 of the License.
9+
*
10+
* blobsaver is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with blobsaver. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package airsquared.blobsaver.app;
20+
21+
import java.io.InputStream;
22+
import java.net.MalformedURLException;
23+
import java.net.URL;
24+
import java.net.URLEncoder;
25+
import java.nio.charset.StandardCharsets;
26+
import java.util.Locale;
27+
import java.util.UUID;
28+
29+
final class Analytics {
30+
31+
private static final String trackingID = "UA-197702248-2";
32+
33+
public static void startup() {
34+
collect("/");
35+
}
36+
37+
public static void saveBlobs() {
38+
collect("/save-blobs");
39+
}
40+
41+
public static void saveDevice() {
42+
collect("/save-device");
43+
}
44+
45+
public static void startBackground() {
46+
collect("/start-background");
47+
}
48+
49+
public static void readInfo() {
50+
collect("/read/info");
51+
}
52+
53+
public static void readAPNonce(boolean jailbroken) {
54+
collect("/read/apnonce/" + (jailbroken ? "jailbroken" : "unjailbroken"));
55+
}
56+
57+
public static void olderDevices(boolean show) {
58+
collect("/older-devices/" + (show ? "show" : "hide"));
59+
}
60+
61+
public static void checkBlobs() {
62+
collect("/check-blobs");
63+
}
64+
65+
public static void exitRecovery() {
66+
collect("/exit-recovery");
67+
}
68+
69+
public static void resetPrefs() {
70+
collect("/clear-app-data");
71+
}
72+
73+
public static void disableAnalytics() {
74+
collect("/disable-analytics");
75+
}
76+
77+
private static void collect(String page) {
78+
if (Prefs.getDisableAnalytics()) {
79+
return;
80+
}
81+
sendRequest(getBaseUrl() + "&t=pageview&dl=" + encode(page) + "&an=blobsaver&av=" + encode(Main.appVersion) + "&ul=" + encode(Locale.getDefault().toLanguageTag()));
82+
}
83+
84+
private static String getBaseUrl() {
85+
return "http://www.google-analytics.com/collect?v=1&aip=1&ds=app&tid=" + trackingID + "&cid=" + getUUID();
86+
}
87+
88+
private static String getUUID() {
89+
if (Prefs.getAnalyticsUUID() == null) {
90+
Prefs.setAnalyticsUUID(UUID.randomUUID().toString());
91+
}
92+
return Prefs.getAnalyticsUUID();
93+
}
94+
95+
@SuppressWarnings({"EmptyTryBlock", "unused"})
96+
private static void sendRequest(String url) {
97+
try (InputStream is = new URL(url).openStream()) {
98+
} catch (MalformedURLException e) {
99+
throw new IllegalArgumentException(e);
100+
} catch (Throwable e) { // don't interrupt application if error occurs
101+
e.printStackTrace();
102+
}
103+
}
104+
105+
private static String encode(String s) {
106+
return URLEncoder.encode(s, StandardCharsets.UTF_8);
107+
}
108+
109+
}

src/main/java/airsquared/blobsaver/app/Background.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ public static void startBackground() {
182182
systemctl("enable", "--user", "--now", "blobsaver.timer");
183183
runOnce(); // systemd doesn't start it automatically when enabled
184184
}
185+
Analytics.startBackground();
185186
}
186187

187188
public static void stopBackground() {

src/main/java/airsquared/blobsaver/app/Controller.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,14 @@ public void showOlderDevicesHandler(Event evt) {
253253
Devices.updateLists();
254254
}
255255

256-
public void checkBlobs() { Utils.openURL("https://verify.shsh.host"); }
256+
public void disableAnalyticsHandler(Event evt) {
257+
Prefs.setDisableAnalytics(((CheckMenuItem) evt.getSource()).isSelected());
258+
}
259+
260+
public void checkBlobs() {
261+
Utils.openURL("https://verify.shsh.host");
262+
Analytics.checkBlobs();
263+
}
257264

258265
public void helpLabelHandler(Event evt) {
259266
if (Main.SHOW_BREAKPOINT) {
@@ -329,7 +336,7 @@ private void useMacOSMenuBar() {
329336
new SeparatorMenuItem(), tk.createBringAllToFrontItem());
330337
tk.autoAddWindowMenuItems(menuBar.getMenus().get(3));
331338

332-
menuBar.getMenus().get(4).getItems().remove(8, 10); // remove about
339+
menuBar.getMenus().get(4).getItems().remove(10); // remove about
333340

334341
tk.setApplicationMenu(applicationMenu);
335342
tk.setGlobalMenuBar(menuBar);
@@ -516,6 +523,7 @@ public void readInfo() {
516523
Utils.showReportableError("An unknown error occurred.", Utils.exceptionToString(e));
517524
}
518525
}
526+
Analytics.readInfo();
519527
}
520528

521529
public void readApnonce() {
@@ -568,6 +576,7 @@ public void exitRecoveryHandler() {
568576
e.printStackTrace();
569577
e.showErrorAlert();
570578
}
579+
Analytics.exitRecovery();
571580
}
572581

573582
public void donate() { Utils.openURL("https://www.paypal.me/airsqrd"); }

src/main/java/airsquared/blobsaver/app/LibimobiledeviceUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ protected Void call() throws LibimobiledeviceException {
154154

155155
updateMessage("Success");
156156

157+
Analytics.readAPNonce(jailbroken);
157158
return null;
158159
}
159160

src/main/java/airsquared/blobsaver/app/Main.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public void start(Stage primaryStage) {
118118
primaryStage.setResizable(false);
119119
Utils.checkForUpdates(false);
120120
primaryStage.show();
121+
Analytics.startup();
121122
Prefs.setLastAppVersion(appVersion);
122123
}
123124

src/main/java/airsquared/blobsaver/app/Prefs.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public static void resetPrefs() {
4949
} catch (BackingStoreException e) {
5050
throw new RuntimeException(e);
5151
}
52+
Analytics.resetPrefs();
5253
}
5354

5455
public static void export(File file) {
@@ -104,8 +105,26 @@ public static boolean shouldIgnoreVersion(String testForVersion) {
104105
return testForVersion.equals(appPrefs.get("Ignore Version", null));
105106
}
106107

108+
public static boolean getDisableAnalytics() {
109+
return appPrefs.getBoolean("Disable Analytics", false);
110+
}
111+
112+
public static void setDisableAnalytics(boolean disabled) {
113+
appPrefs.putBoolean("Disable Analytics", disabled);
114+
Analytics.disableAnalytics(); // last analytics message that will be sent
115+
}
116+
117+
public static String getAnalyticsUUID() {
118+
return appPrefs.get("Analytics UUID", null);
119+
}
120+
121+
public static void setAnalyticsUUID(String uuid) {
122+
appPrefs.put("Analytics UUID", uuid);
123+
}
124+
107125
public static void setShowOldDevices(boolean showOldDevices) {
108126
appPrefs.putBoolean("Show Old Devices", showOldDevices);
127+
Analytics.olderDevices(showOldDevices);
109128
}
110129

111130
public static boolean getShowOldDevices() {
@@ -305,6 +324,8 @@ public SavedDevice save() {
305324
if (!savedDevicesList.contains(device)) {
306325
savedDevicesList.add(device); // update observable list
307326
}
327+
328+
Analytics.saveDevice();
308329
return device;
309330
}
310331
}

src/main/java/airsquared/blobsaver/app/TSS.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ protected String call() throws TSSException {
109109
}
110110
}
111111

112+
Analytics.saveBlobs();
112113
return sb.toString();
113114
}
114115

src/main/resources/airsquared/blobsaver/app/blobsaver.fxml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,18 @@
6363
<MenuItem mnemonicParsing="false" onAction="#checkBlobs" text="Check for Valid Blobs..."/>
6464
<MenuItem mnemonicParsing="false" onAction="#exitRecoveryHandler" text="Exit Recovery Mode..."/>
6565
<SeparatorMenuItem mnemonicParsing="false"/>
66+
<CheckMenuItem mnemonicParsing="false" text="Disable Sending Analytics"
67+
onAction="#disableAnalyticsHandler">
68+
<selected>
69+
<Prefs fx:factory="getDisableAnalytics"/>
70+
</selected>
71+
</CheckMenuItem>
72+
<SeparatorMenuItem mnemonicParsing="false"/>
6673
<MenuItem mnemonicParsing="false" onAction="#showWiki" text="blobsaver Help/Wiki"/>
6774
<MenuItem mnemonicParsing="false" onAction="#newGithubIssue" text="Send Feedback (Github Issue)"/>
6875
<MenuItem mnemonicParsing="false" onAction="#sendRedditPM" text="Send Feedback (Reddit PM)"/>
6976
<SeparatorMenuItem mnemonicParsing="false"/>
7077
<MenuItem mnemonicParsing="false" onAction="#donate" text="Donate!"/>
71-
<SeparatorMenuItem mnemonicParsing="false"/>
7278
<MenuItem mnemonicParsing="false" onAction="#aboutMenuHandler" text="About"/>
7379
</Menu>
7480
</MenuBar>

0 commit comments

Comments
 (0)