Add opt-in setting for tracking
This commit is contained in:
parent
c0a1fc84eb
commit
c5d7e482e0
|
@ -158,6 +158,9 @@ public final class Constants {
|
|||
|
||||
public static final String KEY_SIGNATURES_TABLE_INITIALIZED = "key_signatures_table_initialized";
|
||||
|
||||
public static final String KEY_ANALYTICS_ASKED_POLITELY = "analytics_asked";
|
||||
public static final String KEY_ANALYTICS_CONSENT = "analytics_consent";
|
||||
|
||||
public static final class Theme {
|
||||
public static final String LIGHT = "light";
|
||||
public static final String DARK = "dark";
|
||||
|
|
|
@ -6,34 +6,31 @@ import android.app.Application;
|
|||
import android.app.Application.ActivityLifecycleCallbacks;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.piwik.sdk.Piwik;
|
||||
import org.piwik.sdk.Tracker;
|
||||
import org.piwik.sdk.TrackerConfig;
|
||||
import org.piwik.sdk.extra.DownloadTracker.Extra.ApkChecksum;
|
||||
import org.piwik.sdk.extra.TrackHelper;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
|
||||
public class TrackingManager {
|
||||
private Tracker piwikTracker;
|
||||
|
||||
public static TrackingManager getInstance(Context context) {
|
||||
TrackerConfig trackerConfig = new TrackerConfig("https://mugenguild.com/piwik/", 1, "OpenKeychain");
|
||||
Tracker tracker = Piwik.getInstance(context).newTracker(trackerConfig);
|
||||
tracker.setDispatchInterval(30000);
|
||||
|
||||
return new TrackingManager(tracker);
|
||||
return new TrackingManager(context);
|
||||
}
|
||||
|
||||
private TrackingManager(Tracker piwikTracker) {
|
||||
this.piwikTracker = piwikTracker;
|
||||
private TrackingManager(Context context) {
|
||||
refreshSettings(context);
|
||||
}
|
||||
|
||||
public void initialize(Application application) {
|
||||
if (piwikTracker == null) {
|
||||
return;
|
||||
if (piwikTracker != null) {
|
||||
TrackHelper.track().download().identifier(new ApkChecksum(application)).with(piwikTracker);
|
||||
}
|
||||
TrackHelper.track().download().identifier(new ApkChecksum(application)).with(piwikTracker);
|
||||
|
||||
application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
@Override
|
||||
|
@ -47,6 +44,9 @@ public class TrackingManager {
|
|||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
if (piwikTracker == null) {
|
||||
return;
|
||||
}
|
||||
TrackHelper.track().screen(activity.getClass().getSimpleName()).with(piwikTracker);
|
||||
}
|
||||
|
||||
|
@ -99,4 +99,20 @@ public class TrackingManager {
|
|||
.piece(currentCallingPackage.replace(".", "/"))
|
||||
.with(piwikTracker);
|
||||
}
|
||||
|
||||
public synchronized void refreshSettings(Context context) {
|
||||
boolean analyticsHasConsent = Preferences.getPreferences(context).isAnalyticsHasConsent();
|
||||
boolean analyticsEnabled = piwikTracker != null;
|
||||
if (analyticsHasConsent != analyticsEnabled) {
|
||||
if (analyticsHasConsent) {
|
||||
TrackerConfig trackerConfig = new TrackerConfig("https://piwik.openkeychain.org/", 1, "OpenKeychain");
|
||||
piwikTracker = Piwik.getInstance(context).newTracker(trackerConfig);
|
||||
piwikTracker.setDispatchInterval(60000);
|
||||
piwikTracker.setOptOut(false);
|
||||
} else {
|
||||
piwikTracker.setOptOut(true);
|
||||
piwikTracker = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,17 @@ package org.sufficientlysecure.keychain.ui;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.WorkerThread;
|
||||
|
@ -51,9 +56,12 @@ import eu.davidea.flexibleadapter.FlexibleAdapter;
|
|||
import eu.davidea.flexibleadapter.FlexibleAdapter.OnItemClickListener;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter.OnItemLongClickListener;
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter.Mode;
|
||||
import org.sufficientlysecure.keychain.BuildConfig;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.KeychainApplication;
|
||||
import org.sufficientlysecure.keychain.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.TrackingManager;
|
||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||
import org.sufficientlysecure.keychain.daos.DatabaseNotifyManager;
|
||||
import org.sufficientlysecure.keychain.daos.KeyRepository;
|
||||
|
@ -259,6 +267,8 @@ public class KeyListFragment extends RecyclerFragment<FlexibleAdapter<FlexibleKe
|
|||
GenericViewModel viewModel = ViewModelProviders.of(this).get(GenericViewModel.class);
|
||||
LiveData<List<FlexibleKeyItem>> liveData = viewModel.getGenericLiveData(requireContext(), this::loadFlexibleKeyItems);
|
||||
liveData.observe(this, this::onLoadKeyItems);
|
||||
|
||||
maybeAskForAnalytics();
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
@ -267,6 +277,45 @@ public class KeyListFragment extends RecyclerFragment<FlexibleAdapter<FlexibleKe
|
|||
return flexibleKeyItemFactory.mapUnifiedKeyInfoToFlexibleKeyItems(unifiedKeyInfo);
|
||||
}
|
||||
|
||||
private void maybeAskForAnalytics() {
|
||||
Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Preferences preferences = Preferences.getPreferences(context);
|
||||
if (!Constants.DEBUG && !preferences.isAnalyticsHasConsent() && preferences.isAnalyticsAskedPolitely()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
long firstInstallTime = context.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 0).firstInstallTime;
|
||||
long threeDaysAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(3);
|
||||
boolean installedLessThanThreeDaysAgo = firstInstallTime > threeDaysAgo;
|
||||
if (installedLessThanThreeDaysAgo) {
|
||||
return;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrackingManager trackingManager = ((KeychainApplication) requireActivity().getApplication()).getTrackingManager();
|
||||
AlertDialog show = new Builder(context)
|
||||
.setMessage(R.string.dialog_analytics_text)
|
||||
.setPositiveButton(R.string.button_analytics_yes, (dialog, which) -> {
|
||||
preferences.setAnalyticsAskedPolitely();
|
||||
preferences.setAnalyticsGotUserConsent(true);
|
||||
trackingManager.refreshSettings(context);
|
||||
})
|
||||
.setNegativeButton(R.string.button_analytics_no, (dialog, which) -> {
|
||||
preferences.setAnalyticsAskedPolitely();
|
||||
preferences.setAnalyticsGotUserConsent(false);
|
||||
trackingManager.refreshSettings(context);
|
||||
})
|
||||
.show();
|
||||
show.setCanceledOnTouchOutside(false);
|
||||
}
|
||||
|
||||
private void onLoadKeyItems(List<FlexibleKeyItem> flexibleKeyItems) {
|
||||
FlexibleAdapter<FlexibleKeyItem> adapter = getAdapter();
|
||||
if (adapter == null) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import android.os.Bundle;
|
|||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
@ -50,6 +51,7 @@ import android.view.ViewGroup;
|
|||
import android.widget.LinearLayout;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.Constants.Pref;
|
||||
import org.sufficientlysecure.keychain.KeychainApplication;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.AppCompatPreferenceActivity;
|
||||
|
@ -584,6 +586,14 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
Activity activity = getActivity();
|
||||
((KeychainApplication) activity.getApplication()).getTrackingManager().refreshSettings(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
|
|
|
@ -353,6 +353,22 @@ public class Preferences {
|
|||
mSharedPreferences.edit().putBoolean(Pref.SYNC_IS_SCHEDULED, isScheduled).apply();
|
||||
}
|
||||
|
||||
public boolean isAnalyticsAskedPolitely() {
|
||||
return mSharedPreferences.getBoolean(Pref.KEY_ANALYTICS_ASKED_POLITELY, false);
|
||||
}
|
||||
|
||||
public void setAnalyticsAskedPolitely() {
|
||||
mSharedPreferences.edit().putBoolean(Pref.KEY_ANALYTICS_ASKED_POLITELY, true).apply();
|
||||
}
|
||||
|
||||
public boolean isAnalyticsHasConsent() {
|
||||
return mSharedPreferences.getBoolean(Pref.KEY_ANALYTICS_CONSENT, false);
|
||||
}
|
||||
|
||||
public void setAnalyticsGotUserConsent(boolean hasUserConsent) {
|
||||
mSharedPreferences.edit().putBoolean(Pref.KEY_ANALYTICS_CONSENT, hasUserConsent).apply();
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public static abstract class CloudSearchPrefs implements Parcelable {
|
||||
public abstract boolean isKeyserverEnabled();
|
||||
|
|
|
@ -236,6 +236,9 @@
|
|||
<string name="label_experimental_settings_keybase_summary">"Contact keybase.io for key proofs and show them every time a key is displayed"</string>
|
||||
<string name="label_experimental_settings_theme_summary">"(The icons and many screens are not yet adjusted accordingly for the dark theme)"</string>
|
||||
|
||||
<string name="label_settings_analytics_title">Allow anonymous usage statistics</string>
|
||||
<string name="label_settings_analytics_summary">If enabled, sends anonymous usage statistics to help improve the app</string>
|
||||
|
||||
<!-- Proxy Preferences -->
|
||||
<string name="pref_proxy_tor_title">"Enable Tor"</string>
|
||||
<string name="pref_proxy_tor_summary">"Requires Orbot to be installed"</string>
|
||||
|
@ -2045,4 +2048,7 @@
|
|||
<string name="keylist_header_anonymous">Anonymous</string>
|
||||
<string name="keylist_header_special">#</string>
|
||||
|
||||
<string name="dialog_analytics_text">Allow OpenKeychain to collect anonymous usage statistics to help improve the app?</string>
|
||||
<string name="button_analytics_yes">Yes, I want to help!</string>
|
||||
<string name="button_analytics_no">No, thanks</string>
|
||||
</resources>
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
android:summary="@string/label_experimental_settings_desc_summary"
|
||||
android:title="@string/label_experimental_settings_desc_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="analytics_consent"
|
||||
android:persistent="true"
|
||||
android:summary="@string/label_settings_analytics_summary"
|
||||
android:title="@string/label_settings_analytics_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="experimentalEnableLinkedIdentities"
|
||||
|
|
Loading…
Reference in a new issue