Bug 1247689 - Experiment: show prompt on third opening of reader view r?sebastian
MozReview-Commit-ID: CMxdWuFIe5e
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -54,16 +54,17 @@ import org.mozilla.gecko.menu.GeckoMenuI
import org.mozilla.gecko.mozglue.ContextUtils;
import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
import org.mozilla.gecko.overlays.ui.ShareDialog;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.promotion.AddToHomeScreenPromotion;
import org.mozilla.gecko.promotion.BookmarkStateChangeDelegate;
+import org.mozilla.gecko.promotion.ReaderViewBookmarkPromotion;
import org.mozilla.gecko.prompts.Prompt;
import org.mozilla.gecko.prompts.PromptListItem;
import org.mozilla.gecko.reader.SavedReaderViewHelper;
import org.mozilla.gecko.reader.ReaderModeUtils;
import org.mozilla.gecko.reader.ReadingListHelper;
import org.mozilla.gecko.restrictions.Restrictable;
import org.mozilla.gecko.restrictions.RestrictedProfileConfiguration;
import org.mozilla.gecko.restrictions.Restrictions;
@@ -210,16 +211,19 @@ public class BrowserApp extends GeckoApp
private static final String BROWSER_SEARCH_TAG = "browser_search";
// Request ID for startActivityForResult.
private static final int ACTIVITY_REQUEST_PREFERENCES = 1001;
private static final int ACTIVITY_REQUEST_TAB_QUEUE = 2001;
public static final int ACTIVITY_REQUEST_FIRST_READERVIEW_BOOKMARK = 3001;
public static final int ACTIVITY_RESULT_FIRST_READERVIEW_BOOKMARKS_GOTO_BOOKMARKS = 3002;
public static final int ACTIVITY_RESULT_FIRST_READERVIEW_BOOKMARKS_IGNORE = 3003;
+ public static final int ACTIVITY_REQUEST_TRIPLE_READERVIEW = 4001;
+ public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_ADD_BOOKMARK = 4002;
+ public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_IGNORE = 4003;
public static final String ACTION_VIEW_MULTIPLE = AppConstants.ANDROID_PACKAGE_NAME + ".action.VIEW_MULTIPLE";
@RobocopTarget
public static final String EXTRA_SKIP_STARTPANE = "skipstartpane";
private static final String EOL_NOTIFIED = "eol_notified";
private BrowserSearch mBrowserSearch;
@@ -301,17 +305,18 @@ public class BrowserApp extends GeckoApp
// race by determining if the web content should be hidden at the animation's end.
private boolean mHideWebContentOnAnimationEnd;
private final DynamicToolbar mDynamicToolbar = new DynamicToolbar();
private final List<BrowserAppDelegate> delegates = Collections.unmodifiableList(Arrays.asList(
(BrowserAppDelegate) new AddToHomeScreenPromotion(),
(BrowserAppDelegate) new ScreenshotDelegate(),
- (BrowserAppDelegate) new BookmarkStateChangeDelegate()
+ (BrowserAppDelegate) new BookmarkStateChangeDelegate(),
+ (BrowserAppDelegate) new ReaderViewBookmarkPromotion()
));
@NonNull
private SearchEngineManager searchEngineManager; // Contains reference to Context - DO NOT LEAK!
@Override
public View onCreateView(final String name, final Context context, final AttributeSet attrs) {
final View view;
@@ -347,16 +352,17 @@ public class BrowserApp extends GeckoApp
if (mZoomedView != null) {
mZoomedView.stopZoomDisplay(false);
}
if (Tabs.getInstance().isSelectedTab(tab)) {
updateHomePagerForTab(tab);
}
mDynamicToolbar.persistTemporaryVisibility();
+
break;
case START:
if (Tabs.getInstance().isSelectedTab(tab)) {
invalidateOptionsMenu();
if (mDynamicToolbar.isEnabled()) {
mDynamicToolbar.setVisible(true, VisibilityTransition.ANIMATE);
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/promotion/ReaderViewBookmarkPromotion.java
@@ -0,0 +1,119 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.promotion;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.keepsafe.switchboard.SwitchBoard;
+
+import org.mozilla.gecko.BrowserApp;
+import org.mozilla.gecko.BrowserAppDelegate;
+import org.mozilla.gecko.GeckoSharedPrefs;
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.Tab;
+import org.mozilla.gecko.Tabs;
+import org.mozilla.gecko.reader.ReaderModeUtils;
+import org.mozilla.gecko.util.Experiments;
+
+import java.lang.ref.WeakReference;
+
+public class ReaderViewBookmarkPromotion extends BrowserAppDelegate implements Tabs.OnTabsChangedListener {
+ private WeakReference<BrowserApp> mBrowserApp;
+
+ private int mTimesEnteredReaderMode = 0;
+
+ @Override
+ public void onCreate(BrowserApp browserApp, Bundle savedInstanceState) {
+ mBrowserApp = new WeakReference<>(browserApp);
+ }
+
+ @Override
+ public void onResume(BrowserApp browserApp) {
+ Tabs.registerOnTabsChangedListener(this);
+ }
+
+ @Override
+ public void onPause(BrowserApp browserApp) {
+ Tabs.unregisterOnTabsChangedListener(this);
+ }
+
+ @Override
+ public void onTabChanged(Tab tab, Tabs.TabEvents msg, String data) {
+ switch (msg) {
+ case LOCATION_CHANGE:
+ // old url: data
+ // new url: tab.getURL()
+ final boolean enteringReaderMode = ReaderModeUtils.isEnteringReaderMode(tab.getURL(), data);
+
+ if (mTimesEnteredReaderMode < 4 && enteringReaderMode) {
+ mTimesEnteredReaderMode++;
+ }
+
+ if (mTimesEnteredReaderMode == 3) {
+ promoteBookmarking();
+ }
+
+ break;
+ }
+ }
+
+ @Override
+ public void onActivityResult(BrowserApp browserApp, int requestCode, int resultCode,
+ Intent data) {
+ switch (requestCode) {
+ case BrowserApp.ACTIVITY_REQUEST_TRIPLE_READERVIEW:
+ if (resultCode == BrowserApp.ACTIVITY_RESULT_TRIPLE_READERVIEW_ADD_BOOKMARK) {
+ final Tab tab = Tabs.getInstance().getSelectedTab();
+ if (tab != null) {
+ tab.addBookmark();
+ }
+ } else if (resultCode == BrowserApp.ACTIVITY_RESULT_TRIPLE_READERVIEW_IGNORE) {
+ // Nothing to do: we won't show this promotion again either way.
+ }
+ break;
+ }
+ }
+
+ private void promoteBookmarking() {
+ final BrowserApp browserApp = mBrowserApp.get();
+ if (browserApp == null) {
+ return;
+ }
+
+ final SharedPreferences prefs = GeckoSharedPrefs.forProfile(browserApp);
+
+ // We reuse the same preference as for the first offline reader view bookmark
+ // as we only want to show one of the two UIs (they both explain the same
+ // functionality).
+ if (prefs.getBoolean(SimpleHelperUI.PREF_FIRST_RVBP_SHOWN, false)) {
+ return;
+ }
+
+ boolean experimentEnabled = SwitchBoard.isInExperiment(browserApp, Experiments.TRIPLE_READERVIEW_BOOKMARK_PROMPT);
+
+ if (!experimentEnabled) {
+ return;
+ }
+
+ SimpleHelperUI.show(browserApp,
+ SimpleHelperUI.TRIPLE_READERVIEW_OPEN_TELEMETRYEXTRA,
+ BrowserApp.ACTIVITY_REQUEST_TRIPLE_READERVIEW,
+ R.string.helper_triple_readerview_open_title,
+ R.string.helper_triple_readerview_open_message,
+ R.drawable.helper_first_readerview_bookmark, // We share the icon with the usual helper UI
+ R.string.helper_triple_readerview_open_button,
+ BrowserApp.ACTIVITY_RESULT_TRIPLE_READERVIEW_ADD_BOOKMARK,
+ BrowserApp.ACTIVITY_RESULT_TRIPLE_READERVIEW_IGNORE);
+
+ GeckoSharedPrefs.forProfile(browserApp)
+ .edit()
+ .putBoolean(SimpleHelperUI.PREF_FIRST_RVBP_SHOWN, true)
+ .apply();
+ }
+
+}
--- a/mobile/android/base/java/org/mozilla/gecko/promotion/SimpleHelperUI.java
+++ b/mobile/android/base/java/org/mozilla/gecko/promotion/SimpleHelperUI.java
@@ -28,16 +28,17 @@ import org.mozilla.gecko.TelemetryContra
/**
* Generic HelperUI (prompt) that can be populated with an image, title, message and action button.
* See show() for usage. This is run as an Activity, results must be handled in the parent Activities
* onActivityResult().
*/
public class SimpleHelperUI extends Locales.LocaleAwareActivity {
public static final String PREF_FIRST_RVBP_SHOWN = "first_reader_view_bookmark_prompt_shown";
public static final String FIRST_RVBP_SHOWN_TELEMETRYEXTRA = "first_readerview_bookmark_prompt";
+ public static final String TRIPLE_READERVIEW_OPEN_TELEMETRYEXTRA = "third_readerview_open_prompt";
private View containerView;
private boolean isAnimating;
private String mTelemetryExtra;
private static final String EXTRA_TELEMETRYEXTRA = "telemetryextra";
--- a/mobile/android/base/java/org/mozilla/gecko/util/Experiments.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/Experiments.java
@@ -42,16 +42,19 @@ public class Experiments {
// Synchronizing the catalog of downloadable content from Kinto
public static final String DOWNLOAD_CONTENT_CATALOG_SYNC = "download-content-catalog-sync";
// Promotion for "Add to homescreen"
public static final String PROMOTE_ADD_TO_HOMESCREEN = "promote-add-to-homescreen";
public static final String PREF_ONBOARDING_VERSION = "onboarding_version";
+ // Promotion to bookmark reader-view items after entering reader view three times (Bug 1247689)
+ public static final String TRIPLE_READERVIEW_BOOKMARK_PROMPT = "triple-readerview-bookmark-prompt";
+
private static volatile Boolean disabled = null;
/**
* Determines whether Switchboard is disabled by the MOZ_DISABLE_SWITCHBOARD
* environment variable. We need to read this value from the intent string
* extra because environment variables from our test harness aren't set
* until Gecko is loaded, and we need to know this before then.
*
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -773,8 +773,13 @@ just addresses the organization to follo
<!ENTITY whatsnew_notification_title "&brandShortName; is up to date">
<!ENTITY whatsnew_notification_summary "Find out what\'s new in this version">
<!ENTITY promotion_add_to_homescreen "Add to home screen">
<!ENTITY helper_first_offline_bookmark_title "Read offline">
<!ENTITY helper_first_offline_bookmark_message "Find your Reader View items in Bookmarks, even offline.">
<!ENTITY helper_first_offline_bookmark_button "Go to Bookmarks">
+
+<!ENTITY helper_triple_readerview_open_title "Available offline">
+<!ENTITY helper_triple_readerview_open_message "Bookmark Reader View items to read them offline.">
+<!ENTITY helper_triple_readerview_open_button "Add to Bookmarks">
+
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -505,16 +505,17 @@ gbjar.sources += ['java/org/mozilla/geck
'preferences/SetHomepagePreference.java',
'preferences/SyncPreference.java',
'PrefsHelper.java',
'PrintHelper.java',
'PrivateTab.java',
'promotion/AddToHomeScreenPromotion.java',
'promotion/BookmarkStateChangeDelegate.java',
'promotion/HomeScreenPrompt.java',
+ 'promotion/ReaderViewBookmarkPromotion.java',
'promotion/SimpleHelperUI.java',
'prompts/ColorPickerInput.java',
'prompts/IconGridInput.java',
'prompts/IntentChooserPrompt.java',
'prompts/IntentHandler.java',
'prompts/Prompt.java',
'prompts/PromptInput.java',
'prompts/PromptListAdapter.java',
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -606,9 +606,13 @@
<string name="whatsnew_notification_url">https://support.mozilla.org/1/mobile/&formatS1;/&formatS2;/&formatS3;/new-android</string>
<string name="promotion_add_to_homescreen">&promotion_add_to_homescreen;</string>
<string name="helper_first_offline_bookmark_title">&helper_first_offline_bookmark_title;</string>
<string name="helper_first_offline_bookmark_message">&helper_first_offline_bookmark_message;</string>
<string name="helper_first_offline_bookmark_button">&helper_first_offline_bookmark_button;</string>
+ <string name="helper_triple_readerview_open_title">&helper_triple_readerview_open_title;</string>
+ <string name="helper_triple_readerview_open_message">&helper_triple_readerview_open_message;</string>
+ <string name="helper_triple_readerview_open_button">&helper_triple_readerview_open_button;</string>
+
</resources>