BrowserBookmarksPage.java revision 2d963a2899afbe000d1ab498f94de87f25e33184
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.browser; 18 19import android.app.Activity; 20import android.app.Fragment; 21import android.app.LoaderManager; 22import android.content.ClipData; 23import android.content.ClipboardManager; 24import android.content.ContentUris; 25import android.content.Context; 26import android.content.CursorLoader; 27import android.content.Intent; 28import android.content.Loader; 29import android.content.res.Configuration; 30import android.content.res.Resources; 31import android.database.Cursor; 32import android.graphics.Bitmap; 33import android.graphics.BitmapFactory; 34import android.net.Uri; 35import android.os.AsyncTask; 36import android.os.Bundle; 37import android.provider.BrowserContract; 38import android.provider.BrowserContract.Accounts; 39import android.provider.BrowserContract.ChromeSyncColumns; 40import android.view.ActionMode; 41import android.view.ContextMenu; 42import android.view.ContextMenu.ContextMenuInfo; 43import android.view.LayoutInflater; 44import android.view.MenuInflater; 45import android.view.MenuItem; 46import android.view.View; 47import android.view.ViewGroup; 48import android.widget.ExpandableListView; 49import android.widget.ExpandableListView.OnChildClickListener; 50import android.widget.ImageView; 51import android.widget.LinearLayout; 52import android.widget.Toast; 53 54import com.android.browser.BookmarkDragHandler.BookmarkDragController; 55import com.android.browser.BookmarkDragHandler.BookmarkDragState; 56import com.android.browser.provider.BrowserProvider2; 57import com.android.browser.view.BookmarkExpandableView; 58import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo; 59 60import java.util.HashMap; 61 62interface BookmarksPageCallbacks { 63 // Return true if handled 64 boolean onBookmarkSelected(Cursor c, boolean isFolder); 65 // Return true if handled 66 boolean onOpenInNewWindow(String... urls); 67} 68 69/** 70 * View showing the user's bookmarks in the browser. 71 */ 72public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener, 73 LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller, 74 OnChildClickListener { 75 76 public static class ExtraDragState { 77 public int childPosition; 78 public int groupPosition; 79 } 80 81 static final String LOGTAG = "browser"; 82 83 static final int LOADER_ACCOUNTS = 1; 84 static final int LOADER_BOOKMARKS = 100; 85 86 static final String EXTRA_DISABLE_WINDOW = "disable_new_window"; 87 88 static final String ACCOUNT_TYPE = "account_type"; 89 static final String ACCOUNT_NAME = "account_name"; 90 91 public static final int VIEW_THUMBNAILS = 1; 92 public static final int VIEW_LIST = 2; 93 94 BookmarksPageCallbacks mCallbacks; 95 View mRoot; 96 BookmarkExpandableView mGrid; 97 boolean mDisableNewWindow; 98 boolean mEnableContextMenu = true; 99 View mEmptyView; 100 View mHeader; 101 HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>(); 102 BookmarkDragHandler mDragHandler; 103 104 @Override 105 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 106 if (id == LOADER_ACCOUNTS) { 107 return new AccountsLoader(getActivity()); 108 } else if (id >= LOADER_BOOKMARKS) { 109 String accountType = args.getString(ACCOUNT_TYPE); 110 String accountName = args.getString(ACCOUNT_NAME); 111 BookmarksLoader bl = new BookmarksLoader(getActivity(), 112 accountType, accountName); 113 return bl; 114 } else { 115 throw new UnsupportedOperationException("Unknown loader id " + id); 116 } 117 } 118 119 @Override 120 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 121 if (loader.getId() == LOADER_ACCOUNTS) { 122 LoaderManager lm = getLoaderManager(); 123 int id = LOADER_BOOKMARKS; 124 while (cursor.moveToNext()) { 125 String accountName = cursor.getString(0); 126 String accountType = cursor.getString(1); 127 Bundle args = new Bundle(); 128 args.putString(ACCOUNT_NAME, accountName); 129 args.putString(ACCOUNT_TYPE, accountType); 130 BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter( 131 getActivity(), VIEW_THUMBNAILS); 132 mBookmarkAdapters.put(id, adapter); 133 mGrid.addAccount(accountName, adapter); 134 lm.restartLoader(id, args, this); 135 id++; 136 } 137 // TODO: Figure out what a reload of these means 138 // Currently, a reload is triggered whenever bookmarks change 139 // This is less than ideal 140 // It also causes UI flickering as a new adapter is created 141 // instead of re-using an existing one when the account_name is the 142 // same. 143 // For now, this is a one-shot load 144 getLoaderManager().destroyLoader(LOADER_ACCOUNTS); 145 } else if (loader.getId() >= LOADER_BOOKMARKS) { 146 BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId()); 147 adapter.changeCursor(cursor); 148 } 149 } 150 151 @Override 152 public void onLoaderReset(Loader<Cursor> loader) { 153 } 154 155 @Override 156 public boolean onContextItemSelected(MenuItem item) { 157 BookmarkContextMenuInfo i = (BookmarkContextMenuInfo)item.getMenuInfo(); 158 // If we have no menu info, we can't tell which item was selected. 159 if (i == null) { 160 return false; 161 } 162 163 if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) { 164 return true; 165 } 166 return super.onContextItemSelected(item); 167 } 168 169 public boolean handleContextItem(int itemId, int groupPosition, 170 int childPosition) { 171 final Activity activity = getActivity(); 172 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 173 174 switch (itemId) { 175 case R.id.open_context_menu_id: 176 loadUrl(adapter, childPosition); 177 break; 178 case R.id.edit_context_menu_id: 179 editBookmark(adapter, childPosition); 180 break; 181 case R.id.shortcut_context_menu_id: 182 Cursor c = adapter.getItem(childPosition); 183 activity.sendBroadcast(createShortcutIntent(getActivity(), c)); 184 break; 185 case R.id.delete_context_menu_id: 186 displayRemoveBookmarkDialog(adapter, childPosition); 187 break; 188 case R.id.new_window_context_menu_id: 189 openInNewWindow(adapter, childPosition); 190 break; 191 case R.id.share_link_context_menu_id: { 192 Cursor cursor = adapter.getItem(childPosition); 193 Controller.sharePage(activity, 194 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE), 195 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL), 196 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON), 197 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL)); 198 break; 199 } 200 case R.id.copy_url_context_menu_id: 201 copy(getUrl(adapter, childPosition)); 202 break; 203 case R.id.homepage_context_menu_id: { 204 BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition)); 205 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show(); 206 break; 207 } 208 // Only for the Most visited page 209 case R.id.save_to_bookmarks_menu_id: { 210 Cursor cursor = adapter.getItem(childPosition); 211 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 212 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 213 // If the site is bookmarked, the item becomes remove from 214 // bookmarks. 215 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name); 216 break; 217 } 218 default: 219 return false; 220 } 221 return true; 222 } 223 224 static Bitmap getBitmap(Cursor cursor, int columnIndex) { 225 byte[] data = cursor.getBlob(columnIndex); 226 if (data == null) { 227 return null; 228 } 229 return BitmapFactory.decodeByteArray(data, 0, data.length); 230 } 231 232 private MenuItem.OnMenuItemClickListener mContextItemClickListener = 233 new MenuItem.OnMenuItemClickListener() { 234 @Override 235 public boolean onMenuItemClick(MenuItem item) { 236 return onContextItemSelected(item); 237 } 238 }; 239 240 @Override 241 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 242 BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo; 243 BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition); 244 Cursor cursor = adapter.getItem(info.childPosition); 245 if (!canEdit(cursor)) { 246 return; 247 } 248 boolean isFolder 249 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 250 251 final Activity activity = getActivity(); 252 MenuInflater inflater = activity.getMenuInflater(); 253 inflater.inflate(R.menu.bookmarkscontext, menu); 254 if (isFolder) { 255 menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true); 256 } else { 257 menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true); 258 if (mDisableNewWindow) { 259 menu.findItem(R.id.new_window_context_menu_id).setVisible(false); 260 } 261 } 262 BookmarkItem header = new BookmarkItem(activity); 263 populateBookmarkItem(cursor, header, isFolder); 264 menu.setHeaderView(header); 265 266 int count = menu.size(); 267 for (int i = 0; i < count; i++) { 268 menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener); 269 } 270 } 271 272 boolean canEdit(Cursor c) { 273 String unique = c.getString(BookmarksLoader.COLUMN_INDEX_SERVER_UNIQUE); 274 return !ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS.equals(unique); 275 } 276 277 private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) { 278 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 279 if (isFolder) { 280 item.setUrl(null); 281 Bitmap bitmap = 282 BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark); 283 item.setFavicon(bitmap); 284 new LookupBookmarkCount(getActivity(), item) 285 .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 286 } else { 287 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 288 item.setUrl(url); 289 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 290 item.setFavicon(bitmap); 291 } 292 } 293 294 /** 295 * Create a new BrowserBookmarksPage. 296 */ 297 @Override 298 public void onCreate(Bundle icicle) { 299 super.onCreate(icicle); 300 Bundle args = getArguments(); 301 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); 302 setHasOptionsMenu(true); 303 if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) { 304 mCallbacks = new CombinedBookmarksCallbackWrapper( 305 (CombinedBookmarksCallbacks) getActivity()); 306 } 307 } 308 309 private static class CombinedBookmarksCallbackWrapper 310 implements BookmarksPageCallbacks { 311 312 private CombinedBookmarksCallbacks mCombinedCallback; 313 314 private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) { 315 mCombinedCallback = cb; 316 } 317 318 @Override 319 public boolean onOpenInNewWindow(String... urls) { 320 mCombinedCallback.openInNewTab(urls); 321 return true; 322 } 323 324 @Override 325 public boolean onBookmarkSelected(Cursor c, boolean isFolder) { 326 if (isFolder) { 327 return false; 328 } 329 mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c)); 330 return true; 331 } 332 }; 333 334 @Override 335 public View onCreateView(LayoutInflater inflater, ViewGroup container, 336 Bundle savedInstanceState) { 337 mRoot = inflater.inflate(R.layout.bookmarks, container, false); 338 mEmptyView = mRoot.findViewById(android.R.id.empty); 339 340 mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid); 341 mGrid.setOnChildClickListener(this); 342 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 343 mGrid.setBreadcrumbController(this); 344 setEnableContextMenu(mEnableContextMenu); 345 mDragHandler = new BookmarkDragHandler(getActivity(), mDragController, 346 mGrid.getDragAdapter()); 347 348 // Start the loaders 349 LoaderManager lm = getLoaderManager(); 350 lm.restartLoader(LOADER_ACCOUNTS, null, this); 351 352 return mRoot; 353 } 354 355 @Override 356 public void onDestroyView() { 357 super.onDestroyView(); 358 mGrid.setBreadcrumbController(null); 359 LoaderManager lm = getLoaderManager(); 360 lm.destroyLoader(LOADER_ACCOUNTS); 361 for (int id : mBookmarkAdapters.keySet()) { 362 lm.destroyLoader(id); 363 } 364 mBookmarkAdapters.clear(); 365 } 366 367 private BrowserBookmarksAdapter getChildAdapter(int groupPosition) { 368 return mGrid.getChildAdapter(groupPosition); 369 } 370 371 private BreadCrumbView getBreadCrumbs(int groupPosition) { 372 return mGrid.getBreadCrumbs(groupPosition); 373 } 374 375 @Override 376 public boolean onChildClick(ExpandableListView parent, View v, 377 int groupPosition, int childPosition, long id) { 378 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 379 Cursor cursor = adapter.getItem(childPosition); 380 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 381 if (mCallbacks != null && 382 mCallbacks.onBookmarkSelected(cursor, isFolder)) { 383 return true; 384 } 385 386 // TODO: Folder stuff 387 if (isFolder) { 388 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 389 Uri uri = ContentUris.withAppendedId( 390 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 391 BreadCrumbView crumbs = getBreadCrumbs(groupPosition); 392 if (crumbs != null) { 393 // update crumbs 394 crumbs.pushView(title, uri); 395 } 396 loadFolder(groupPosition, uri); 397 } 398 return true; 399 } 400 401 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) { 402 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 403 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 404 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 405 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 406 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon); 407 } 408 409 private void loadUrl(BrowserBookmarksAdapter adapter, int position) { 410 if (mCallbacks != null && adapter != null) { 411 mCallbacks.onBookmarkSelected(adapter.getItem(position), false); 412 } 413 } 414 415 private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) { 416 if (mCallbacks != null) { 417 Cursor c = adapter.getItem(position); 418 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1; 419 if (isFolder) { 420 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID); 421 new OpenAllInTabsTask(id).execute(); 422 } else { 423 mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c)); 424 } 425 } 426 } 427 428 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> { 429 long mFolderId; 430 public OpenAllInTabsTask(long id) { 431 mFolderId = id; 432 } 433 434 @Override 435 protected Cursor doInBackground(Void... params) { 436 Context c = getActivity(); 437 if (c == null) return null; 438 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c), 439 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?", 440 new String[] { Long.toString(mFolderId) }, null); 441 } 442 443 @Override 444 protected void onPostExecute(Cursor result) { 445 if (mCallbacks != null && result.getCount() > 0) { 446 String[] urls = new String[result.getCount()]; 447 int i = 0; 448 while (result.moveToNext()) { 449 urls[i++] = BrowserBookmarksPage.getUrl(result); 450 } 451 mCallbacks.onOpenInNewWindow(urls); 452 } 453 } 454 455 } 456 457 private void editBookmark(BrowserBookmarksAdapter adapter, int position) { 458 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 459 Cursor cursor = adapter.getItem(position); 460 Bundle item = new Bundle(); 461 item.putString(BrowserContract.Bookmarks.TITLE, 462 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 463 item.putString(BrowserContract.Bookmarks.URL, 464 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 465 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 466 if (data != null) { 467 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 468 BitmapFactory.decodeByteArray(data, 0, data.length)); 469 } 470 item.putLong(BrowserContract.Bookmarks._ID, 471 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 472 item.putLong(BrowserContract.Bookmarks.PARENT, 473 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 474 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); 475 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, 476 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); 477 startActivity(intent); 478 } 479 480 private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter, 481 int position) { 482 // Put up a dialog asking if the user really wants to 483 // delete the bookmark 484 Cursor cursor = adapter.getItem(position); 485 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); 486 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 487 Context context = getActivity(); 488 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null); 489 } 490 491 private String getUrl(BrowserBookmarksAdapter adapter, int position) { 492 return getUrl(adapter.getItem(position)); 493 } 494 495 /* package */ static String getUrl(Cursor c) { 496 return c.getString(BookmarksLoader.COLUMN_INDEX_URL); 497 } 498 499 private void copy(CharSequence text) { 500 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 501 Context.CLIPBOARD_SERVICE); 502 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString()))); 503 } 504 505 @Override 506 public void onConfigurationChanged(Configuration newConfig) { 507 super.onConfigurationChanged(newConfig); 508 Resources res = getActivity().getResources(); 509 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 510 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop); 511 mRoot.setPadding(0, paddingTop, 0, 0); 512 getActivity().invalidateOptionsMenu(); 513 } 514 515 /** 516 * BreadCrumb controller callback 517 */ 518 @Override 519 public void onTop(BreadCrumbView view, int level, Object data) { 520 int groupPosition = (Integer) view.getTag(R.id.group_position); 521 Uri uri = (Uri) data; 522 if (uri == null) { 523 // top level 524 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 525 } 526 loadFolder(groupPosition, uri); 527 } 528 529 /** 530 * @param uri 531 */ 532 private void loadFolder(int groupPosition, Uri uri) { 533 LoaderManager manager = getLoaderManager(); 534 // This assumes groups are ordered the same as loaders 535 BookmarksLoader loader = (BookmarksLoader) ((Loader<?>) 536 manager.getLoader(LOADER_BOOKMARKS + groupPosition)); 537 loader.setUri(uri); 538 loader.forceLoad(); 539 } 540 541 public void setCallbackListener(BookmarksPageCallbacks callbackListener) { 542 mCallbacks = callbackListener; 543 } 544 545 public void setEnableContextMenu(boolean enable) { 546 mEnableContextMenu = enable; 547 if (mGrid != null) { 548 if (mEnableContextMenu) { 549 registerForContextMenu(mGrid); 550 } else { 551 unregisterForContextMenu(mGrid); 552 mGrid.setLongClickable(false); 553 } 554 } 555 } 556 557 private BookmarkDragController mDragController = new BookmarkDragController() { 558 559 @Override 560 public boolean startDrag(Cursor item) { 561 return canEdit(item); 562 } 563 564 @Override 565 public ViewGroup getActionModeView(ActionMode mode, 566 BookmarkDragState state) { 567 LayoutInflater inflater = LayoutInflater.from(getActivity()); 568 LinearLayout view = (LinearLayout) inflater.inflate( 569 R.layout.bookmarks_drag_actionmode, null); 570 view.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); 571 ExtraDragState extraState = (ExtraDragState) state.extraState; 572 BrowserBookmarksAdapter adapter = getChildAdapter(extraState.groupPosition); 573 Cursor c = adapter.getItem(extraState.childPosition); 574 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 575 if (isFolder) { 576 view.findViewById(R.id.open_context_menu_id).setVisibility(View.GONE); 577 ImageView iv = (ImageView) view.findViewById( 578 R.id.new_window_context_menu_id); 579 iv.setImageResource(R.drawable.ic_windows_holo_dark); 580 } 581 return view; 582 } 583 584 @Override 585 public void actionItemClicked(View v, BookmarkDragState state) { 586 if (v.getId() == R.id.info) { 587 mGrid.showContextMenuForState(state); 588 } else { 589 ExtraDragState extraState = (ExtraDragState) state.extraState; 590 handleContextItem(v.getId(), extraState.groupPosition, 591 extraState.childPosition); 592 } 593 } 594 }; 595 596 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { 597 Context mContext; 598 BookmarkItem mHeader; 599 600 public LookupBookmarkCount(Context context, BookmarkItem header) { 601 mContext = context.getApplicationContext(); 602 mHeader = header; 603 } 604 605 @Override 606 protected Integer doInBackground(Long... params) { 607 if (params.length != 1) { 608 throw new IllegalArgumentException("Missing folder id!"); 609 } 610 Uri uri = BookmarkUtils.getBookmarksUri(mContext); 611 Cursor c = mContext.getContentResolver().query(uri, 612 null, BrowserContract.Bookmarks.PARENT + "=?", 613 new String[] {params[0].toString()}, null); 614 return c.getCount(); 615 } 616 617 @Override 618 protected void onPostExecute(Integer result) { 619 if (result > 0) { 620 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, 621 result)); 622 } else if (result == 0) { 623 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); 624 } 625 } 626 } 627 628 static class AccountsLoader extends CursorLoader { 629 630 static String[] ACCOUNTS_PROJECTION = new String[] { 631 Accounts.ACCOUNT_NAME, 632 Accounts.ACCOUNT_TYPE 633 }; 634 635 public AccountsLoader(Context context) { 636 super(context, Accounts.CONTENT_URI 637 .buildUpon() 638 .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false") 639 .build(), 640 ACCOUNTS_PROJECTION, null, null, null); 641 } 642 643 } 644} 645