Niedzielski has uploaded a new change for review. https://gerrit.wikimedia.org/r/223976
Change subject: Add daily stats funnel ...................................................................... Add daily stats funnel - Add event logging up to once a day on page load complete to report the app install lifetime in days. - Add daily event callback method to PageViewFragmentInternal. - Add LongPreference and supporting code and refactor IntPreference. - Fix default IntPreference max digit length for default radix. It is valuable to know the distribution curve of the app installation retention. A new funnel is made available to report this information up to once a day. The funnel may later encompass additional reports at the same frequency. Bug: T103188 Change-Id: I9dcce02fe19954381521d81cc8ec4378af51bf86 --- M wikipedia/res/values/attrs.xml M wikipedia/res/values/preference_keys.xml M wikipedia/res/values/styles.xml M wikipedia/res/xml/developer_preferences.xml A wikipedia/src/main/java/org/wikipedia/analytics/DailyStatsFunnel.java M wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java M wikipedia/src/main/java/org/wikipedia/settings/IntPreference.java A wikipedia/src/main/java/org/wikipedia/settings/LongPreference.java M wikipedia/src/main/java/org/wikipedia/settings/Prefs.java M wikipedia/src/main/java/org/wikipedia/settings/PrefsIoUtil.java 10 files changed, 254 insertions(+), 66 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia refs/changes/76/223976/1 diff --git a/wikipedia/res/values/attrs.xml b/wikipedia/res/values/attrs.xml index d42922e..ec594d1 100644 --- a/wikipedia/res/values/attrs.xml +++ b/wikipedia/res/values/attrs.xml @@ -28,10 +28,14 @@ <attr name="autoSummarize" format="boolean" /> </declare-styleable> - <declare-styleable name="IntPreference"> - <attr name="intPreferenceStyle" format="reference" /> + <declare-styleable name="LongPreference"> + <attr name="longPreferenceStyle" format="reference" /> <attr name="radix" format="integer" /> <attr name="summaryFormat" format="string" /> </declare-styleable> + <declare-styleable name="IntPreference"> + <attr name="intPreferenceStyle" format="reference" /> + </declare-styleable> + </resources> diff --git a/wikipedia/res/values/preference_keys.xml b/wikipedia/res/values/preference_keys.xml index 5b1c36b..0647ef9 100644 --- a/wikipedia/res/values/preference_keys.xml +++ b/wikipedia/res/values/preference_keys.xml @@ -22,6 +22,7 @@ <string name="preference_key_know_toc_drawer">knowToC</string> <string name="preference_key_show_images">showImages</string> <string name="preference_key_exp_page_load">expPageLoad</string> + <string name="preference_key_last_daily_event_time">lastDailyEventTime</string> <string name="preference_key_login_username">username</string> <string name="preference_key_login_password">password</string> <string name="preference_key_login_user_id">userID</string> diff --git a/wikipedia/res/values/styles.xml b/wikipedia/res/values/styles.xml index d21f3d4..e7a5ded 100644 --- a/wikipedia/res/values/styles.xml +++ b/wikipedia/res/values/styles.xml @@ -1,6 +1,7 @@ <resources> <style name="AppTheme" parent="Theme.WikiLight"> <item name="editTextAutoSummarizePreferenceStyle">@style/EditTextAutoSummarizePreference</item> + <item name="longPreferenceStyle">@style/LongPreference</item> <item name="intPreferenceStyle">@style/IntPreference</item> </style> @@ -121,10 +122,14 @@ <!-- parent="@android:style/Preference.DialogPreference.EditTextPreference" is not exposed. --> </style> - <style name="IntPreference" parent="EditTextAutoSummarizePreference"> + <style name="LongPreference" parent="EditTextAutoSummarizePreference"> <item name="android:inputType">number</item> - <item name="android:maxLength">8</item> + <item name="android:maxLength">20</item> <item name="android:gravity">right|end</item> + </style> + + <style name="IntPreference" parent="LongPreference"> + <item name="android:maxLength">11</item> </style> <style name="HexIntPreference" parent="IntPreference"> @@ -132,6 +137,7 @@ <item name="android:digits">0123456789abcdef</item> <item name="radix">16</item> <item name="summaryFormat">%08x</item> + <item name="android:maxLength">8</item> </style> </resources> diff --git a/wikipedia/res/xml/developer_preferences.xml b/wikipedia/res/xml/developer_preferences.xml index 209bc5f..7b017bc 100644 --- a/wikipedia/res/xml/developer_preferences.xml +++ b/wikipedia/res/xml/developer_preferences.xml @@ -59,6 +59,11 @@ android:key="@string/preference_key_exp_page_load" android:title="@string/preference_key_exp_page_load" /> + <org.wikipedia.settings.LongPreference + style="@style/LongPreference" + android:key="@string/preference_key_last_daily_event_time" + android:title="@string/preference_key_last_daily_event_time" /> + <org.wikipedia.settings.CheckBoxPreferenceMultiLine android:key="@string/preference_key_show_developer_settings" android:title="@string/preference_key_show_developer_settings" /> diff --git a/wikipedia/src/main/java/org/wikipedia/analytics/DailyStatsFunnel.java b/wikipedia/src/main/java/org/wikipedia/analytics/DailyStatsFunnel.java new file mode 100644 index 0000000..ac41680 --- /dev/null +++ b/wikipedia/src/main/java/org/wikipedia/analytics/DailyStatsFunnel.java @@ -0,0 +1,53 @@ +package org.wikipedia.analytics; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.support.annotation.NonNull; + +import org.json.JSONObject; +import org.wikipedia.WikipediaApp; + +import java.util.concurrent.TimeUnit; + +// https://meta.wikimedia.org/wiki/Schema:MobileWikiAppDailyStats +public class DailyStatsFunnel extends Funnel { + private static final String SCHEMA_NAME = "MobileWikiAppDailyStats"; + private static final int SCHEMA_REVISION = 12637385; + + public DailyStatsFunnel(WikipediaApp app) { + super(app, SCHEMA_NAME, SCHEMA_REVISION); + } + + public void log(Context context) { + log(getInstallAgeDays(context)); + } + + public void log(long appInstallAgeDays) { + log("appInstallAgeDays", appInstallAgeDays); + } + + @Override protected void preprocessSessionToken(@NonNull JSONObject eventData) { } + + private long getInstallAgeDays(Context context) { + return TimeUnit.MILLISECONDS.toDays(getInstallAge(context)); + } + + private long getInstallAge(Context context) { + return getAbsoluteTime() - getInstallTime(context); + } + + /** @return The absolute time since initial app install in milliseconds. */ + private long getInstallTime(Context context) { + try { + return context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0) + .firstInstallTime; + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + } + + private long getAbsoluteTime() { + return System.currentTimeMillis(); + } +} \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java index 52a1552..6444ac0 100755 --- a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java +++ b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java @@ -9,6 +9,7 @@ import org.wikipedia.ViewAnimations; import org.wikipedia.WikipediaApp; import org.wikipedia.analytics.ConnectionIssueFunnel; +import org.wikipedia.analytics.DailyStatsFunnel; import org.wikipedia.analytics.LinkPreviewFunnel; import org.wikipedia.analytics.SavedPagesFunnel; import org.wikipedia.analytics.TabFunnel; @@ -31,6 +32,7 @@ import org.wikipedia.staticdata.MainPageNameData; import org.wikipedia.tooltip.ToolTipUtil; import org.wikipedia.util.NetworkUtils; +import org.wikipedia.util.log.L; import org.wikipedia.views.ObservableWebView; import org.wikipedia.views.SwipeRefreshLayoutWithScroll; import org.wikipedia.views.WikiDrawerLayout; @@ -70,6 +72,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -792,6 +795,10 @@ savedPagesFunnel.logUpdate(); savePage(); } + + if (isDailyEventDue()) { + onDailyEvent(); + } } public PageTitle adjustPageTitleFromMobileview(PageTitle title, JSONObject mobileView) @@ -1035,4 +1042,35 @@ getView().findViewById(R.id.fragment_page_tool_tip_select_text_target), R.layout.inflate_tool_tip_select_text, Color.BLACK, ToolTip.Position.RIGHT); } + + private void onDailyEvent() { + L.d("Previous event was " + timeSinceLastDailyEventDays() + " days ago."); + logDailyEventReport(); + recordLastDailyEventTime(); + } + + private void logDailyEventReport() { + new DailyStatsFunnel(app).log(getActivity()); + } + + private boolean isDailyEventDue() { + return timeSinceLastDailyEvent() > TimeUnit.DAYS.toMillis(1); + } + + private void recordLastDailyEventTime() { + Prefs.setLastDailyEventTime(getAbsoluteTime()); + } + + private long timeSinceLastDailyEventDays() { + return TimeUnit.MILLISECONDS.toDays(timeSinceLastDailyEvent()); + } + + private long timeSinceLastDailyEvent() { + return Math.min(Integer.MAX_VALUE, + Math.max(0, getAbsoluteTime() - Prefs.getLastDailyEventTime())); + } + + private long getAbsoluteTime() { + return System.currentTimeMillis(); + } } diff --git a/wikipedia/src/main/java/org/wikipedia/settings/IntPreference.java b/wikipedia/src/main/java/org/wikipedia/settings/IntPreference.java index 6017910..69a1834 100644 --- a/wikipedia/src/main/java/org/wikipedia/settings/IntPreference.java +++ b/wikipedia/src/main/java/org/wikipedia/settings/IntPreference.java @@ -1,21 +1,11 @@ package org.wikipedia.settings; +import android.annotation.TargetApi; import android.content.Context; -import android.content.res.TypedArray; -import android.text.TextUtils; +import android.os.Build; import android.util.AttributeSet; -import org.wikipedia.R; - -public class IntPreference extends EditTextAutoSummarizePreference { - private static final int[] DEFAULT_STYLEABLE = R.styleable.IntPreference; - private static final int DEFAULT_STYLE = R.style.IntPreference; - private static final int DEFAULT_RADIX = 10; - private static final String DEFAULT_SUMMARY_FORMAT = "%d"; - - private int radix = DEFAULT_RADIX; - private String summaryFormat = DEFAULT_SUMMARY_FORMAT; - +public class IntPreference extends LongPreference { public IntPreference(Context context) { this(context, null); } @@ -26,30 +16,11 @@ public IntPreference(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(attrs, defStyleAttr, DEFAULT_STYLE); } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) public IntPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - init(attrs, defStyleAttr, defStyleRes); - } - - public int getRadix() { - return radix; - } - - public void setRadix(int radix) { - this.radix = radix; - updateAutoSummary(); - } - - public String getSummaryFormat() { - return summaryFormat; - } - - public void setSummaryFormat(String format) { - summaryFormat = format; - updateAutoSummary(); } @Override @@ -58,45 +29,20 @@ } @Override - protected boolean persistString(String radixValue) { - boolean persistent = persistInt(radixStringToInt(radixValue)); - - updateAutoSummary(radixValue); - - return persistent; + protected boolean persistRadixString(String radixValue) { + return persistInt(radixStringToInt(radixValue)); } @Override - protected void updateAutoSummary(String radixValue) { - super.updateAutoSummary(sanitizeRadixString(radixValue)); - } - - private String sanitizeRadixString(String radixValue) { + protected String sanitizeRadixString(String radixValue) { return intToSummary(radixStringToInt(radixValue)); } private int radixStringToInt(String radixValue) { - return TextUtils.isEmpty(radixValue) ? 0 : Long.valueOf(radixValue, getRadix()).intValue(); + return Long.valueOf(radixStringToLong(radixValue)).intValue(); } private String intToSummary(int value) { return String.format(getSummaryFormat(), value); - } - - private void setAttributes(AttributeSet attrs, int defStyleAttr, int defStyleRes) { - TypedArray array = getContext().obtainStyledAttributes(attrs, DEFAULT_STYLEABLE, - defStyleAttr, defStyleRes); - radix = array.getInteger(R.styleable.IntPreference_radix, DEFAULT_RADIX); - summaryFormat = defaultIfEmpty(array.getString(R.styleable.IntPreference_summaryFormat), - DEFAULT_SUMMARY_FORMAT); - array.recycle(); - } - - private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) { - setAttributes(attrs, defStyleAttr, defStyleRes); - } - - private <T extends CharSequence> T defaultIfEmpty(T value, T defaultValue) { - return TextUtils.isEmpty(value) ? defaultValue : value; } } \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/settings/LongPreference.java b/wikipedia/src/main/java/org/wikipedia/settings/LongPreference.java new file mode 100644 index 0000000..cc6c2b4 --- /dev/null +++ b/wikipedia/src/main/java/org/wikipedia/settings/LongPreference.java @@ -0,0 +1,109 @@ +package org.wikipedia.settings; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.text.TextUtils; +import android.util.AttributeSet; + +import org.wikipedia.R; + +public class LongPreference extends EditTextAutoSummarizePreference { + private static final int[] DEFAULT_STYLEABLE = R.styleable.LongPreference; + private static final int DEFAULT_STYLE = R.style.LongPreference; + private static final int DEFAULT_RADIX = 10; + private static final String DEFAULT_SUMMARY_FORMAT = "%d"; + + private int radix = DEFAULT_RADIX; + private String summaryFormat = DEFAULT_SUMMARY_FORMAT; + + public LongPreference(Context context) { + this(context, null); + } + + public LongPreference(Context context, AttributeSet attrs) { + this(context, attrs, DEFAULT_STYLE_ATTR); + } + + public LongPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs, defStyleAttr, DEFAULT_STYLE); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public LongPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(attrs, defStyleAttr, defStyleRes); + } + + public int getRadix() { + return radix; + } + + public void setRadix(int radix) { + this.radix = radix; + updateAutoSummary(); + } + + public String getSummaryFormat() { + return summaryFormat; + } + + public void setSummaryFormat(String format) { + summaryFormat = format; + updateAutoSummary(); + } + + @Override + protected String getPersistedString(String defaultRadixValue) { + return longToSummary(getPersistedLong(radixStringToLong(defaultRadixValue))); + } + + @Override + protected boolean persistString(String radixValue) { + boolean persistent = persistRadixString(radixValue); + + updateAutoSummary(radixValue); + + return persistent; + } + + @Override + protected void updateAutoSummary(String radixValue) { + super.updateAutoSummary(sanitizeRadixString(radixValue)); + } + + protected boolean persistRadixString(String radixValue) { + return persistLong(radixStringToLong(radixValue)); + } + + protected String sanitizeRadixString(String radixValue) { + return longToSummary(radixStringToLong(radixValue)); + } + + protected long radixStringToLong(String radixValue) { + return TextUtils.isEmpty(radixValue) ? 0 : Long.valueOf(radixValue, getRadix()); + } + + protected String longToSummary(long value) { + return String.format(getSummaryFormat(), value); + } + + private void setAttributes(AttributeSet attrs, int defStyleAttr, int defStyleRes) { + TypedArray array = getContext().obtainStyledAttributes(attrs, DEFAULT_STYLEABLE, + defStyleAttr, defStyleRes); + radix = array.getInteger(R.styleable.LongPreference_radix, DEFAULT_RADIX); + summaryFormat = defaultIfEmpty(array.getString(R.styleable.LongPreference_summaryFormat), + DEFAULT_SUMMARY_FORMAT); + array.recycle(); + } + + private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) { + setAttributes(attrs, defStyleAttr, defStyleRes); + } + + private <T extends CharSequence> T defaultIfEmpty(T value, T defaultValue) { + return TextUtils.isEmpty(value) ? defaultValue : value; + } +} \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/settings/Prefs.java b/wikipedia/src/main/java/org/wikipedia/settings/Prefs.java index f58567e..5ebf967 100644 --- a/wikipedia/src/main/java/org/wikipedia/settings/Prefs.java +++ b/wikipedia/src/main/java/org/wikipedia/settings/Prefs.java @@ -11,10 +11,12 @@ import static org.wikipedia.settings.PrefsIoUtil.getBoolean; import static org.wikipedia.settings.PrefsIoUtil.getInt; import static org.wikipedia.settings.PrefsIoUtil.getKey; +import static org.wikipedia.settings.PrefsIoUtil.getLong; import static org.wikipedia.settings.PrefsIoUtil.getString; import static org.wikipedia.settings.PrefsIoUtil.remove; import static org.wikipedia.settings.PrefsIoUtil.setBoolean; import static org.wikipedia.settings.PrefsIoUtil.setInt; +import static org.wikipedia.settings.PrefsIoUtil.setLong; import static org.wikipedia.settings.PrefsIoUtil.setString; /** Shared preferences utility for convenient POJO access. */ @@ -82,6 +84,14 @@ remove(getCookiesForDomainKey(domain)); } + public static long getLastDailyEventTime() { + return getLong(R.string.preference_key_last_daily_event_time, 0); + } + + public static void setLastDailyEventTime(long time) { + setLong(R.string.preference_key_last_daily_event_time, time); + } + public static boolean isShowDeveloperSettingsEnabled() { return getBoolean(R.string.preference_key_show_developer_settings, WikipediaApp.getInstance().isDevRelease()); diff --git a/wikipedia/src/main/java/org/wikipedia/settings/PrefsIoUtil.java b/wikipedia/src/main/java/org/wikipedia/settings/PrefsIoUtil.java index 7fee09b..c3fdf72 100644 --- a/wikipedia/src/main/java/org/wikipedia/settings/PrefsIoUtil.java +++ b/wikipedia/src/main/java/org/wikipedia/settings/PrefsIoUtil.java @@ -22,6 +22,14 @@ setString(getKey(keyResourceId), value); } + public static long getLong(int keyResourceId, long defaultValue) { + return getLong(getKey(keyResourceId), defaultValue); + } + + public static void setLong(int keyResourceId, long value) { + setLong(getKey(keyResourceId), value); + } + public static int getInt(int keyResourceId, int defaultValue) { return getInt(getKey(keyResourceId), defaultValue); } @@ -47,6 +55,14 @@ edit().putString(key, value).apply(); } + public static long getLong(String key, long defaultValue) { + return getPreferences().getLong(key, defaultValue); + } + + public static void setLong(String key, long value) { + edit().putLong(key, value).apply(); + } + public static int getInt(String key, int defaultValue) { return getPreferences().getInt(key, defaultValue); } -- To view, visit https://gerrit.wikimedia.org/r/223976 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9dcce02fe19954381521d81cc8ec4378af51bf86 Gerrit-PatchSet: 1 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Niedzielski <sniedziel...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits