Commit bdb43101 authored by Pavel Yatsuk's avatar Pavel Yatsuk Committed by Commit Bot

[Touchless] Add "Remove" context menu item for last tab button

Selecting remove will remove last navigation from history and switch
last button to Google logo.
The logic is implemented by remembering timestamp of last removed
history entry in SharedPreferences. Only History items with later
timestamp are displayed on last tab button.

BUG=959317
R=wylieb@chromium.org

Change-Id: I8e67afca631bbc233d90f34791eff146bc1f37dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1644155Reviewed-by: default avatarBrandon Wylie <wylieb@chromium.org>
Commit-Queue: Pavel Yatsuk <pavely@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666044}
parent 6ce2a060
...@@ -41,6 +41,8 @@ import java.util.List; ...@@ -41,6 +41,8 @@ import java.util.List;
class OpenLastTabMediator extends EmptyTabObserver class OpenLastTabMediator extends EmptyTabObserver
implements HistoryProvider.BrowsingHistoryObserver, FocusableComponent { implements HistoryProvider.BrowsingHistoryObserver, FocusableComponent {
private static final String FIRST_LAUNCHED_KEY = "TOUCHLESS_WAS_FIRST_LAUNCHED"; private static final String FIRST_LAUNCHED_KEY = "TOUCHLESS_WAS_FIRST_LAUNCHED";
private static final String LAST_REMOVED_VISIT_TIMESTAMP_KEY =
"TOUCHLESS_LAST_REMOVED_VISIT_TIMESTAMP";
private final Context mContext; private final Context mContext;
private final Profile mProfile; private final Profile mProfile;
...@@ -52,6 +54,10 @@ class OpenLastTabMediator extends EmptyTabObserver ...@@ -52,6 +54,10 @@ class OpenLastTabMediator extends EmptyTabObserver
private final RoundedIconGenerator mIconGenerator; private final RoundedIconGenerator mIconGenerator;
private final LargeIconBridge mIconBridge; private final LargeIconBridge mIconBridge;
private HistoryItem mHistoryItem;
private boolean mPreferencesRead;
private long mLastRemovedVisitTimestamp = Long.MIN_VALUE;
OpenLastTabMediator(Context context, Profile profile, NativePageHost nativePageHost, OpenLastTabMediator(Context context, Profile profile, NativePageHost nativePageHost,
PropertyModel model, OpenLastTabView view) { PropertyModel model, OpenLastTabView view) {
mModel = model; mModel = model;
...@@ -67,20 +73,31 @@ class OpenLastTabMediator extends EmptyTabObserver ...@@ -67,20 +73,31 @@ class OpenLastTabMediator extends EmptyTabObserver
ViewUtils.createDefaultRoundedIconGenerator(mContext.getResources(), false); ViewUtils.createDefaultRoundedIconGenerator(mContext.getResources(), false);
mIconBridge = new LargeIconBridge(mProfile); mIconBridge = new LargeIconBridge(mProfile);
readPreferences();
// TODO(wylieb):Investigate adding an item limit to the API.
// Query the history for everything (no API exists to only query for the most recent).
refreshHistoryData();
}
private SharedPreferences getSharedPreferences() {
return mNativePageHost.getActiveTab().getActivity().getPreferences(Context.MODE_PRIVATE);
}
private void readPreferences() {
PostTask.postTask(TaskTraits.USER_VISIBLE, () -> { PostTask.postTask(TaskTraits.USER_VISIBLE, () -> {
// Check if this is a first launch of Chrome. // Check if this is a first launch of Chrome.
SharedPreferences prefs = mNativePageHost.getActiveTab().getActivity().getPreferences( SharedPreferences prefs = getSharedPreferences();
Context.MODE_PRIVATE);
boolean firstLaunched = prefs.getBoolean(FIRST_LAUNCHED_KEY, true); boolean firstLaunched = prefs.getBoolean(FIRST_LAUNCHED_KEY, true);
prefs.edit().putBoolean(FIRST_LAUNCHED_KEY, false).apply(); prefs.edit().putBoolean(FIRST_LAUNCHED_KEY, false).apply();
mLastRemovedVisitTimestamp =
prefs.getLong(LAST_REMOVED_VISIT_TIMESTAMP_KEY, Long.MIN_VALUE);
PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> { PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> {
mPreferencesRead = true;
mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_FIRST_LAUNCH, firstLaunched); mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_FIRST_LAUNCH, firstLaunched);
updateModel();
}); });
}); });
// TODO(wylieb):Investigate adding an item limit to the API.
// Query the history for everything (no API exists to only query for the most recent).
refreshHistoryData();
} }
void destroy() { void destroy() {
...@@ -115,41 +132,55 @@ class OpenLastTabMediator extends EmptyTabObserver ...@@ -115,41 +132,55 @@ class OpenLastTabMediator extends EmptyTabObserver
@Override @Override
public void onQueryHistoryComplete(List<HistoryItem> items, boolean hasMorePotentialMatches) { public void onQueryHistoryComplete(List<HistoryItem> items, boolean hasMorePotentialMatches) {
if (items.size() == 0) { if (items.size() == 0) {
mHistoryItem = null;
} else {
// First item is most recent.
mHistoryItem = items.get(0);
}
if (mPreferencesRead) {
updateModel();
}
}
// updateModel is only called after preferences are read. It populates model with data from
// mHistoryItem.
private void updateModel() {
if (mHistoryItem == null || mHistoryItem.getTimestamp() <= mLastRemovedVisitTimestamp) {
// Consider the case where the history has nothing in it to be a failure. // Consider the case where the history has nothing in it to be a failure.
mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_LOAD_SUCCESS, false); mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_LOAD_SUCCESS, false);
return; return;
} }
// First item is most recent. String title = UrlUtilities.getDomainAndRegistry(mHistoryItem.getUrl(), false);
HistoryItem item = items.get(0);
String title = UrlUtilities.getDomainAndRegistry(item.getUrl(), false);
// Default the timestamp to happening just now. If it happened over a minute ago, calculate // Default the timestamp to happening just now. If it happened over a minute ago, calculate
// and set the relative timestamp string. // and set the relative timestamp string.
String timestamp = mContext.getResources().getString(R.string.open_last_tab_just_now); String timestamp = mContext.getResources().getString(R.string.open_last_tab_just_now);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (now - item.getTimestamp() > MINUTE_IN_MILLIS) { if (now - mHistoryItem.getTimestamp() > MINUTE_IN_MILLIS) {
timestamp = getRelativeTimeSpanString(item.getTimestamp(), now, MINUTE_IN_MILLIS) timestamp =
.toString(); getRelativeTimeSpanString(mHistoryItem.getTimestamp(), now, MINUTE_IN_MILLIS)
.toString();
} }
mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_TITLE, title); mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_TITLE, title);
mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_TIMESTAMP, timestamp); mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_TIMESTAMP, timestamp);
boolean willReturnIcon = mIconBridge.getLargeIconForUrl(item.getUrl(), boolean willReturnIcon = mIconBridge.getLargeIconForUrl(mHistoryItem.getUrl(),
mContext.getResources().getDimensionPixelSize(R.dimen.open_last_tab_icon_size), mContext.getResources().getDimensionPixelSize(R.dimen.open_last_tab_icon_size),
(icon, fallbackColor, isFallbackColorDefault, iconType) -> { (icon, fallbackColor, isFallbackColorDefault, iconType) -> {
setAndShowButton(item.getUrl(), icon, fallbackColor, title); setAndShowButton(mHistoryItem.getUrl(), icon, fallbackColor, title);
}); });
// False if icon bridge won't call us back. // False if icon bridge won't call us back.
if (!willReturnIcon) { if (!willReturnIcon) {
setAndShowButton(item.getUrl(), null, R.color.default_icon_color, title); setAndShowButton(mHistoryItem.getUrl(), null, R.color.default_icon_color, title);
} }
mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_LOAD_SUCCESS, true); mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_LOAD_SUCCESS, true);
} }
@Override @Override
public void onHistoryDeleted() {} public void onHistoryDeleted() {
refreshHistoryData();
}
@Override @Override
public void hasOtherFormsOfBrowsingData(boolean hasOtherForms) {} public void hasOtherFormsOfBrowsingData(boolean hasOtherForms) {}
...@@ -172,7 +203,22 @@ class OpenLastTabMediator extends EmptyTabObserver ...@@ -172,7 +203,22 @@ class OpenLastTabMediator extends EmptyTabObserver
@Override @Override
public boolean isItemSupported( public boolean isItemSupported(
@ContextMenuManager.ContextMenuItemId int menuItemId) { @ContextMenuManager.ContextMenuItemId int menuItemId) {
return menuItemId == ContextMenuManager.ContextMenuItemId.ADD_TO_MY_APPS; return menuItemId == ContextMenuManager.ContextMenuItemId.ADD_TO_MY_APPS
|| menuItemId == ContextMenuManager.ContextMenuItemId.REMOVE;
}
@Override
public void removeItem() {
mLastRemovedVisitTimestamp = mHistoryItem.getTimestamp();
PostTask.postTask(TaskTraits.USER_VISIBLE, () -> {
SharedPreferences prefs = getSharedPreferences();
prefs.edit()
.putLong(LAST_REMOVED_VISIT_TIMESTAMP_KEY,
mLastRemovedVisitTimestamp)
.apply();
});
mHistoryBridge.markItemForRemoval(mHistoryItem);
mHistoryBridge.removeItems();
} }
@Override @Override
......
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