Commit ffa30255 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Content Indexing : Show NTP Card only when content available

We should show NTP entry point only when
1 - There are prefetch or content indexed articles available
2 - Show only once per session. If user dismissed in one tab, don't show it on another new tab when opened

Bug: 1031796
Change-Id: I229fa4ecfa1b58ffcfe281af5c732f168268ed36
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1956162
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723625}
parent bddea18c
......@@ -516,6 +516,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/DownloadUmaStatsEntry.java",
"java/src/org/chromium/chrome/browser/download/DownloadUpdate.java",
"java/src/org/chromium/chrome/browser/download/DownloadUtils.java",
"java/src/org/chromium/chrome/browser/download/ExploreOfflineStatusProvider.java",
"java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java",
"java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java",
"java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java",
......
......@@ -10,7 +10,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/hairline_border_card_background"
android:padding="@dimen/card_padding">
android:paddingTop="@dimen/card_padding"
android:paddingStart="@dimen/card_padding"
android:paddingEnd="@dimen/card_padding"
android:paddingBottom="10dp">
<org.chromium.ui.widget.ChromeImageView
android:id="@+id/icon"
......
......@@ -73,7 +73,6 @@ import org.chromium.components.offline_items_collection.OfflineItemState;
import org.chromium.components.offline_items_collection.PendingState;
import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.net.NetworkChangeNotifier;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.widget.Toast;
......@@ -216,14 +215,6 @@ public class DownloadUtils {
return true;
}
/**
* @return Whether Chrome is currently offline and Offline Home should be shown for downloads.
*/
public static boolean shouldShowOfflineHome() {
return ChromeFeatureList.isEnabled(ChromeFeatureList.OFFLINE_HOME)
&& NetworkChangeNotifier.isInitialized() && !NetworkChangeNotifier.isOnline();
}
/**
* @return Whether or not the Intent corresponds to a DownloadActivity that should show off the
* record downloads.
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download;
import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.OfflineContentProvider;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.UpdateDelta;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
* Keeps track of prefetch content addition and removal from chrome. This information is used to
* decide whether or not users should be see a message on NTP about offline content availability in
* chrome.
*/
public class ExploreOfflineStatusProvider implements OfflineContentProvider.Observer {
private static ExploreOfflineStatusProvider sInstance;
private Set<ContentId> mPrefetchItems = new HashSet<>();
/**
* @return An {@link ExploreOfflineStatusProvider} instance singleton. If one
* is not available this will create a new one.
*/
public static ExploreOfflineStatusProvider getInstance() {
if (sInstance == null) {
sInstance = new ExploreOfflineStatusProvider();
}
return sInstance;
}
private ExploreOfflineStatusProvider() {
OfflineContentProvider provider = OfflineContentAggregatorFactory.get();
provider.addObserver(this);
provider.getAllItems(this::onItemsAdded);
}
/**
* @return Whether or not there are any prefetch content available in chrome.
*/
public boolean isPrefetchContentAvailable() {
return SharedPreferencesManager.getInstance().readBoolean(
ChromePreferenceKeys.EXPLORE_OFFLINE_CONTENT_AVAILABILITY_STATUS, false);
}
@Override
public void onItemsAdded(ArrayList<OfflineItem> items) {
if (items.isEmpty()) return;
for (OfflineItem item : items) {
if (item.isSuggested) mPrefetchItems.add(item.id);
}
updateSharedPref();
}
@Override
public void onItemRemoved(ContentId id) {
if (mPrefetchItems.isEmpty()) return;
mPrefetchItems.remove(id);
updateSharedPref();
}
@Override
public void onItemUpdated(OfflineItem item, UpdateDelta updateDelta) {}
private void updateSharedPref() {
SharedPreferencesManager.getInstance().writeBoolean(
ChromePreferenceKeys.EXPLORE_OFFLINE_CONTENT_AVAILABILITY_STATUS,
!mPrefetchItems.isEmpty());
}
}
......@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.crash.LogcatExtractionRunnable;
import org.chromium.chrome.browser.crash.MinidumpUploadService;
import org.chromium.chrome.browser.download.DownloadController;
import org.chromium.chrome.browser.download.DownloadManagerService;
import org.chromium.chrome.browser.download.ExploreOfflineStatusProvider;
import org.chromium.chrome.browser.firstrun.ForcedSigninProcessor;
import org.chromium.chrome.browser.flags.FeatureUtilities;
import org.chromium.chrome.browser.history.HistoryDeletionBridge;
......@@ -444,6 +445,7 @@ public class ProcessInitializationHandler {
deferredStartupHandler.addDeferredTask(
() -> SharedClipboardShareActivity.updateComponentEnabledState());
deferredStartupHandler.addDeferredTask(() -> ExploreOfflineStatusProvider.getInstance());
}
private void initChannelsAsync() {
......
......@@ -889,7 +889,7 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
private Runnable openDownloadHomeCallback() {
return () -> {
DownloadUtils.showDownloadManager(mActivity, mActivity.getActivityTabProvider().get(),
DownloadOpenSource.NEW_TAB_PAGE);
DownloadOpenSource.NEW_TAB_PAGE, true /*showPrefetchedContent*/);
};
}
......
......@@ -10,7 +10,7 @@ import android.widget.Button;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.download.ExploreOfflineStatusProvider;
import org.chromium.net.NetworkChangeNotifier;
/**
......@@ -18,10 +18,10 @@ import org.chromium.net.NetworkChangeNotifier;
* responsible for inflating the card layout and displaying the card based on network connectivity.
*/
public class ExploreOfflineCard {
private static boolean sCardDismissed;
private final View mRootView;
private final Runnable mOpenDownloadHomeCallback;
private NetworkChangeNotifier.ConnectionTypeObserver mConnectionTypeObserver;
private boolean mCardDismissed;
/**
* Constructor.
......@@ -32,7 +32,7 @@ public class ExploreOfflineCard {
mRootView = rootView;
mOpenDownloadHomeCallback = openDownloadHomeCallback;
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.OFFLINE_HOME)) return;
if (!isFeatureEnabled()) return;
setCardViewVisibility();
mConnectionTypeObserver = connectionType -> {
setCardViewVisibility();
......@@ -47,7 +47,7 @@ public class ExploreOfflineCard {
}
private void setCardViewVisibility() {
boolean isVisible = !mCardDismissed && DownloadUtils.shouldShowOfflineHome();
boolean isVisible = !sCardDismissed && shouldShowExploreOfflineMessage();
View cardView = mRootView.findViewById(R.id.explore_offline_card);
if (cardView == null) {
......@@ -64,14 +64,24 @@ public class ExploreOfflineCard {
Button cancelButton = cardView.findViewById(R.id.button_secondary);
confirmButton.setOnClickListener(v -> {
mCardDismissed = true;
sCardDismissed = true;
setCardViewVisibility();
mOpenDownloadHomeCallback.run();
});
cancelButton.setOnClickListener(v -> {
mCardDismissed = true;
sCardDismissed = true;
setCardViewVisibility();
});
return cardView;
}
private static boolean shouldShowExploreOfflineMessage() {
return isFeatureEnabled() && NetworkChangeNotifier.isInitialized()
&& !NetworkChangeNotifier.isOnline()
&& ExploreOfflineStatusProvider.getInstance().isPrefetchContentAvailable();
}
private static boolean isFeatureEnabled() {
return ChromeFeatureList.isEnabled(ChromeFeatureList.OFFLINE_HOME);
}
}
......@@ -140,6 +140,12 @@ public final class ChromePreferenceKeys {
public static final String CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_4 =
"contextual_search_impressions_week_4";
/**
* Indicates whether or not there are prefetched content in chrome that can be viewed offline.
*/
public static final String EXPLORE_OFFLINE_CONTENT_AVAILABILITY_STATUS =
"Chrome.NTPExploreOfflineCard.HasExploreOfflineContent";
/**
* Whether the promotion for data reduction has been skipped on first invocation.
* Default value is false.
......@@ -424,6 +430,7 @@ public final class ChromePreferenceKeys {
CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_2,
CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_3,
CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_4,
EXPLORE_OFFLINE_CONTENT_AVAILABILITY_STATUS,
PROMOS_SKIPPED_ON_FIRST_START,
SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION,
SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment