| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.chrome.browser.ntp; | |
| 6 | |
| 7 import android.annotation.TargetApi; | |
| 8 import android.app.Activity; | |
| 9 import android.app.ActivityManager; | |
| 10 import android.app.ActivityManager.RecentTaskInfo; | |
| 11 import android.app.Dialog; | |
| 12 import android.content.Intent; | |
| 13 import android.os.Build; | |
| 14 import android.text.TextUtils; | |
| 15 | |
| 16 import org.chromium.base.ThreadUtils; | |
| 17 import org.chromium.chrome.browser.ChromeApplication; | |
| 18 import org.chromium.chrome.browser.UrlConstants; | |
| 19 import org.chromium.chrome.browser.document.DocumentUtils; | |
| 20 import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; | |
| 21 import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; | |
| 22 import org.chromium.chrome.browser.ntp.RecentlyClosedBridge.RecentlyClosedTab; | |
| 23 import org.chromium.chrome.browser.tab.Tab; | |
| 24 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; | |
| 25 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | |
| 26 import org.chromium.chrome.browser.tabmodel.TabModelObserver; | |
| 27 import org.chromium.chrome.browser.tabmodel.TabModelUtils; | |
| 28 import org.chromium.chrome.browser.tabmodel.document.ActivityDelegate; | |
| 29 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModel; | |
| 30 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelImpl; | |
| 31 import org.chromium.ui.WindowOpenDisposition; | |
| 32 | |
| 33 import java.util.ArrayList; | |
| 34 import java.util.List; | |
| 35 | |
| 36 /** | |
| 37 * ChromeHome specific version of RecentTabsManager that allows opening new Docu
mentActivities | |
| 38 * instead of tabs. | |
| 39 */ | |
| 40 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
| 41 public class DocumentRecentTabsManager extends RecentTabsManager { | |
| 42 /** | |
| 43 * The number of ms to delay opening a new tab, so that we have time to hide
dialog before | |
| 44 * the screenshot of the current page is taken. | |
| 45 */ | |
| 46 private static final int NEW_TAB_DELAY_MS = 150; | |
| 47 private final Activity mActivity; | |
| 48 private final List<CurrentlyOpenTab> mCurrentlyOpenTabs; | |
| 49 private final DocumentTabModel mTabModel; | |
| 50 private final DocumentTabModel.InitializationObserver mUpdateOpenTabsObserve
r; | |
| 51 private TabModelObserver mTabModelObserver; | |
| 52 private Dialog mDialog; | |
| 53 | |
| 54 private boolean mShowingAllInCurrentTabs; | |
| 55 | |
| 56 /** | |
| 57 * @param activity Activity that should be used to launch intents. | |
| 58 */ | |
| 59 public DocumentRecentTabsManager(Tab tab, Activity activity) { | |
| 60 super(tab, tab.getProfile().getOriginalProfile(), activity); | |
| 61 mActivity = activity; | |
| 62 mCurrentlyOpenTabs = new ArrayList<CurrentlyOpenTab>(); | |
| 63 mTabModel = | |
| 64 ChromeApplication.getDocumentTabModelSelector().getModel(tab.isI
ncognito()); | |
| 65 mUpdateOpenTabsObserver = new DocumentTabModel.InitializationObserver(mT
abModel) { | |
| 66 @Override | |
| 67 public boolean isSatisfied(int currentState) { | |
| 68 return currentState >= DocumentTabModelImpl.STATE_FULLY_LOAD
ED; | |
| 69 } | |
| 70 | |
| 71 @Override | |
| 72 public boolean isCanceled() { | |
| 73 return mActivity.isDestroyed() || mActivity.isFinishing(); | |
| 74 } | |
| 75 | |
| 76 @Override | |
| 77 protected void runImmediately() { | |
| 78 updateCurrentlyOpenTabsWhenDatabaseReady(); | |
| 79 } | |
| 80 }; | |
| 81 mTabModelObserver = new EmptyTabModelObserver() { | |
| 82 @Override | |
| 83 public void didAddTab(Tab tab, TabLaunchType type) { | |
| 84 updateCurrentlyOpenTabsWhenDatabaseReady(); | |
| 85 } | |
| 86 | |
| 87 @Override | |
| 88 public void didCloseTab(int tabId, boolean incognito) { | |
| 89 updateCurrentlyOpenTabsWhenDatabaseReady(); | |
| 90 } | |
| 91 }; | |
| 92 mTabModel.addObserver(mTabModelObserver); | |
| 93 updateCurrentlyOpenTabs(); | |
| 94 } | |
| 95 | |
| 96 /** | |
| 97 * @param dialog Dialog that displays the RecentTabsPage and will be dismiss
ed when | |
| 98 * a link is opened. | |
| 99 */ | |
| 100 public void setDialog(Dialog dialog) { | |
| 101 mDialog = dialog; | |
| 102 } | |
| 103 | |
| 104 @Override | |
| 105 public void destroy() { | |
| 106 super.destroy(); | |
| 107 mTabModel.removeObserver(mTabModelObserver); | |
| 108 } | |
| 109 | |
| 110 @Override | |
| 111 public void openForeignSessionTab(final ForeignSession session, final Foreig
nSessionTab tab, | |
| 112 int windowDisposition) { | |
| 113 // Hide the dialog for screenshot. We don't want to dismiss yet because
that will destroy | |
| 114 // the NativePage objects we need in the delayed runnable. | |
| 115 if (mDialog != null) mDialog.hide(); | |
| 116 ThreadUtils.postOnUiThreadDelayed(new Runnable() { | |
| 117 @Override | |
| 118 public void run() { | |
| 119 if (isDestroyed()) return; | |
| 120 DocumentRecentTabsManager.super.openForeignSessionTab( | |
| 121 session, tab, WindowOpenDisposition.NEW_FOREGROUND_TAB); | |
| 122 if (mDialog != null) mDialog.dismiss(); | |
| 123 } | |
| 124 }, NEW_TAB_DELAY_MS); | |
| 125 } | |
| 126 | |
| 127 @Override | |
| 128 public void openRecentlyClosedTab(final RecentlyClosedTab tab, int windowDis
position) { | |
| 129 // Hide the dialog for screenshot. We don't want to dismiss yet because
that will destroy | |
| 130 // the NativePage objects we need in the delayed runnable. | |
| 131 if (mDialog != null) mDialog.hide(); | |
| 132 ThreadUtils.postOnUiThreadDelayed(new Runnable() { | |
| 133 @Override | |
| 134 public void run() { | |
| 135 if (isDestroyed()) return; | |
| 136 DocumentRecentTabsManager.super.openRecentlyClosedTab( | |
| 137 tab, WindowOpenDisposition.NEW_FOREGROUND_TAB); | |
| 138 if (mDialog != null) mDialog.dismiss(); | |
| 139 } | |
| 140 }, NEW_TAB_DELAY_MS); | |
| 141 } | |
| 142 | |
| 143 @Override | |
| 144 public void openHistoryPage() { | |
| 145 super.openHistoryPage(); | |
| 146 if (mDialog != null) mDialog.dismiss(); | |
| 147 } | |
| 148 | |
| 149 @Override | |
| 150 public List<CurrentlyOpenTab> getCurrentlyOpenTabs() { | |
| 151 return mCurrentlyOpenTabs; | |
| 152 } | |
| 153 | |
| 154 @Override | |
| 155 public void setCurrentlyOpenTabsShowAll(boolean showingAll) { | |
| 156 mShowingAllInCurrentTabs = showingAll; | |
| 157 postUpdate(); | |
| 158 } | |
| 159 | |
| 160 @Override | |
| 161 public boolean isCurrentlyOpenTabsShowingAll() { | |
| 162 return mShowingAllInCurrentTabs; | |
| 163 } | |
| 164 | |
| 165 @Override | |
| 166 public void closeTab(CurrentlyOpenTab tab) { | |
| 167 Tab currentTab = | |
| 168 ChromeApplication.getDocumentTabModelSelector().getCurrentTab(); | |
| 169 Tab tabOject = TabModelUtils.getTabById(mTabModel, tab.getTabId()); | |
| 170 mTabModel.closeTab(tabOject); | |
| 171 if (currentTab.getId() == tabOject.getId()) { | |
| 172 Intent intent = new Intent(); | |
| 173 intent.setAction(Intent.ACTION_MAIN); | |
| 174 intent.setPackage(mActivity.getPackageName()); | |
| 175 mActivity.startActivity(intent); | |
| 176 } | |
| 177 postUpdate(); | |
| 178 } | |
| 179 | |
| 180 @Override | |
| 181 protected void updateCurrentlyOpenTabs() { | |
| 182 mUpdateOpenTabsObserver.runWhenReady(); | |
| 183 } | |
| 184 | |
| 185 private void updateCurrentlyOpenTabsWhenDatabaseReady() { | |
| 186 final int currentTabId = ActivityDelegate.getTabIdFromIntent(mActivity.g
etIntent()); | |
| 187 | |
| 188 ActivityManager am = (ActivityManager) mActivity.getSystemService( | |
| 189 Activity.ACTIVITY_SERVICE); | |
| 190 List<ActivityManager.AppTask> taskList = am.getAppTasks(); | |
| 191 mCurrentlyOpenTabs.clear(); | |
| 192 for (int i = 0; i < taskList.size(); i++) { | |
| 193 RecentTaskInfo taskInfo = DocumentUtils.getTaskInfoFromTask(taskList
.get(i)); | |
| 194 if (taskInfo == null) continue; | |
| 195 | |
| 196 final Intent baseIntent = taskInfo.baseIntent; | |
| 197 final int tabId = ActivityDelegate.getTabIdFromIntent(baseIntent); | |
| 198 String url = mTabModel.getCurrentUrlForDocument(tabId); | |
| 199 if (TextUtils.isEmpty(url) || url.startsWith(UrlConstants.CHROME_NAT
IVE_SCHEME)) { | |
| 200 continue; | |
| 201 } | |
| 202 | |
| 203 CharSequence description = taskInfo.description; | |
| 204 String title = description != null ? description.toString() : ""; | |
| 205 | |
| 206 final Runnable startNewDocument = new Runnable() { | |
| 207 @Override | |
| 208 public void run() { | |
| 209 Intent newIntent = Tab.createBringTabToFrontIntent(tabId); | |
| 210 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); | |
| 211 mActivity.startActivity(newIntent); | |
| 212 } | |
| 213 }; | |
| 214 | |
| 215 Runnable onClickRunnable = new Runnable() { | |
| 216 @Override | |
| 217 public void run() { | |
| 218 if (mDialog != null) mDialog.dismiss(); | |
| 219 if (currentTabId != tabId) { | |
| 220 ThreadUtils.postOnUiThreadDelayed(startNewDocument, NEW_
TAB_DELAY_MS); | |
| 221 } | |
| 222 } | |
| 223 }; | |
| 224 mCurrentlyOpenTabs.add(new CurrentlyOpenTab(tabId, url, title, onCli
ckRunnable)); | |
| 225 } | |
| 226 } | |
| 227 } | |
| OLD | NEW |