Index: chrome/android/java_staging/src/org/chromium/chrome/browser/bookmark/ManageBookmarkActivity.java |
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmark/ManageBookmarkActivity.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmark/ManageBookmarkActivity.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..686a8499215b6d2dfea46f7e9c4985093ec98433 |
--- /dev/null |
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmark/ManageBookmarkActivity.java |
@@ -0,0 +1,335 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.bookmark; |
+ |
+import android.Manifest; |
+import android.app.Fragment; |
+import android.app.FragmentManager.OnBackStackChangedListener; |
+import android.app.FragmentTransaction; |
+import android.content.Intent; |
+import android.content.pm.PackageManager; |
+import android.content.res.Configuration; |
+import android.net.Uri; |
+import android.nfc.NfcAdapter; |
+import android.os.Bundle; |
+import android.os.Process; |
+import android.support.v4.app.FragmentActivity; |
+import android.util.Log; |
+import android.view.WindowManager; |
+ |
+import org.chromium.base.VisibleForTesting; |
+import org.chromium.base.annotations.SuppressFBWarnings; |
+import org.chromium.base.library_loader.ProcessInitException; |
+import org.chromium.chrome.browser.ChromiumApplication; |
+import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
+import org.chromium.ui.UiUtils; |
+import org.chromium.ui.base.DeviceFormFactor; |
+ |
+/** |
+ * This class provides the adding bookmark UI. It is also required by |
+ * android.provider.Browser.saveBookmark |
+ */ |
+public class ManageBookmarkActivity extends FragmentActivity { |
+ |
+ private static final String BOOKMARK_ID_URI_PARAM = "id"; |
+ private static final String BOOKMARK_IS_FOLDER_URI_PARAM = "isfolder"; |
+ |
+ private static final String TAG = "ManageBookmarkActivity"; |
+ |
+ /* TODO(gb-deprecation): Use android.provider.BrowserContract.Bookmarks.IS_FOLDER */ |
+ public static final String BOOKMARK_INTENT_IS_FOLDER = "folder"; |
+ /* TODO(gb-deprecation): Use android.provider.BrowserContract.Bookmarks.TITLE */ |
+ public static final String BOOKMARK_INTENT_TITLE = "title"; |
+ /* TODO(gb-deprecation): Use android.provider.BrowserContract.Bookmarks.URL */ |
+ public static final String BOOKMARK_INTENT_URL = "url"; |
+ /* TODO(gb-deprecation): Use android.provider.BrowserContract.Bookmarks._ID */ |
+ public static final String BOOKMARK_INTENT_ID = "_id"; |
+ |
+ /** |
+ * The tag used when adding the base add/edit bookmark fragment. |
+ */ |
+ @VisibleForTesting |
+ public static final String BASE_ADD_EDIT_FRAGMENT_TAG = "AddEdit"; |
+ /** |
+ * The tag used when adding the folder selection fragment triggered by the base |
+ * add/edit bookmark fragment. |
+ */ |
+ @VisibleForTesting |
+ public static final String BASE_SELECT_FOLDER_FRAGMENT_TAG = "SelectFolder"; |
+ /** |
+ * The tag used when adding the add new bookmark folder fragment triggered by the initial |
+ * folder selection fragment. |
+ */ |
+ @VisibleForTesting |
+ public static final String ADD_FOLDER_FRAGMENT_TAG = "AddFolder"; |
+ /** |
+ * The tag used when adding the folder selection fragment triggered by the add new bookmark |
+ * folder fragment. |
+ */ |
+ protected static final String ADD_FOLDER_SELECT_FOLDER_FRAGMENT_TAG = "AddFolderSelectFolder"; |
+ |
+ /** |
+ * Internally used to temporarily disable the back button while performing non-cancelable |
+ * asynchronous tasks that modify the bookmark model. |
+ */ |
+ private boolean mIsBackEnabled = true; |
+ |
+ @Override |
+ protected void onCreate(Bundle savedInstanceState) { |
+ super.onCreate(savedInstanceState); |
+ try { |
+ if (getApplication() instanceof ChromiumApplication) { |
+ ((ChromiumApplication) getApplication()) |
+ .startBrowserProcessesAndLoadLibrariesSync(this, true); |
+ } |
+ } catch (ProcessInitException e) { |
+ Log.e(TAG, "Unable to load native library.", e); |
+ ChromiumApplication.reportStartupErrorAndExit(e); |
+ return; |
+ } |
+ if (!DeviceFormFactor.isTablet(this)) { |
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN |
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); |
+ } |
+ |
+ if (savedInstanceState == null) { |
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); |
+ fragmentTransaction.add( |
+ android.R.id.content, generateBaseFragment(), BASE_ADD_EDIT_FRAGMENT_TAG); |
+ fragmentTransaction.commit(); |
+ } else { |
+ initializeFragmentState(); |
+ } |
+ |
+ // When adding or removing fragments, ensure the keyboard is hidden if visible as the |
+ // editing fields are no longer on the screen. |
+ getFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() { |
+ @Override |
+ public void onBackStackChanged() { |
+ UiUtils.hideKeyboard(findViewById(android.R.id.content)); |
+ } |
+ }); |
+ if (checkPermission(Manifest.permission.NFC, Process.myPid(), Process.myUid()) |
+ == PackageManager.PERMISSION_GRANTED) { |
+ NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); |
+ if (nfcAdapter != null) nfcAdapter.setNdefPushMessage(null, this); |
+ } |
+ } |
+ |
+ @Override |
+ public void finish() { |
+ super.finish(); |
+ // Disables closing animation only for large/xlarge screen because the activity shows in |
+ // fullscreen in other cases and so closing animation doesn't look unnatural. |
+ if (getResources().getConfiguration().isLayoutSizeAtLeast( |
+ Configuration.SCREENLAYOUT_SIZE_LARGE)) { |
+ overridePendingTransition(0, 0); |
+ } |
+ } |
+ |
+ @Override |
+ public void onBackPressed() { |
+ if (!mIsBackEnabled) return; |
+ if (getFragmentManager().getBackStackEntryCount() == 0) { |
+ finish(); |
+ } else { |
+ getFragmentManager().popBackStackImmediate(); |
+ } |
+ } |
+ |
+ /** |
+ * Initializes the fragment state after a state restoration. |
+ * <p> |
+ * Reinitializes all of the event listeners on the fragments as they are not persisted across |
+ * activity recreation (and were referencing the old activity anyway). |
+ * <p> |
+ * The hidden state of the fragments are also not persisted across activity changes, so we need |
+ * to hide and show the fragments accordingly (since we know that hierarchy of the fragments |
+ * we can do this as a simple nested conditional). |
+ */ |
+ private void initializeFragmentState() { |
+ AddEditBookmarkFragment baseAddEditFragment = (AddEditBookmarkFragment) getFragmentManager() |
+ .findFragmentByTag(BASE_ADD_EDIT_FRAGMENT_TAG); |
+ setActionListenerOnAddEdit(baseAddEditFragment); |
+ |
+ Fragment selectFolderFragment = |
+ getFragmentManager().findFragmentByTag(BASE_SELECT_FOLDER_FRAGMENT_TAG); |
+ if (selectFolderFragment != null) { |
+ setActionListenerOnFolderSelection( |
+ (SelectBookmarkFolderFragment) selectFolderFragment); |
+ |
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); |
+ fragmentTransaction.hide(baseAddEditFragment); |
+ |
+ Fragment addFolderFragment = |
+ getFragmentManager().findFragmentByTag(ADD_FOLDER_FRAGMENT_TAG); |
+ if (addFolderFragment != null) { |
+ fragmentTransaction.hide(selectFolderFragment); |
+ setActionListenerOnAddEdit((AddEditBookmarkFragment) addFolderFragment); |
+ |
+ Fragment addFolderSelectFolderFragment = getFragmentManager().findFragmentByTag( |
+ ADD_FOLDER_SELECT_FOLDER_FRAGMENT_TAG); |
+ if (addFolderSelectFolderFragment != null) { |
+ setActionListenerOnFolderSelection( |
+ (SelectBookmarkFolderFragment) addFolderSelectFolderFragment); |
+ fragmentTransaction.hide(addFolderFragment); |
+ fragmentTransaction.show(addFolderSelectFolderFragment); |
+ } else { |
+ fragmentTransaction.show(addFolderFragment); |
+ } |
+ } else { |
+ fragmentTransaction.show(selectFolderFragment); |
+ } |
+ fragmentTransaction.commit(); |
+ } |
+ } |
+ |
+ /** |
+ * Creates the base add/edit bookmark fragment based on the intent passed to this activity. |
+ * |
+ * @return The appropriate fragment based on the intent parameters. |
+ */ |
+ @SuppressFBWarnings("NP_NULL_ON_SOME_PATH") |
+ private AddEditBookmarkFragment generateBaseFragment() { |
+ if (getIntent() == null) { |
+ throw new IllegalArgumentException("intent can not be null"); |
+ } |
+ Intent intent = getIntent(); |
+ Uri intentUri = intent.getData(); |
+ |
+ Long bookmarkId = null; |
+ boolean isFolder = false; |
+ AddEditBookmarkFragment addEditFragment; |
+ if (intentUri != null && intentUri.getHost().equals("editbookmark")) { |
+ isFolder = intentUri.getBooleanQueryParameter(BOOKMARK_IS_FOLDER_URI_PARAM, false); |
+ String bookmarkIdParam = intentUri.getQueryParameter(BOOKMARK_ID_URI_PARAM); |
+ if (bookmarkIdParam != null) bookmarkId = Long.parseLong(bookmarkIdParam); |
+ addEditFragment = AddEditBookmarkFragment.newEditInstance(isFolder, bookmarkId); |
+ } else { |
+ Bundle extras = intent.getExtras(); |
+ String url = null; |
+ String name = null; |
+ if (extras != null) { |
+ isFolder = extras.getBoolean(BOOKMARK_INTENT_IS_FOLDER, false); |
+ |
+ if (extras.containsKey(BOOKMARK_INTENT_TITLE)) { |
+ name = extras.getString(BOOKMARK_INTENT_TITLE); |
+ } |
+ if (extras.containsKey(BOOKMARK_INTENT_URL)) { |
+ url = extras.getString(BOOKMARK_INTENT_URL); |
+ url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
+ } |
+ if (extras.containsKey(BOOKMARK_INTENT_ID)) { |
+ bookmarkId = extras.getLong(BOOKMARK_INTENT_ID); |
+ } |
+ } |
+ addEditFragment = AddEditBookmarkFragment.newInstance(isFolder, bookmarkId, name, url); |
+ } |
+ setActionListenerOnAddEdit(addEditFragment); |
+ return addEditFragment; |
+ } |
+ |
+ /** |
+ * Creates and sets an action listener on the add/edit bookmark fragment. |
+ * @param addEditFragment The fragment that the listener should be attached to. |
+ */ |
+ private void setActionListenerOnAddEdit(final AddEditBookmarkFragment addEditFragment) { |
+ addEditFragment.setOnActionListener(new AddEditBookmarkFragment.OnActionListener() { |
+ @Override |
+ public void onCancel() { |
+ finishAddEdit(); |
+ } |
+ |
+ |
+ @Override |
+ public void onNodeEdited(long id) { |
+ finishAddEdit(); |
+ } |
+ |
+ @Override |
+ public void onFolderCreated(long id, String name) { |
+ finishAddEdit(); |
+ if (getFragmentManager().getBackStackEntryCount() != 0) { |
+ ((SelectBookmarkFolderFragment) addEditFragment.getTargetFragment()) |
+ .executeFolderSelection(id, name); |
+ } |
+ } |
+ |
+ @Override |
+ public void triggerFolderSelection() { |
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); |
+ |
+ boolean isRoot = getFragmentManager().getBackStackEntryCount() == 0; |
+ SelectBookmarkFolderFragment selectFolder = |
+ SelectBookmarkFolderFragment.newInstance( |
+ // Only allow the root add/edit bookmark UI to create new bookmark |
+ // folders during selection. |
+ isRoot, |
+ addEditFragment.getParentFolderId(), |
+ addEditFragment.isFolder()); |
+ selectFolder.setTargetFragment(addEditFragment, 0); |
+ setActionListenerOnFolderSelection(selectFolder); |
+ |
+ String tag = isRoot ? BASE_SELECT_FOLDER_FRAGMENT_TAG |
+ : ADD_FOLDER_SELECT_FOLDER_FRAGMENT_TAG; |
+ fragmentTransaction.add(android.R.id.content, selectFolder, tag); |
+ fragmentTransaction.hide(addEditFragment); |
+ fragmentTransaction.addToBackStack(null); |
+ fragmentTransaction.commit(); |
+ } |
+ |
+ @Override |
+ public void onRemove() { |
+ finishAddEdit(); |
+ } |
+ |
+ @Override |
+ public void setBackEnabled(boolean enabled) { |
+ mIsBackEnabled = enabled; |
+ } |
+ |
+ private void finishAddEdit() { |
+ if (getFragmentManager().getBackStackEntryCount() == 0) { |
+ finish(); |
+ } else { |
+ getFragmentManager().popBackStackImmediate(); |
+ } |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * Creates and sets an action listener on the bookmark folder selection fragment. |
+ * @param selectFolder The fragment that the listener should be attached to. |
+ */ |
+ private void setActionListenerOnFolderSelection( |
+ final SelectBookmarkFolderFragment selectFolder) { |
+ selectFolder.setOnActionListener(new SelectBookmarkFolderFragment.OnActionListener() { |
+ @Override |
+ public void triggerNewFolderCreation(long selectedFolderId, String selectedFolderName) { |
+ newFolder(selectFolder, selectedFolderId, selectedFolderName); |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * Create and display the fragment for creating a new bookmark folder. |
+ * @param triggeringFragment The fragment that requested the new folder fragment to be shown. |
+ * @param parentFolderId The ID of the bookmark folder to used as the default parent of the |
+ * folder. |
+ * @param parentName The name of the bookmark folder to be used at the default parent. |
+ */ |
+ private void newFolder(Fragment triggeringFragment, long parentFolderId, String parentName) { |
+ AddEditBookmarkFragment newFolderFragment = |
+ AddEditBookmarkFragment.newAddNewFolderInstance(parentFolderId, parentName); |
+ newFolderFragment.setTargetFragment(triggeringFragment, 0); |
+ setActionListenerOnAddEdit(newFolderFragment); |
+ getFragmentManager().beginTransaction() |
+ .hide(triggeringFragment) |
+ .add(android.R.id.content, newFolderFragment, ADD_FOLDER_FRAGMENT_TAG) |
+ .addToBackStack(null) |
+ .commit(); |
+ } |
+} |