blob: e00422553233e18f949a36e9e04ffe74a4214cfe [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
Dany Rybnikov535d4af2014-06-23 09:16:09 +03002 * Copyright (c) 2014, Linux Foundation. All rights reserved.
The Android Open Source Project0c908882009-03-03 19:32:16 -08003 * Copyright (C) 2006 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Bijan Amirzada41242f22014-03-21 12:12:18 -070018package com.android.browser;
The Android Open Source Project0c908882009-03-03 19:32:16 -080019
20import android.app.Activity;
Jeff Hamilton64144e42010-08-18 16:31:59 -050021import android.app.Fragment;
Jeff Hamilton84029622010-08-05 14:29:28 -050022import android.app.LoaderManager;
Dianne Hackborneb07b172010-08-26 22:18:14 -070023import android.content.ClipData;
Michael Kolbbef7a752010-08-25 17:11:35 -070024import android.content.ClipboardManager;
Jeff Hamilton84029622010-08-05 14:29:28 -050025import android.content.ContentUris;
Dianne Hackborn80f32622010-08-05 14:17:53 -070026import android.content.Context;
John Reck71efc2b2011-05-09 16:54:28 -070027import android.content.CursorLoader;
The Android Open Source Project0c908882009-03-03 19:32:16 -080028import android.content.Intent;
Jeff Hamilton84029622010-08-05 14:29:28 -050029import android.content.Loader;
John Reck4f61ee42011-08-22 16:31:14 -070030import android.content.SharedPreferences;
John Reckb3417f02011-01-14 11:01:05 -080031import android.content.res.Configuration;
32import android.content.res.Resources;
Jeff Hamilton84029622010-08-05 14:29:28 -050033import android.database.Cursor;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034import android.graphics.Bitmap;
Jeff Hamilton84029622010-08-05 14:29:28 -050035import android.graphics.BitmapFactory;
John Reckf94abcf2011-10-10 15:33:48 -070036import android.graphics.BitmapFactory.Options;
Dave Tharp490ca7f2015-06-16 11:17:34 -070037import android.graphics.Canvas;
Jeff Hamilton84029622010-08-05 14:29:28 -050038import android.net.Uri;
John Reckc8490812010-11-22 14:15:36 -080039import android.os.AsyncTask;
The Android Open Source Project0c908882009-03-03 19:32:16 -080040import android.os.Bundle;
Dave Tharp490ca7f2015-06-16 11:17:34 -070041import android.util.Log;
The Android Open Source Project0c908882009-03-03 19:32:16 -080042import android.view.ContextMenu;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050043import android.view.ContextMenu.ContextMenuInfo;
Jeff Hamilton64144e42010-08-18 16:31:59 -050044import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080045import android.view.MenuInflater;
46import android.view.MenuItem;
47import android.view.View;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050048import android.view.ViewGroup;
Pankaj Garg49b79252014-11-07 17:33:41 -080049import android.widget.Button;
John Reck71efc2b2011-05-09 16:54:28 -070050import android.widget.ExpandableListView;
51import android.widget.ExpandableListView.OnChildClickListener;
Jeff Hamilton84029622010-08-05 14:29:28 -050052import android.widget.Toast;
The Android Open Source Project0c908882009-03-03 19:32:16 -080053
Dave Tharp490ca7f2015-06-16 11:17:34 -070054import com.android.browser.mdm.ManagedBookmarksRestriction;
Bijan Amirzada41242f22014-03-21 12:12:18 -070055import com.android.browser.platformsupport.BrowserContract;
56import com.android.browser.platformsupport.BrowserContract.Accounts;
57import com.android.browser.provider.BrowserProvider2;
58import com.android.browser.view.BookmarkExpandableView;
59import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080060
61import java.util.HashMap;
John Recke7c97de2011-05-27 14:42:43 -070062
John Reck4f61ee42011-08-22 16:31:14 -070063import org.json.JSONException;
64import org.json.JSONObject;
65
Dany Rybnikovdb490c12015-03-29 15:46:24 +030066import org.codeaurora.net.NetworkServices;
Dany Rybnikov535d4af2014-06-23 09:16:09 +030067
John Reck608baa72010-11-24 10:32:28 -080068interface BookmarksPageCallbacks {
69 // Return true if handled
70 boolean onBookmarkSelected(Cursor c, boolean isFolder);
71 // Return true if handled
John Reckd3e4d5b2011-07-13 15:48:43 -070072 boolean onOpenInNewWindow(String... urls);
John Reck608baa72010-11-24 10:32:28 -080073}
74
The Android Open Source Project0c908882009-03-03 19:32:16 -080075/**
76 * View showing the user's bookmarks in the browser.
77 */
Jeff Hamilton64144e42010-08-18 16:31:59 -050078public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
John Reck9db95292011-06-20 13:00:12 -070079 LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
John Reckd3e4d5b2011-07-13 15:48:43 -070080 OnChildClickListener {
The Android Open Source Project0c908882009-03-03 19:32:16 -080081
Dave Tharp490ca7f2015-06-16 11:17:34 -070082 private static final String TAG = "BrowserBookmarksPage";
83
John Recke7c97de2011-05-27 14:42:43 -070084 public static class ExtraDragState {
85 public int childPosition;
86 public int groupPosition;
87 }
88
Jeff Hamilton84029622010-08-05 14:29:28 -050089 static final String LOGTAG = "browser";
Nicolas Catania095292f2010-03-15 09:00:14 -070090
John Reck71efc2b2011-05-09 16:54:28 -070091 static final int LOADER_ACCOUNTS = 1;
92 static final int LOADER_BOOKMARKS = 100;
Jeff Hamilton84029622010-08-05 14:29:28 -050093
Michael Kolb801ecb72010-08-25 12:57:38 -070094 static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
John Reck4f61ee42011-08-22 16:31:14 -070095 static final String PREF_GROUP_STATE = "bbp_group_state";
Michael Kolb801ecb72010-08-25 12:57:38 -070096
John Reck71efc2b2011-05-09 16:54:28 -070097 static final String ACCOUNT_TYPE = "account_type";
98 static final String ACCOUNT_NAME = "account_name";
99
luxiaoldbe4a622013-07-19 17:14:06 +0800100 static final long DEFAULT_FOLDER_ID = -1;
101
John Reck608baa72010-11-24 10:32:28 -0800102 BookmarksPageCallbacks mCallbacks;
John Reck0ce8a942011-01-14 19:57:09 -0800103 View mRoot;
John Reck9db95292011-06-20 13:00:12 -0700104 BookmarkExpandableView mGrid;
Jeff Hamilton84029622010-08-05 14:29:28 -0500105 boolean mDisableNewWindow;
John Reck608baa72010-11-24 10:32:28 -0800106 boolean mEnableContextMenu = true;
Jeff Hamilton84029622010-08-05 14:29:28 -0500107 View mEmptyView;
John Reck608baa72010-11-24 10:32:28 -0800108 View mHeader;
John Reck71efc2b2011-05-09 16:54:28 -0700109 HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
John Reck4f61ee42011-08-22 16:31:14 -0700110 JSONObject mState;
luxiaoldbe4a622013-07-19 17:14:06 +0800111 long mCurrentFolderId = BrowserProvider2.FIXED_ID_ROOT;
Michael Kolb370a4f32010-10-06 10:45:32 -0700112
Jeff Hamilton84029622010-08-05 14:29:28 -0500113 @Override
114 public Loader<Cursor> onCreateLoader(int id, Bundle args) {
John Reck71efc2b2011-05-09 16:54:28 -0700115 if (id == LOADER_ACCOUNTS) {
116 return new AccountsLoader(getActivity());
117 } else if (id >= LOADER_BOOKMARKS) {
118 String accountType = args.getString(ACCOUNT_TYPE);
119 String accountName = args.getString(ACCOUNT_NAME);
120 BookmarksLoader bl = new BookmarksLoader(getActivity(),
121 accountType, accountName);
122 return bl;
123 } else {
124 throw new UnsupportedOperationException("Unknown loader id " + id);
Jeff Hamilton84029622010-08-05 14:29:28 -0500125 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500126 }
127
128 @Override
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500129 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
John Reck71efc2b2011-05-09 16:54:28 -0700130 if (loader.getId() == LOADER_ACCOUNTS) {
131 LoaderManager lm = getLoaderManager();
132 int id = LOADER_BOOKMARKS;
133 while (cursor.moveToNext()) {
134 String accountName = cursor.getString(0);
135 String accountType = cursor.getString(1);
136 Bundle args = new Bundle();
137 args.putString(ACCOUNT_NAME, accountName);
138 args.putString(ACCOUNT_TYPE, accountType);
139 BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
John Reckaf991f92012-04-24 15:31:16 -0700140 getActivity());
John Reck71efc2b2011-05-09 16:54:28 -0700141 mBookmarkAdapters.put(id, adapter);
John Reck4f61ee42011-08-22 16:31:14 -0700142 boolean expand = true;
143 try {
144 expand = mState.getBoolean(accountName != null ? accountName
145 : BookmarkExpandableView.LOCAL_ACCOUNT_NAME);
146 } catch (JSONException e) {} // no state for accountName
147 mGrid.addAccount(accountName, adapter, expand);
John Reck71efc2b2011-05-09 16:54:28 -0700148 lm.restartLoader(id, args, this);
149 id++;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500150 }
John Reck71efc2b2011-05-09 16:54:28 -0700151 // TODO: Figure out what a reload of these means
152 // Currently, a reload is triggered whenever bookmarks change
153 // This is less than ideal
154 // It also causes UI flickering as a new adapter is created
155 // instead of re-using an existing one when the account_name is the
156 // same.
157 // For now, this is a one-shot load
158 getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
159 } else if (loader.getId() >= LOADER_BOOKMARKS) {
160 BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
161 adapter.changeCursor(cursor);
luxiaoldbe4a622013-07-19 17:14:06 +0800162 if (adapter.getCount() != 0) {
163 mCurrentFolderId = adapter.getItem(0).getLong(BookmarksLoader.COLUMN_INDEX_PARENT);
164 }
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500165 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500166 }
167
John Reck522a4382011-01-26 13:23:47 -0800168 @Override
Dianne Hackborn39772c82010-12-16 00:43:54 -0800169 public void onLoaderReset(Loader<Cursor> loader) {
John Reck3ad8d5c2012-04-23 14:50:09 -0700170 if (loader.getId() >= LOADER_BOOKMARKS) {
171 BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
172 adapter.changeCursor(null);
173 }
Dianne Hackborn39772c82010-12-16 00:43:54 -0800174 }
175
The Android Open Source Project0c908882009-03-03 19:32:16 -0800176 @Override
177 public boolean onContextItemSelected(MenuItem item) {
John Reck54ed3aa2011-08-19 15:16:05 -0700178 if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) {
179 return false;
180 }
181 BookmarkContextMenuInfo i = (BookmarkContextMenuInfo) item.getMenuInfo();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800182 // If we have no menu info, we can't tell which item was selected.
183 if (i == null) {
Leon Scrogginsc8cae082010-11-03 18:51:46 -0400184 return false;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800185 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700186
John Recke7c97de2011-05-27 14:42:43 -0700187 if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) {
188 return true;
189 }
190 return super.onContextItemSelected(item);
191 }
192
193 public boolean handleContextItem(int itemId, int groupPosition,
194 int childPosition) {
195 final Activity activity = getActivity();
196 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
197
198 switch (itemId) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800199 case R.id.open_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700200 loadUrl(adapter, childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800201 break;
Dave Tharp490ca7f2015-06-16 11:17:34 -0700202 case R.id.folder_edit_context_menu_id:
The Android Open Source Project0c908882009-03-03 19:32:16 -0800203 case R.id.edit_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700204 editBookmark(adapter, childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800205 break;
206 case R.id.shortcut_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700207 Cursor c = adapter.getItem(childPosition);
John Reck608baa72010-11-24 10:32:28 -0800208 activity.sendBroadcast(createShortcutIntent(getActivity(), c));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800209 break;
Dave Tharp490ca7f2015-06-16 11:17:34 -0700210 case R.id.folder_delete_context_menu_id:
The Android Open Source Project0c908882009-03-03 19:32:16 -0800211 case R.id.delete_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700212 displayRemoveBookmarkDialog(adapter, childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800213 break;
214 case R.id.new_window_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700215 openInNewWindow(adapter, childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800216 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500217 case R.id.share_link_context_menu_id: {
John Recke7c97de2011-05-27 14:42:43 -0700218 Cursor cursor = adapter.getItem(childPosition);
Michael Kolb8233fac2010-10-26 16:08:53 -0700219 Controller.sharePage(activity,
Jeff Hamilton84029622010-08-05 14:29:28 -0500220 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
221 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
222 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
223 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800224 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500225 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800226 case R.id.copy_url_context_menu_id:
John Recke7c97de2011-05-27 14:42:43 -0700227 copy(getUrl(adapter, childPosition));
Leon Scrogginsfeb941d2009-05-28 17:27:38 -0400228 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500229 case R.id.homepage_context_menu_id: {
John Recke7c97de2011-05-27 14:42:43 -0700230 BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition));
Jeff Hamilton64144e42010-08-18 16:31:59 -0500231 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
Leon Scrogginsfeb941d2009-05-28 17:27:38 -0400232 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500233 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400234 // Only for the Most visited page
Jeff Hamilton84029622010-08-05 14:29:28 -0500235 case R.id.save_to_bookmarks_menu_id: {
John Recke7c97de2011-05-27 14:42:43 -0700236 Cursor cursor = adapter.getItem(childPosition);
Jeff Hamilton84029622010-08-05 14:29:28 -0500237 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
238 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400239 // If the site is bookmarked, the item becomes remove from
240 // bookmarks.
Jeff Hamilton64144e42010-08-18 16:31:59 -0500241 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400242 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500243 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800244 default:
John Recke7c97de2011-05-27 14:42:43 -0700245 return false;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800246 }
247 return true;
248 }
249
John Reck608baa72010-11-24 10:32:28 -0800250 static Bitmap getBitmap(Cursor cursor, int columnIndex) {
John Reckf94abcf2011-10-10 15:33:48 -0700251 return getBitmap(cursor, columnIndex, null);
252 }
253
254 static ThreadLocal<Options> sOptions = new ThreadLocal<Options>() {
255 @Override
256 protected Options initialValue() {
257 return new Options();
258 };
259 };
260 static Bitmap getBitmap(Cursor cursor, int columnIndex, Bitmap inBitmap) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500261 byte[] data = cursor.getBlob(columnIndex);
262 if (data == null) {
263 return null;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800264 }
John Reckf94abcf2011-10-10 15:33:48 -0700265 Options opts = sOptions.get();
266 opts.inBitmap = inBitmap;
267 opts.inSampleSize = 1;
268 opts.inScaled = false;
269 try {
270 return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
271 } catch (IllegalArgumentException ex) {
272 // Failed to re-use bitmap, create a new one
273 return BitmapFactory.decodeByteArray(data, 0, data.length);
274 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500275 }
276
John Reckc8490812010-11-22 14:15:36 -0800277 private MenuItem.OnMenuItemClickListener mContextItemClickListener =
278 new MenuItem.OnMenuItemClickListener() {
279 @Override
280 public boolean onMenuItemClick(MenuItem item) {
281 return onContextItemSelected(item);
282 }
283 };
284
Jeff Hamilton84029622010-08-05 14:29:28 -0500285 @Override
286 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
John Reck71efc2b2011-05-09 16:54:28 -0700287 BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
288 BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
289 Cursor cursor = adapter.getItem(info.childPosition);
John Reck1cebb442010-12-10 12:02:16 -0800290 if (!canEdit(cursor)) {
291 return;
292 }
Leon Scroggins5e8a40f2010-09-27 17:13:35 -0400293 boolean isFolder
294 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
Dave Tharp490ca7f2015-06-16 11:17:34 -0700295 boolean isMdmElem = ManagedBookmarksRestriction.getInstance().mDb.
296 isMdmElement(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
Michael Kolb801ecb72010-08-25 12:57:38 -0700297
Jeff Hamilton64144e42010-08-18 16:31:59 -0500298 final Activity activity = getActivity();
299 MenuInflater inflater = activity.getMenuInflater();
Jeff Hamilton84029622010-08-05 14:29:28 -0500300 inflater.inflate(R.menu.bookmarkscontext, menu);
John Reckc8490812010-11-22 14:15:36 -0800301 if (isFolder) {
302 menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true);
Dave Tharp490ca7f2015-06-16 11:17:34 -0700303 if(isMdmElem) {
304 menu.findItem(R.id.folder_edit_context_menu_id).setEnabled(false);
305 menu.findItem(R.id.folder_delete_context_menu_id).setEnabled(false);
306 }
John Reckc8490812010-11-22 14:15:36 -0800307 } else {
308 menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true);
309 if (mDisableNewWindow) {
310 menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
311 }
Dave Tharp490ca7f2015-06-16 11:17:34 -0700312 if(isMdmElem) {
313 menu.findItem(R.id.edit_context_menu_id).setEnabled(false);
314 menu.findItem(R.id.delete_context_menu_id).setEnabled(false);
315 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500316 }
John Reckc8490812010-11-22 14:15:36 -0800317 BookmarkItem header = new BookmarkItem(activity);
John Reck83c01512011-09-09 11:14:16 -0700318 header.setEnableScrolling(true);
Dave Tharp490ca7f2015-06-16 11:17:34 -0700319 populateBookmarkItem(cursor, header, isFolder, isMdmElem);
John Reckc8490812010-11-22 14:15:36 -0800320 menu.setHeaderView(header);
Jeff Hamilton84029622010-08-05 14:29:28 -0500321
John Reckc8490812010-11-22 14:15:36 -0800322 int count = menu.size();
323 for (int i = 0; i < count; i++) {
324 menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener);
Jeff Hamilton84029622010-08-05 14:29:28 -0500325 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500326 }
327
John Reck1cebb442010-12-10 12:02:16 -0800328 boolean canEdit(Cursor c) {
John Reckd18ac4b2012-04-12 17:27:34 -0700329 int type = c.getInt(BookmarksLoader.COLUMN_INDEX_TYPE);
330 return type == BrowserContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK
331 || type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER;
John Reck1cebb442010-12-10 12:02:16 -0800332 }
333
Dave Tharp490ca7f2015-06-16 11:17:34 -0700334 public static Bitmap overlayBookmarkBitmap(Bitmap origImage, int overlayResId, Context context,
335 float overlayScaleFactor) {
336 if (origImage == null) {
337 Log.e(TAG, "Orig Image is null!");
338 return origImage;
339 }
340 // Get metrics for incoming bitmap
341 int origWidth = origImage.getWidth();
342 int origHeight = origImage.getHeight();
343
344 // Load the bitmap for the badge
345 Bitmap srcOverlay = BitmapFactory.decodeResource(context.getResources(), overlayResId);
346
347 if (srcOverlay == null) {
348 Log.e(TAG, "Overlay bitmap creation failed");
349 return origImage;
350 }
351
352 // Scale the badge
353 float fx = (float) srcOverlay.getWidth() * overlayScaleFactor;
354 float fy = (float) srcOverlay.getHeight() * overlayScaleFactor;
355 Bitmap scaledOverlay = Bitmap.createScaledBitmap(srcOverlay, (int) fx, (int) fy, true);
356 if (scaledOverlay == null) {
357 srcOverlay.recycle();
358 Runtime.getRuntime().gc();
359 Log.e(TAG, "Scaled bitmap creation failed");
360 return origImage;
361 }
362
363 // Create the bitmap we are compositing into
364 Bitmap overlaid = Bitmap.createBitmap(origWidth, origHeight, Bitmap.Config.ARGB_8888);
365 if (overlaid == null) {
366 srcOverlay.recycle();
367 scaledOverlay.recycle();
368 Runtime.getRuntime().gc();
369 Log.e(TAG, "Composite bitmap creation failed");
370 return origImage;
371 }
372
373 // Do the overlay
374 Canvas comboImage = new Canvas(overlaid);
375 comboImage.drawBitmap(origImage, 0, 0, null);
376
377 comboImage.drawBitmap(scaledOverlay,
378 origWidth - scaledOverlay.getWidth(),
379 origHeight - scaledOverlay.getHeight(),
380 null);
381
382 // Clean up our bitmaps
383 srcOverlay.recycle();
384 scaledOverlay.recycle();
385 Runtime.getRuntime().gc();
386
387 return overlaid;
388 }
389
390 private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder, boolean isMdmElem) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500391 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
John Reckc8490812010-11-22 14:15:36 -0800392 if (isFolder) {
393 item.setUrl(null);
394 Bitmap bitmap =
Enrico Rosd6efa972014-12-02 19:49:59 -0800395 BitmapFactory.decodeResource(getResources(), R.drawable.ic_deco_folder_normal);
Dave Tharp490ca7f2015-06-16 11:17:34 -0700396 if (isMdmElem) {
397 bitmap = overlayBookmarkBitmap(bitmap, R.drawable.img_deco_mdm_badge_bright, getActivity(), 0.25f);
398 }
John Reckc8490812010-11-22 14:15:36 -0800399 item.setFavicon(bitmap);
John Reck60e33362010-12-02 17:52:38 -0800400 new LookupBookmarkCount(getActivity(), item)
401 .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
John Reckc8490812010-11-22 14:15:36 -0800402 } else {
403 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
404 item.setUrl(url);
405 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
Dave Tharp490ca7f2015-06-16 11:17:34 -0700406 if (isMdmElem) {
407 if (null == bitmap) {
408 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_deco_favicon_normal);
409 }
410 bitmap = overlayBookmarkBitmap(bitmap, R.drawable.img_deco_mdm_badge_bright, getActivity(), 0.25f);
411 }
John Reckc8490812010-11-22 14:15:36 -0800412 item.setFavicon(bitmap);
Jeff Hamilton84029622010-08-05 14:29:28 -0500413 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500414 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800415
416 /**
417 * Create a new BrowserBookmarksPage.
Nicolas Catania095292f2010-03-15 09:00:14 -0700418 */
The Android Open Source Project0c908882009-03-03 19:32:16 -0800419 @Override
Jeff Hamilton64144e42010-08-18 16:31:59 -0500420 public void onCreate(Bundle icicle) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800421 super.onCreate(icicle);
John Reck4f61ee42011-08-22 16:31:14 -0700422 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
423 try {
424 mState = new JSONObject(prefs.getString(PREF_GROUP_STATE, "{}"));
425 } catch (JSONException e) {
426 // Parse failed, clear preference and start with empty state
427 prefs.edit().remove(PREF_GROUP_STATE).apply();
428 mState = new JSONObject();
429 }
Jeff Hamilton64144e42010-08-18 16:31:59 -0500430 Bundle args = getArguments();
Leon Scrogginsbc922852010-10-22 12:15:27 -0400431 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
John Reck2d963a22011-08-10 15:53:07 -0700432 if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) {
433 mCallbacks = new CombinedBookmarksCallbackWrapper(
434 (CombinedBookmarksCallbacks) getActivity());
435 }
Tarun Nainani87a86682015-02-05 11:47:35 -0800436 if (mCallbacks == null) {
437 View cb = getActivity().getWindow().getDecorView().findViewById(R.id.combo_view_container);
438 if (cb != null && cb instanceof CombinedBookmarksCallbacks) {
439 mCallbacks = new CombinedBookmarksCallbackWrapper(
440 (CombinedBookmarksCallbacks) cb);
441 }
442 }
Jeff Hamilton64144e42010-08-18 16:31:59 -0500443 }
Leon Scrogginsd87f85e2009-08-18 14:13:31 -0400444
John Reck4f61ee42011-08-22 16:31:14 -0700445 @Override
446 public void onPause() {
447 super.onPause();
448 try {
449 mState = mGrid.saveGroupState();
450 // Save state
451 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
452 prefs.edit()
453 .putString(PREF_GROUP_STATE, mState.toString())
454 .apply();
455 } catch (JSONException e) {
456 // Not critical, ignore
457 }
458 }
459
John Reck2d963a22011-08-10 15:53:07 -0700460 private static class CombinedBookmarksCallbackWrapper
461 implements BookmarksPageCallbacks {
462
463 private CombinedBookmarksCallbacks mCombinedCallback;
464
465 private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) {
466 mCombinedCallback = cb;
467 }
468
469 @Override
470 public boolean onOpenInNewWindow(String... urls) {
471 mCombinedCallback.openInNewTab(urls);
472 return true;
473 }
474
475 @Override
476 public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
477 if (isFolder) {
478 return false;
479 }
480 mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c));
481 return true;
482 }
483 };
484
Jeff Hamilton64144e42010-08-18 16:31:59 -0500485 @Override
Jeff Hamilton64144e42010-08-18 16:31:59 -0500486 public View onCreateView(LayoutInflater inflater, ViewGroup container,
487 Bundle savedInstanceState) {
Pankaj Garg49b79252014-11-07 17:33:41 -0800488 final Activity activity = getActivity();
John Reck0ce8a942011-01-14 19:57:09 -0800489 mRoot = inflater.inflate(R.layout.bookmarks, container, false);
490 mEmptyView = mRoot.findViewById(android.R.id.empty);
Leon Scrogginsd87f85e2009-08-18 14:13:31 -0400491
John Reck9db95292011-06-20 13:00:12 -0700492 mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid);
John Reck71efc2b2011-05-09 16:54:28 -0700493 mGrid.setOnChildClickListener(this);
494 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
495 mGrid.setBreadcrumbController(this);
John Reck608baa72010-11-24 10:32:28 -0800496 setEnableContextMenu(mEnableContextMenu);
497
Pankaj Garg49b79252014-11-07 17:33:41 -0800498 Button btn = (Button) mRoot.findViewById(R.id.add_bookmark_button);
499 btn.setOnClickListener(new View.OnClickListener() {
500 @Override
501 public void onClick(View view) {
Dave Tharp490ca7f2015-06-16 11:17:34 -0700502 ManagedBookmarksRestriction mbr = ManagedBookmarksRestriction.getInstance();
503 if (mbr.isEnabled() &&
504 mbr.mDb.isMdmElement(mCurrentFolderId)) {
505 Toast.makeText(getActivity(), R.string.mdm_managed_alert, Toast.LENGTH_SHORT).show();
506 }
507 else {
508 Intent intent = new Intent(activity, AddBookmarkPage.class);
509 intent.putExtra(BrowserContract.Bookmarks.URL, "http://");
510 intent.putExtra(BrowserContract.Bookmarks.TITLE, "");
511 intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
512 activity.startActivity(intent);
513 }
Pankaj Garg49b79252014-11-07 17:33:41 -0800514 }
515 });
516
517 btn = (Button) mRoot.findViewById(R.id.new_bmfolder_button);
518 btn.setOnClickListener(new View.OnClickListener() {
519 @Override
520 public void onClick(View view) {
Dave Tharp490ca7f2015-06-16 11:17:34 -0700521 ManagedBookmarksRestriction mbr = ManagedBookmarksRestriction.getInstance();
522 if (mbr.isEnabled() &&
523 mbr.mDb.isMdmElement(mCurrentFolderId)) {
524 Toast.makeText(getActivity(), R.string.mdm_managed_alert, Toast.LENGTH_SHORT).show();
525 }
526 else {
527 Intent intent = new Intent(activity, AddBookmarkFolder.class);
528 intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
529 activity.startActivity(intent);
530 }
Pankaj Garg49b79252014-11-07 17:33:41 -0800531 }
532 });
533
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500534 // Start the loaders
535 LoaderManager lm = getLoaderManager();
John Reck71efc2b2011-05-09 16:54:28 -0700536 lm.restartLoader(LOADER_ACCOUNTS, null, this);
Jeff Hamilton84029622010-08-05 14:29:28 -0500537
Dany Rybnikovb80159e2014-06-23 09:16:09 +0300538 //Notify about anticipated network activity
Dany Rybnikovdb490c12015-03-29 15:46:24 +0300539 NetworkServices.HintUpcomingUserActivity();
Dany Rybnikovb80159e2014-06-23 09:16:09 +0300540
John Reck0ce8a942011-01-14 19:57:09 -0800541 return mRoot;
Jeff Hamilton64144e42010-08-18 16:31:59 -0500542 }
Michael Kolb801ecb72010-08-25 12:57:38 -0700543
John Reck608baa72010-11-24 10:32:28 -0800544 @Override
545 public void onDestroyView() {
546 super.onDestroyView();
John Reck71efc2b2011-05-09 16:54:28 -0700547 mGrid.setBreadcrumbController(null);
John Reckc3c46d72011-09-06 16:17:34 -0700548 mGrid.clearAccounts();
John Reck71efc2b2011-05-09 16:54:28 -0700549 LoaderManager lm = getLoaderManager();
550 lm.destroyLoader(LOADER_ACCOUNTS);
551 for (int id : mBookmarkAdapters.keySet()) {
Tarun Nainaniebdf18e2014-07-09 19:35:30 -0700552 mBookmarkAdapters.get(id).quitThread();
John Reck71efc2b2011-05-09 16:54:28 -0700553 lm.destroyLoader(id);
John Reck608baa72010-11-24 10:32:28 -0800554 }
John Reck71efc2b2011-05-09 16:54:28 -0700555 mBookmarkAdapters.clear();
John Reck71efc2b2011-05-09 16:54:28 -0700556 }
557
558 private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
John Reck9db95292011-06-20 13:00:12 -0700559 return mGrid.getChildAdapter(groupPosition);
John Reck71efc2b2011-05-09 16:54:28 -0700560 }
561
562 private BreadCrumbView getBreadCrumbs(int groupPosition) {
John Reck9db95292011-06-20 13:00:12 -0700563 return mGrid.getBreadCrumbs(groupPosition);
Nicolas Catania095292f2010-03-15 09:00:14 -0700564 }
565
Jeff Hamilton84029622010-08-05 14:29:28 -0500566 @Override
John Reck71efc2b2011-05-09 16:54:28 -0700567 public boolean onChildClick(ExpandableListView parent, View v,
568 int groupPosition, int childPosition, long id) {
569 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
570 Cursor cursor = adapter.getItem(childPosition);
John Reck608baa72010-11-24 10:32:28 -0800571 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
572 if (mCallbacks != null &&
573 mCallbacks.onBookmarkSelected(cursor, isFolder)) {
John Reck71efc2b2011-05-09 16:54:28 -0700574 return true;
Ben Murdoch328ea872009-09-16 13:33:29 +0100575 }
576
John Reck608baa72010-11-24 10:32:28 -0800577 if (isFolder) {
Michael Kolb370a4f32010-10-06 10:45:32 -0700578 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Jeff Hamilton84029622010-08-05 14:29:28 -0500579 Uri uri = ContentUris.withAppendedId(
580 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
John Reck71efc2b2011-05-09 16:54:28 -0700581 BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
582 if (crumbs != null) {
Michael Kolb370a4f32010-10-06 10:45:32 -0700583 // update crumbs
John Reck71efc2b2011-05-09 16:54:28 -0700584 crumbs.pushView(title, uri);
John Reckcece1fe2011-09-13 08:47:17 -0700585 crumbs.setVisibility(View.VISIBLE);
luxiaoldbe4a622013-07-19 17:14:06 +0800586 Object data = crumbs.getTopData();
587 mCurrentFolderId = (data != null ? ContentUris.parseId((Uri) data)
588 : DEFAULT_FOLDER_ID);
Michael Kolb370a4f32010-10-06 10:45:32 -0700589 }
John Reck71efc2b2011-05-09 16:54:28 -0700590 loadFolder(groupPosition, uri);
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400591 }
John Reck71efc2b2011-05-09 16:54:28 -0700592 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800593 }
594
John Reck608baa72010-11-24 10:32:28 -0800595 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500596 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
Michael Kolbccaa8962010-10-20 17:03:10 -0700597 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Jeff Hamilton84029622010-08-05 14:29:28 -0500598 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
599 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
John Reck608baa72010-11-24 10:32:28 -0800600 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800601 }
602
John Reck71efc2b2011-05-09 16:54:28 -0700603 private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
604 if (mCallbacks != null && adapter != null) {
605 mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
John Reck608baa72010-11-24 10:32:28 -0800606 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800607 }
608
John Reck71efc2b2011-05-09 16:54:28 -0700609 private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
John Reck608baa72010-11-24 10:32:28 -0800610 if (mCallbacks != null) {
John Reck71efc2b2011-05-09 16:54:28 -0700611 Cursor c = adapter.getItem(position);
John Reck1b3c66e2011-01-11 13:20:32 -0800612 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
613 if (isFolder) {
614 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
615 new OpenAllInTabsTask(id).execute();
616 } else {
John Reckd3e4d5b2011-07-13 15:48:43 -0700617 mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c));
John Reck1b3c66e2011-01-11 13:20:32 -0800618 }
John Reck608baa72010-11-24 10:32:28 -0800619 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800620 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700621
John Reck1b3c66e2011-01-11 13:20:32 -0800622 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> {
623 long mFolderId;
624 public OpenAllInTabsTask(long id) {
625 mFolderId = id;
626 }
627
628 @Override
629 protected Cursor doInBackground(Void... params) {
630 Context c = getActivity();
631 if (c == null) return null;
632 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c),
633 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?",
634 new String[] { Long.toString(mFolderId) }, null);
635 }
636
637 @Override
638 protected void onPostExecute(Cursor result) {
John Reckd3e4d5b2011-07-13 15:48:43 -0700639 if (mCallbacks != null && result.getCount() > 0) {
640 String[] urls = new String[result.getCount()];
641 int i = 0;
John Reck1b3c66e2011-01-11 13:20:32 -0800642 while (result.moveToNext()) {
John Reckd3e4d5b2011-07-13 15:48:43 -0700643 urls[i++] = BrowserBookmarksPage.getUrl(result);
John Reck1b3c66e2011-01-11 13:20:32 -0800644 }
John Reckd3e4d5b2011-07-13 15:48:43 -0700645 mCallbacks.onOpenInNewWindow(urls);
John Reck1b3c66e2011-01-11 13:20:32 -0800646 }
647 }
648
649 }
650
John Reck71efc2b2011-05-09 16:54:28 -0700651 private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500652 Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
John Reck71efc2b2011-05-09 16:54:28 -0700653 Cursor cursor = adapter.getItem(position);
Jeff Hamilton84029622010-08-05 14:29:28 -0500654 Bundle item = new Bundle();
Michael Kolbbef7a752010-08-25 17:11:35 -0700655 item.putString(BrowserContract.Bookmarks.TITLE,
Jeff Hamilton84029622010-08-05 14:29:28 -0500656 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
Michael Kolbbef7a752010-08-25 17:11:35 -0700657 item.putString(BrowserContract.Bookmarks.URL,
Jeff Hamilton84029622010-08-05 14:29:28 -0500658 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
659 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
660 if (data != null) {
Michael Kolbbef7a752010-08-25 17:11:35 -0700661 item.putParcelable(BrowserContract.Bookmarks.FAVICON,
Jeff Hamilton84029622010-08-05 14:29:28 -0500662 BitmapFactory.decodeByteArray(data, 0, data.length));
663 }
John Reckc8490812010-11-22 14:15:36 -0800664 item.putLong(BrowserContract.Bookmarks._ID,
665 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
Leon Scroggins III052ce662010-09-13 14:44:16 -0400666 item.putLong(BrowserContract.Bookmarks.PARENT,
667 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT));
John Reckc8490812010-11-22 14:15:36 -0800668 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item);
669 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER,
670 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1);
671 startActivity(intent);
Jeff Hamilton84029622010-08-05 14:29:28 -0500672 }
673
John Reck71efc2b2011-05-09 16:54:28 -0700674 private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
675 int position) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800676 // Put up a dialog asking if the user really wants to
677 // delete the bookmark
John Reck71efc2b2011-05-09 16:54:28 -0700678 Cursor cursor = adapter.getItem(position);
Leon Scroggins75630672011-01-13 17:56:15 -0500679 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
680 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Jeff Hamilton64144e42010-08-18 16:31:59 -0500681 Context context = getActivity();
Leon Scroggins75630672011-01-13 17:56:15 -0500682 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800683 }
684
John Reck71efc2b2011-05-09 16:54:28 -0700685 private String getUrl(BrowserBookmarksAdapter adapter, int position) {
686 return getUrl(adapter.getItem(position));
John Reck608baa72010-11-24 10:32:28 -0800687 }
688
689 /* package */ static String getUrl(Cursor c) {
690 return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800691 }
Michael Kolb801ecb72010-08-25 12:57:38 -0700692
The Android Open Source Project0c908882009-03-03 19:32:16 -0800693 private void copy(CharSequence text) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500694 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
695 Context.CLIPBOARD_SERVICE);
Dianne Hackbornbf1d10a2011-01-17 12:29:51 -0800696 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString())));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800697 }
Michael Kolb370a4f32010-10-06 10:45:32 -0700698
John Reckb3417f02011-01-14 11:01:05 -0800699 @Override
John Reckb3417f02011-01-14 11:01:05 -0800700 public void onConfigurationChanged(Configuration newConfig) {
701 super.onConfigurationChanged(newConfig);
702 Resources res = getActivity().getResources();
John Reck71efc2b2011-05-09 16:54:28 -0700703 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
John Reck0ce8a942011-01-14 19:57:09 -0800704 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
John Reckf3828cd2011-06-14 17:21:55 -0700705 mRoot.setPadding(0, paddingTop, 0, 0);
John Reckb3417f02011-01-14 11:01:05 -0800706 }
707
John Reck608baa72010-11-24 10:32:28 -0800708 /**
709 * BreadCrumb controller callback
710 */
711 @Override
John Reck71efc2b2011-05-09 16:54:28 -0700712 public void onTop(BreadCrumbView view, int level, Object data) {
713 int groupPosition = (Integer) view.getTag(R.id.group_position);
John Reck89f73c12010-12-01 10:10:14 -0800714 Uri uri = (Uri) data;
715 if (uri == null) {
716 // top level
717 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
718 }
John Reck71efc2b2011-05-09 16:54:28 -0700719 loadFolder(groupPosition, uri);
John Reckcece1fe2011-09-13 08:47:17 -0700720 if (level <= 1) {
721 view.setVisibility(View.GONE);
722 } else {
723 view.setVisibility(View.VISIBLE);
724 }
John Reck89f73c12010-12-01 10:10:14 -0800725 }
726
727 /**
728 * @param uri
729 */
John Reck71efc2b2011-05-09 16:54:28 -0700730 private void loadFolder(int groupPosition, Uri uri) {
John Reck89f73c12010-12-01 10:10:14 -0800731 LoaderManager manager = getLoaderManager();
John Reck71efc2b2011-05-09 16:54:28 -0700732 // This assumes groups are ordered the same as loaders
733 BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
734 manager.getLoader(LOADER_BOOKMARKS + groupPosition));
John Reck89f73c12010-12-01 10:10:14 -0800735 loader.setUri(uri);
736 loader.forceLoad();
John Reck608baa72010-11-24 10:32:28 -0800737 }
738
John Reck608baa72010-11-24 10:32:28 -0800739 public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
740 mCallbacks = callbackListener;
741 }
742
743 public void setEnableContextMenu(boolean enable) {
744 mEnableContextMenu = enable;
745 if (mGrid != null) {
746 if (mEnableContextMenu) {
747 registerForContextMenu(mGrid);
748 } else {
749 unregisterForContextMenu(mGrid);
750 mGrid.setLongClickable(false);
751 }
752 }
John Reck608baa72010-11-24 10:32:28 -0800753 }
John Reckc8490812010-11-22 14:15:36 -0800754
755 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> {
756 Context mContext;
757 BookmarkItem mHeader;
758
759 public LookupBookmarkCount(Context context, BookmarkItem header) {
Ben Murdoch914c5592011-08-01 13:58:47 +0100760 mContext = context.getApplicationContext();
John Reckc8490812010-11-22 14:15:36 -0800761 mHeader = header;
762 }
763
764 @Override
765 protected Integer doInBackground(Long... params) {
766 if (params.length != 1) {
767 throw new IllegalArgumentException("Missing folder id!");
768 }
769 Uri uri = BookmarkUtils.getBookmarksUri(mContext);
Axesh R. Ajmera632e5a02014-11-13 09:52:46 -0800770 Cursor c = null;
771 try {
772 c = mContext.getContentResolver().query(uri,
773 null, BrowserContract.Bookmarks.PARENT + "=?",
774 new String[] {params[0].toString()}, null);
775 return c.getCount();
776 } finally {
777 if (c != null) {
778 c.close();
779 }
780 }
John Reckc8490812010-11-22 14:15:36 -0800781 }
782
783 @Override
784 protected void onPostExecute(Integer result) {
785 if (result > 0) {
786 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount,
787 result));
788 } else if (result == 0) {
789 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty));
790 }
791 }
792 }
John Reck89f73c12010-12-01 10:10:14 -0800793
John Reck71efc2b2011-05-09 16:54:28 -0700794 static class AccountsLoader extends CursorLoader {
John Reck89f73c12010-12-01 10:10:14 -0800795
John Reck71efc2b2011-05-09 16:54:28 -0700796 static String[] ACCOUNTS_PROJECTION = new String[] {
797 Accounts.ACCOUNT_NAME,
798 Accounts.ACCOUNT_TYPE
799 };
John Reck89f73c12010-12-01 10:10:14 -0800800
John Reck71efc2b2011-05-09 16:54:28 -0700801 public AccountsLoader(Context context) {
John Reck1e9815d2011-08-08 17:45:05 -0700802 super(context, Accounts.CONTENT_URI
803 .buildUpon()
804 .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false")
805 .build(),
806 ACCOUNTS_PROJECTION, null, null, null);
John Reck89f73c12010-12-01 10:10:14 -0800807 }
John Reck522a4382011-01-26 13:23:47 -0800808
John Reck522a4382011-01-26 13:23:47 -0800809 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800810}