summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/WebBackForwardList.java
blob: 62a55318d3065bfdbb5450f8025fc5dd2e7a0009 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.webkit;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * This class contains the back/forward list for a WebView.
 * WebView.copyBackForwardList() will return a copy of this class used to
 * inspect the entries in the list.
 */
public class WebBackForwardList implements Cloneable, Serializable {
    // Current position in the list.
    private int mCurrentIndex;
    // ArrayList of WebHistoryItems for maintaining our copy.
    private ArrayList<WebHistoryItem> mArray;
    // Flag to indicate that the list is invalid
    private boolean mClearPending;

    /**
     * Construct a back/forward list used by clients of WebView.
     */
    /*package*/ WebBackForwardList() {
        mCurrentIndex = -1;
        mArray = new ArrayList<WebHistoryItem>();
    }

    /**
     * Return the current history item. This method returns null if the list is
     * empty.
     * @return The current history item.
     */
    public synchronized WebHistoryItem getCurrentItem() {
        return getItemAtIndex(mCurrentIndex);
    }

    /**
     * Get the index of the current history item. This index can be used to
     * directly index into the array list.
     * @return The current index from 0...n or -1 if the list is empty.
     */
    public synchronized int getCurrentIndex() {
        return mCurrentIndex;
    }

    /**
     * Get the history item at the given index. The index range is from 0...n
     * where 0 is the first item and n is the last item.
     * @param index The index to retrieve.
     */
    public synchronized WebHistoryItem getItemAtIndex(int index) {
        if (index < 0 || index >= getSize()) {
            return null;
        }
        return mArray.get(index);
    }

    /**
     * Get the total size of the back/forward list.
     * @return The size of the list.
     */
    public synchronized int getSize() {
        return mArray.size();
    }

    /**
     * Mark the back/forward list as having a pending clear. This is used on the
     * UI side to mark the list as being invalid during the clearHistory method.
     */
    /*package*/ synchronized void setClearPending() {
        mClearPending = true;
    }

    /**
     * Return the status of the clear flag. This is used on the UI side to
     * determine if the list is valid for checking things like canGoBack.
     */
    /*package*/ synchronized boolean getClearPending() {
        return mClearPending;
    }

    /**
     * Add a new history item to the list. This will remove all items after the
     * current item and append the new item to the end of the list. Called from
     * the WebCore thread only. Synchronized because the UI thread may be
     * reading the array or the current index.
     * @param item A new history item.
     */
    /*package*/ synchronized void addHistoryItem(WebHistoryItem item) {
        // Update the current position because we are going to add the new item
        // in that slot.
        ++mCurrentIndex;
        // If the current position is not at the end, remove all history items
        // after the current item.
        final int size = mArray.size();
        final int newPos = mCurrentIndex;
        if (newPos != size) {
            for (int i = size - 1; i >= newPos; i--) {
                final WebHistoryItem h = mArray.remove(i);
            }
        }
        // Add the item to the list.
        mArray.add(item);
    }

    /**
     * Clear the back/forward list. Called from the WebCore thread.
     */
    /*package*/ synchronized void close(int nativeFrame) {
        // Clear the array first because nativeClose will call addHistoryItem
        // with the current item.
        mArray.clear();
        mCurrentIndex = -1;
        nativeClose(nativeFrame);
        // Reset the clear flag
        mClearPending = false;
    }

    /* Remove the item at the given index. Called by JNI only. */
    private synchronized void removeHistoryItem(int index) {
        // XXX: This is a special case. Since the callback is only triggered
        // when removing the first item, we can assert that the index is 0.
        // This lets us change the current index without having to query the
        // native BackForwardList.
        if (DebugFlags.WEB_BACK_FORWARD_LIST && (index != 0)) {
            throw new AssertionError();
        }
        final WebHistoryItem h = mArray.remove(index);
        // XXX: If we ever add another callback for removing history items at
        // any index, this will no longer be valid.
        mCurrentIndex--;
    }

    /**
     * Clone the entire object to be used in the UI thread by clients of
     * WebView. This creates a copy that should never be modified by any of the
     * webkit package classes.
     */
    protected synchronized WebBackForwardList clone() {
        WebBackForwardList l = new WebBackForwardList();
        if (mClearPending) {
            // If a clear is pending, return a copy with only the current item.
            l.addHistoryItem(getCurrentItem());
            return l;
        }
        l.mCurrentIndex = mCurrentIndex;
        int size = getSize();
        l.mArray = new ArrayList<WebHistoryItem>(size);
        for (int i = 0; i < size; i++) {
            // Add a copy of each WebHistoryItem
            l.mArray.add(mArray.get(i).clone());
        }
        return l;
    }

    /**
     * Set the new history index.
     * @param newIndex The new history index.
     */
    /*package*/ synchronized void setCurrentIndex(int newIndex) {
        mCurrentIndex = newIndex;
    }

    /**
     * Restore the history index.
     */
    /*package*/ static native synchronized void restoreIndex(int nativeFrame,
            int index);

    /* Close the native list. */
    private static native void nativeClose(int nativeFrame);
}