1// Copyright 2013 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
5package org.chromium.chrome.browser;
6
7import org.chromium.base.CalledByNative;
8import org.chromium.chrome.browser.profiles.Profile;
9import org.chromium.ui.WindowOpenDisposition;
10
11import java.util.ArrayList;
12import java.util.List;
13
14/**
15 * This class allows Java code to get and clear the list of recently closed tabs.
16 */
17public class RecentlyClosedBridge {
18    private long mNativeRecentlyClosedTabsBridge;
19
20    /**
21     * Callback interface for getting notified when the list of recently closed tabs is updated.
22     */
23    public interface RecentlyClosedCallback {
24        /**
25         * This method will be called every time the list of recently closed tabs is updated.
26         *
27         * It's a good place to call {@link RecentlyClosedBridge#getRecentlyClosedTabs()} to get the
28         * updated list of tabs.
29         */
30        @CalledByNative("RecentlyClosedCallback")
31        void onUpdated();
32    }
33
34    /**
35     * Represents a recently closed tab.
36     */
37    public static class RecentlyClosedTab {
38        public final int id;
39        public final String title;
40        public final String url;
41
42        private RecentlyClosedTab(int id, String title, String url) {
43            this.id = id;
44            this.title = title;
45            this.url = url;
46        }
47    }
48
49    @CalledByNative
50    private static void pushTab(
51            List<RecentlyClosedTab> tabs, int id, String title, String url) {
52        RecentlyClosedTab tab = new RecentlyClosedTab(id, title, url);
53        tabs.add(tab);
54    }
55
56    /**
57     * Initializes this class with the given profile.
58     * @param profile The Profile whose recently closed tabs will be queried.
59     */
60    public RecentlyClosedBridge(Profile profile) {
61        mNativeRecentlyClosedTabsBridge = nativeInit(profile);
62    }
63
64    @Override
65    protected void finalize() {
66        // Ensure that destroy() was called.
67        assert mNativeRecentlyClosedTabsBridge == 0;
68    }
69
70    /**
71     * Cleans up the C++ side of this class. This instance must not be used after calling destroy().
72     */
73    public void destroy() {
74        assert mNativeRecentlyClosedTabsBridge != 0;
75        nativeDestroy(mNativeRecentlyClosedTabsBridge);
76        mNativeRecentlyClosedTabsBridge = 0;
77    }
78
79    /**
80     * Sets the callback to be called whenever the list of recently closed tabs changes.
81     * @param callback The RecentlyClosedCallback to be notified, or null.
82     */
83    public void setRecentlyClosedCallback(RecentlyClosedCallback callback) {
84        nativeSetRecentlyClosedCallback(mNativeRecentlyClosedTabsBridge, callback);
85    }
86
87    /**
88     * @param maxTabCount The maximum number of recently closed tabs to return.
89     * @return The list of recently closed tabs, with up to maxTabCount elements.
90     */
91    public List<RecentlyClosedTab> getRecentlyClosedTabs(int maxTabCount) {
92        List<RecentlyClosedTab> tabs = new ArrayList<RecentlyClosedTab>();
93        boolean received = nativeGetRecentlyClosedTabs(mNativeRecentlyClosedTabsBridge, tabs,
94                maxTabCount);
95        return received ? tabs : null;
96    }
97
98    // TODO(newt): delete this once all callers are using the new method below.
99    /**
100     * Opens a recently closed tab in the current tab.
101     *
102     * @param tab The current Tab.
103     * @param recentTab The RecentlyClosedTab to open.
104     * @return Whether the tab was successfully opened.
105     */
106    public boolean openRecentlyClosedTab(Tab tab, RecentlyClosedTab recentTab) {
107        return openRecentlyClosedTab(tab, recentTab, WindowOpenDisposition.CURRENT_TAB);
108    }
109
110    /**
111     * Opens a recently closed tab in the current tab or a new tab. If opened in the current tab,
112     * the current tab's entire history is replaced.
113     *
114     * @param tab The current Tab.
115     * @param recentTab The RecentlyClosedTab to open.
116     * @param windowOpenDisposition The WindowOpenDisposition value specifying whether to open in
117     *         the current tab or a new tab.
118     * @return Whether the tab was successfully opened.
119     */
120    public boolean openRecentlyClosedTab(Tab tab, RecentlyClosedTab recentTab,
121            int windowOpenDisposition) {
122        return nativeOpenRecentlyClosedTab(mNativeRecentlyClosedTabsBridge, tab, recentTab.id,
123                windowOpenDisposition);
124    }
125
126    /**
127     * Clears all recently closed tabs.
128     */
129    public void clearRecentlyClosedTabs() {
130        nativeClearRecentlyClosedTabs(mNativeRecentlyClosedTabsBridge);
131    }
132
133    private native long nativeInit(Profile profile);
134    private native void nativeDestroy(long nativeRecentlyClosedTabsBridge);
135    private native void nativeSetRecentlyClosedCallback(
136            long nativeRecentlyClosedTabsBridge, RecentlyClosedCallback callback);
137    private native boolean nativeGetRecentlyClosedTabs(
138            long nativeRecentlyClosedTabsBridge, List<RecentlyClosedTab> tabs, int maxTabCount);
139    private native boolean nativeOpenRecentlyClosedTab(long nativeRecentlyClosedTabsBridge,
140            Tab tab, int recentTabId, int windowOpenDisposition);
141    private native void nativeClearRecentlyClosedTabs(long nativeRecentlyClosedTabsBridge);
142}
143