summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/ActionModeHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/ActionModeHandler.java')
-rw-r--r--src/com/android/gallery3d/ui/ActionModeHandler.java501
1 files changed, 0 insertions, 501 deletions
diff --git a/src/com/android/gallery3d/ui/ActionModeHandler.java b/src/com/android/gallery3d/ui/ActionModeHandler.java
deleted file mode 100644
index 6b4f10312..000000000
--- a/src/com/android/gallery3d/ui/ActionModeHandler.java
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.gallery3d.ui;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.nfc.NfcAdapter;
-import android.os.Handler;
-import android.view.ActionMode;
-import android.view.ActionMode.Callback;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ShareActionProvider;
-import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.ui.MenuExecutor.ProgressListener;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.ThreadPool.Job;
-import com.android.gallery3d.util.ThreadPool.JobContext;
-
-import java.util.ArrayList;
-
-public class ActionModeHandler implements Callback, PopupList.OnPopupItemClickListener {
-
- @SuppressWarnings("unused")
- private static final String TAG = "ActionModeHandler";
-
- private static final int MAX_SELECTED_ITEMS_FOR_SHARE_INTENT = 300;
- private static final int MAX_SELECTED_ITEMS_FOR_PANORAMA_SHARE_INTENT = 10;
-
- private static final int SUPPORT_MULTIPLE_MASK = MediaObject.SUPPORT_DELETE
- | MediaObject.SUPPORT_ROTATE | MediaObject.SUPPORT_SHARE
- | MediaObject.SUPPORT_CACHE;
-
- public interface ActionModeListener {
- public boolean onActionItemClicked(MenuItem item);
- }
-
- private final AbstractGalleryActivity mActivity;
- private final MenuExecutor mMenuExecutor;
- private final SelectionManager mSelectionManager;
- private final NfcAdapter mNfcAdapter;
- private Menu mMenu;
- private MenuItem mSharePanoramaMenuItem;
- private MenuItem mShareMenuItem;
- private ShareActionProvider mSharePanoramaActionProvider;
- private ShareActionProvider mShareActionProvider;
- private SelectionMenu mSelectionMenu;
- private ActionModeListener mListener;
- private Future<?> mMenuTask;
- private final Handler mMainHandler;
- private ActionMode mActionMode;
-
- private static class GetAllPanoramaSupports implements PanoramaSupportCallback {
- private int mNumInfoRequired;
- private JobContext mJobContext;
- public boolean mAllPanoramas = true;
- public boolean mAllPanorama360 = true;
- public boolean mHasPanorama360 = false;
- private Object mLock = new Object();
-
- public GetAllPanoramaSupports(ArrayList<MediaObject> mediaObjects, JobContext jc) {
- mJobContext = jc;
- mNumInfoRequired = mediaObjects.size();
- for (MediaObject mediaObject : mediaObjects) {
- mediaObject.getPanoramaSupport(this);
- }
- }
-
- @Override
- public void panoramaInfoAvailable(MediaObject mediaObject, boolean isPanorama,
- boolean isPanorama360) {
- synchronized (mLock) {
- mNumInfoRequired--;
- mAllPanoramas = isPanorama && mAllPanoramas;
- mAllPanorama360 = isPanorama360 && mAllPanorama360;
- mHasPanorama360 = mHasPanorama360 || isPanorama360;
- if (mNumInfoRequired == 0 || mJobContext.isCancelled()) {
- mLock.notifyAll();
- }
- }
- }
-
- public void waitForPanoramaSupport() {
- synchronized (mLock) {
- while (mNumInfoRequired != 0 && !mJobContext.isCancelled()) {
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- // May be a cancelled job context
- }
- }
- }
- }
- }
-
- public ActionModeHandler(
- AbstractGalleryActivity activity, SelectionManager selectionManager) {
- mActivity = Utils.checkNotNull(activity);
- mSelectionManager = Utils.checkNotNull(selectionManager);
- mMenuExecutor = new MenuExecutor(activity, selectionManager);
- mMainHandler = new Handler(activity.getMainLooper());
- mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity.getAndroidContext());
- }
-
- public void startActionMode() {
- Activity a = mActivity;
- mActionMode = a.startActionMode(this);
- View customView = LayoutInflater.from(a).inflate(
- R.layout.action_mode, null);
- mActionMode.setCustomView(customView);
- mSelectionMenu = new SelectionMenu(a,
- (Button) customView.findViewById(R.id.selection_menu), this);
- updateSelectionMenu();
- }
-
- public void finishActionMode() {
- mActionMode.finish();
- }
-
- public void setTitle(String title) {
- mSelectionMenu.setTitle(title);
- }
-
- public void setActionModeListener(ActionModeListener listener) {
- mListener = listener;
- }
-
- private WakeLockHoldingProgressListener mDeleteProgressListener;
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- GLRoot root = mActivity.getGLRoot();
- root.lockRenderThread();
- try {
- boolean result;
- // Give listener a chance to process this command before it's routed to
- // ActionModeHandler, which handles command only based on the action id.
- // Sometimes the listener may have more background information to handle
- // an action command.
- if (mListener != null) {
- result = mListener.onActionItemClicked(item);
- if (result) {
- mSelectionManager.leaveSelectionMode();
- return result;
- }
- }
- ProgressListener listener = null;
- String confirmMsg = null;
- int action = item.getItemId();
- if (action == R.id.action_delete) {
- confirmMsg = mActivity.getResources().getQuantityString(
- R.plurals.delete_selection, mSelectionManager.getSelectedCount());
- if (mDeleteProgressListener == null) {
- mDeleteProgressListener = new WakeLockHoldingProgressListener(mActivity,
- "Gallery Delete Progress Listener");
- }
- listener = mDeleteProgressListener;
- }
- mMenuExecutor.onMenuClicked(item, confirmMsg, listener);
- } finally {
- root.unlockRenderThread();
- }
- return true;
- }
-
- @Override
- public boolean onPopupItemClick(int itemId) {
- GLRoot root = mActivity.getGLRoot();
- root.lockRenderThread();
- try {
- if (itemId == R.id.action_select_all) {
- updateSupportedOperation();
- mMenuExecutor.onMenuClicked(itemId, null, false, true);
- }
- return true;
- } finally {
- root.unlockRenderThread();
- }
- }
-
- private void updateSelectionMenu() {
- // update title
- int count = mSelectionManager.getSelectedCount();
- String format = mActivity.getResources().getQuantityString(
- R.plurals.number_of_items_selected, count);
- setTitle(String.format(format, count));
-
- // For clients who call SelectionManager.selectAll() directly, we need to ensure the
- // menu status is consistent with selection manager.
- mSelectionMenu.updateSelectAllMode(mSelectionManager.inSelectAllMode());
- }
-
- private final OnShareTargetSelectedListener mShareTargetSelectedListener =
- new OnShareTargetSelectedListener() {
- @Override
- public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
- mSelectionManager.leaveSelectionMode();
- return false;
- }
- };
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.getMenuInflater().inflate(R.menu.operation, menu);
-
- mMenu = menu;
- mSharePanoramaMenuItem = menu.findItem(R.id.action_share_panorama);
- if (mSharePanoramaMenuItem != null) {
- mSharePanoramaActionProvider = (ShareActionProvider) mSharePanoramaMenuItem
- .getActionProvider();
- mSharePanoramaActionProvider.setOnShareTargetSelectedListener(
- mShareTargetSelectedListener);
- mSharePanoramaActionProvider.setShareHistoryFileName("panorama_share_history.xml");
- }
- mShareMenuItem = menu.findItem(R.id.action_share);
- if (mShareMenuItem != null) {
- mShareActionProvider = (ShareActionProvider) mShareMenuItem
- .getActionProvider();
- mShareActionProvider.setOnShareTargetSelectedListener(
- mShareTargetSelectedListener);
- mShareActionProvider.setShareHistoryFileName("share_history.xml");
- }
- return true;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- mSelectionManager.leaveSelectionMode();
- }
-
- private ArrayList<MediaObject> getSelectedMediaObjects(JobContext jc) {
- ArrayList<Path> unexpandedPaths = mSelectionManager.getSelected(false);
- if (unexpandedPaths.isEmpty()) {
- // This happens when starting selection mode from overflow menu
- // (instead of long press a media object)
- return null;
- }
- ArrayList<MediaObject> selected = new ArrayList<MediaObject>();
- DataManager manager = mActivity.getDataManager();
- for (Path path : unexpandedPaths) {
- if (jc.isCancelled()) {
- return null;
- }
- selected.add(manager.getMediaObject(path));
- }
-
- return selected;
- }
- // Menu options are determined by selection set itself.
- // We cannot expand it because MenuExecuter executes it based on
- // the selection set instead of the expanded result.
- // e.g. LocalImage can be rotated but collections of them (LocalAlbum) can't.
- private int computeMenuOptions(ArrayList<MediaObject> selected) {
- int operation = MediaObject.SUPPORT_ALL;
- int type = 0;
- for (MediaObject mediaObject: selected) {
- int support = mediaObject.getSupportedOperations();
- type |= mediaObject.getMediaType();
- operation &= support;
- }
-
- switch (selected.size()) {
- case 1:
- final String mimeType = MenuExecutor.getMimeType(type);
- if (!GalleryUtils.isEditorAvailable(mActivity, mimeType)) {
- operation &= ~MediaObject.SUPPORT_EDIT;
- }
- break;
- default:
- operation &= SUPPORT_MULTIPLE_MASK;
- }
-
- return operation;
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void setNfcBeamPushUris(Uri[] uris) {
- if (mNfcAdapter != null && ApiHelper.HAS_SET_BEAM_PUSH_URIS) {
- mNfcAdapter.setBeamPushUrisCallback(null, mActivity);
- mNfcAdapter.setBeamPushUris(uris, mActivity);
- }
- }
-
- // Share intent needs to expand the selection set so we can get URI of
- // each media item
- private Intent computePanoramaSharingIntent(JobContext jc, int maxItems) {
- ArrayList<Path> expandedPaths = mSelectionManager.getSelected(true, maxItems);
- if (expandedPaths == null || expandedPaths.size() == 0) {
- return new Intent();
- }
- final ArrayList<Uri> uris = new ArrayList<Uri>();
- DataManager manager = mActivity.getDataManager();
- final Intent intent = new Intent();
- for (Path path : expandedPaths) {
- if (jc.isCancelled()) return null;
- uris.add(manager.getContentUri(path));
- }
-
- final int size = uris.size();
- if (size > 0) {
- if (size > 1) {
- intent.setAction(Intent.ACTION_SEND_MULTIPLE);
- intent.setType(GalleryUtils.MIME_TYPE_PANORAMA360);
- intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
- } else {
- intent.setAction(Intent.ACTION_SEND);
- intent.setType(GalleryUtils.MIME_TYPE_PANORAMA360);
- intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
- }
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
-
- return intent;
- }
-
- private Intent computeSharingIntent(JobContext jc, int maxItems) {
- ArrayList<Path> expandedPaths = mSelectionManager.getSelected(true, maxItems);
- if (expandedPaths == null || expandedPaths.size() == 0) {
- setNfcBeamPushUris(null);
- return new Intent();
- }
- final ArrayList<Uri> uris = new ArrayList<Uri>();
- DataManager manager = mActivity.getDataManager();
- int type = 0;
- final Intent intent = new Intent();
- for (Path path : expandedPaths) {
- if (jc.isCancelled()) return null;
- int support = manager.getSupportedOperations(path);
- type |= manager.getMediaType(path);
-
- if ((support & MediaObject.SUPPORT_SHARE) != 0) {
- uris.add(manager.getContentUri(path));
- }
- }
-
- final int size = uris.size();
- if (size > 0) {
- final String mimeType = MenuExecutor.getMimeType(type);
- if (size > 1) {
- intent.setAction(Intent.ACTION_SEND_MULTIPLE).setType(mimeType);
- intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
- } else {
- intent.setAction(Intent.ACTION_SEND).setType(mimeType);
- intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
- }
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- setNfcBeamPushUris(uris.toArray(new Uri[uris.size()]));
- } else {
- setNfcBeamPushUris(null);
- }
-
- return intent;
- }
-
- public void updateSupportedOperation(Path path, boolean selected) {
- // TODO: We need to improve the performance
- updateSupportedOperation();
- }
-
- public void updateSupportedOperation() {
- // Interrupt previous unfinished task, mMenuTask is only accessed in main thread
- if (mMenuTask != null) mMenuTask.cancel();
-
- updateSelectionMenu();
-
- // Disable share actions until share intent is in good shape
- if (mSharePanoramaMenuItem != null) mSharePanoramaMenuItem.setEnabled(false);
- if (mShareMenuItem != null) mShareMenuItem.setEnabled(false);
-
- // Generate sharing intent and update supported operations in the background
- // The task can take a long time and be canceled in the mean time.
- mMenuTask = mActivity.getThreadPool().submit(new Job<Void>() {
- @Override
- public Void run(final JobContext jc) {
- // Pass1: Deal with unexpanded media object list for menu operation.
- ArrayList<MediaObject> selected = getSelectedMediaObjects(jc);
- if (selected == null) {
- mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- mMenuTask = null;
- if (jc.isCancelled()) return;
- // Disable all the operations when no item is selected
- MenuExecutor.updateMenuOperation(mMenu, 0);
- }
- });
- return null;
- }
- final int operation = computeMenuOptions(selected);
- if (jc.isCancelled()) {
- return null;
- }
- int numSelected = selected.size();
- final boolean canSharePanoramas =
- numSelected < MAX_SELECTED_ITEMS_FOR_PANORAMA_SHARE_INTENT;
- final boolean canShare =
- numSelected < MAX_SELECTED_ITEMS_FOR_SHARE_INTENT;
-
- final GetAllPanoramaSupports supportCallback = canSharePanoramas ?
- new GetAllPanoramaSupports(selected, jc)
- : null;
-
- // Pass2: Deal with expanded media object list for sharing operation.
- final Intent share_panorama_intent = canSharePanoramas ?
- computePanoramaSharingIntent(jc, MAX_SELECTED_ITEMS_FOR_PANORAMA_SHARE_INTENT)
- : new Intent();
- final Intent share_intent = canShare ?
- computeSharingIntent(jc, MAX_SELECTED_ITEMS_FOR_SHARE_INTENT)
- : new Intent();
-
- if (canSharePanoramas) {
- supportCallback.waitForPanoramaSupport();
- }
- if (jc.isCancelled()) {
- return null;
- }
- mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- mMenuTask = null;
- if (jc.isCancelled()) return;
- MenuExecutor.updateMenuOperation(mMenu, operation);
- MenuExecutor.updateMenuForPanorama(mMenu,
- canSharePanoramas && supportCallback.mAllPanorama360,
- canSharePanoramas && supportCallback.mHasPanorama360);
- if (mSharePanoramaMenuItem != null) {
- mSharePanoramaMenuItem.setEnabled(true);
- if (canSharePanoramas && supportCallback.mAllPanorama360) {
- mShareMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- mShareMenuItem.setTitle(
- mActivity.getResources().getString(R.string.share_as_photo));
- } else {
- mSharePanoramaMenuItem.setVisible(false);
- mShareMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- mShareMenuItem.setTitle(
- mActivity.getResources().getString(R.string.share));
- }
- mSharePanoramaActionProvider.setShareIntent(share_panorama_intent);
- }
- if (mShareMenuItem != null) {
- mShareMenuItem.setEnabled(canShare);
- mShareActionProvider.setShareIntent(share_intent);
- }
- }
- });
- return null;
- }
- });
- }
-
- public void pause() {
- if (mMenuTask != null) {
- mMenuTask.cancel();
- mMenuTask = null;
- }
- mMenuExecutor.pause();
- }
-
- public void destroy() {
- mMenuExecutor.destroy();
- }
-
- public void resume() {
- if (mSelectionManager.inSelectionMode()) updateSupportedOperation();
- mMenuExecutor.resume();
- }
-}